SHOW:
|
|
- or go back to the newest paste.
1 | - | // position the light |
1 | + | #include <stdio.h> |
2 | - | glLightfv(GL_LIGHT0, GL_POSITION, lightPos_); |
2 | + | #include <stdlib.h> |
3 | #include <string.h> | |
4 | - | // switch the framebuffer for the first pass |
4 | + | #include <math.h> |
5 | - | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_); |
5 | + | #include <sys/time.h> |
6 | - | glViewport(0, 0, 512, 512); |
6 | + | |
7 | - | glClearColor(0.5, 0.2, 0.1, 1.0f); |
7 | + | #define GL_GLEXT_PROTOTYPES |
8 | - | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
8 | + | #include <GL/gl.h> |
9 | - | |
9 | + | #include <GL/glu.h> |
10 | - | |
10 | + | #include <GL/glut.h> |
11 | - | // set up the projection parameters from the light's POV |
11 | + | |
12 | - | glMatrixMode(GL_PROJECTION); |
12 | + | float light_position[4] = {0.5, 0.5, 1.0, 1.0}; |
13 | - | glPushMatrix(); |
13 | + | float light_ambient [4] = {0.0, 0.0, 0.0, 1.0}; |
14 | - | glLoadIdentity(); |
14 | + | float light_diffuse [4] = {1.0, 1.0, 1.0, 1.0}; |
15 | - | gluPerspective(lightFOV_, lightAspect_, lightNear_, lightFar_); |
15 | + | float light_specular[4] = {1.0, 1.0, 1.0, 1.0}; |
16 | ||
17 | - | glMatrixMode(GL_MODELVIEW); |
17 | + | float lightFOV_ = 90.0; |
18 | - | glPushMatrix(); |
18 | + | float lightNear_ = 0.1; |
19 | - | glLoadIdentity(); |
19 | + | float lightFar_ = 20.0; |
20 | - | // translate to the light's position |
20 | + | |
21 | - | gluLookAt(lightPos_[0], lightPos_[1], lightPos_[2], -1.0f, 0.0f, 5.0f, 0.0f, 1.0f, 0.0f); |
21 | + | float material_emission[4] = {0.0, 0.0, 0.0, 1.0}; |
22 | float material_ambient [4] = {0.2, 0.6, 0.2, 1.0}; | |
23 | - | // render the scene to get the depth information |
23 | + | float material_diffuse [4] = {0.2, 0.6, 0.2, 1.0}; |
24 | - | renderSceneElements(); |
24 | + | float material_specular[4] = {0.3, 0.3, 0.3, 1.0}; |
25 | - | glPopMatrix(); |
25 | + | float material_shininess = 50.0; |
26 | - | |
26 | + | |
27 | - | // end the projection modification |
27 | + | #define W 512 |
28 | - | glMatrixMode(GL_PROJECTION); |
28 | + | #define H 512 |
29 | - | glPopMatrix(); |
29 | + | |
30 | - | glMatrixMode(GL_MODELVIEW); |
30 | + | #define R 20 |
31 | #define N (2 * R + 1) | |
32 | - | // switch back to the system framebuffer for the second pass |
32 | + | |
33 | - | glBindFramebuffer(GL_FRAMEBUFFER, 0); |
33 | + | GLuint indices[N-1][N-1][4]; |
34 | - | glClearColor(1,1,1,1); |
34 | + | |
35 | - | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
35 | + | int width = 1; |
36 | - | glViewport(0, 0, 512, 512); |
36 | + | int height = 1; |
37 | - | |
37 | + | int key_state[0x100]; |
38 | - | // matrix defining the planes for S, T, R, Q components for texture generation |
38 | + | double last = -1.0; |
39 | - | float planeMatrix[16]; |
39 | + | float lightPos_[4] = {0.5, 0.5, 1.0, 1.0}; |
40 | - | glPushMatrix(); |
40 | + | |
41 | - | glLoadIdentity(); |
41 | + | GLuint shadowmap_, renderbuffer_, framebuffer_; |
42 | - | // compensate for the eye-coordinate to texture coordinate conversion: [-1,1] to [0,1] |
42 | + | |
43 | - | glTranslatef(0.5f, 0.5f, 0.5f); |
43 | + | void make_data(void) |
44 | - | glScalef(0.5f, 0.5f, 0.5f); |
44 | + | { |
45 | - | |
45 | + | float k = 0.1; |
46 | - | // do the perspective projection and translate to the light's position |
46 | + | |
47 | - | gluPerspective(lightFOV_, lightAspect_, lightNear_, lightFar_); |
47 | + | static float verts[N][N][3]; |
48 | - | gluLookAt(lightPos_[0], lightPos_[1], lightPos_[2], -1.0f, 0.0f, 5.0f, 0.0f, 1.0f, 0.0f); |
48 | + | static float norms[N][N][3]; |
49 | - | |
49 | + | for (int j = 0; j < N; j++) { |
50 | - | glGetFloatv(GL_MODELVIEW_MATRIX, planeMatrix); |
50 | + | for (int i = 0; i < N; i++) { |
51 | - | glPopMatrix(); |
51 | + | float x = 1.5 * (i / (float) R - 1.0); |
52 | - | |
52 | + | float y = 1.5 * (j / (float) R - 1.0); |
53 | - | // go from OpenGL's column-major to row-major matrix form |
53 | + | float d = x * x + y * y + k; |
54 | - | transposeMatrix16(planeMatrix); |
54 | + | float z = k / d - 2.0; |
55 | verts[j][i][0] = x; | |
56 | - | // set up the type for texture generation |
56 | + | verts[j][i][1] = y; |
57 | - | glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); |
57 | + | verts[j][i][2] = z; |
58 | - | glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); |
58 | + | float d2 = d * d; |
59 | - | glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); |
59 | + | float dx = 2 * k * x / d2; |
60 | - | glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); |
60 | + | float dy = 2 * k * y / d2; |
61 | - | |
61 | + | float dz = 1.0; |
62 | - | // data for texture generation |
62 | + | float m = sqrt(dx * dx + dy * dy + dz * dz); |
63 | - | glTexGenfv(GL_S, GL_OBJECT_PLANE, &planeMatrix[0]); |
63 | + | norms[j][i][0] = dx / m; |
64 | - | glTexGenfv(GL_T, GL_OBJECT_PLANE, &planeMatrix[4]); |
64 | + | norms[j][i][1] = dy / m; |
65 | - | glTexGenfv(GL_R, GL_OBJECT_PLANE, &planeMatrix[8]); |
65 | + | norms[j][i][2] = dz / m; |
66 | - | glTexGenfv(GL_Q, GL_OBJECT_PLANE, &planeMatrix[12]); |
66 | + | } |
67 | } | |
68 | - | glEnable(GL_TEXTURE_GEN_S); |
68 | + | |
69 | - | glEnable(GL_TEXTURE_GEN_T); |
69 | + | glVertexPointer(3, GL_FLOAT, 0, (const GLvoid *) verts); |
70 | - | glEnable(GL_TEXTURE_GEN_R); |
70 | + | glNormalPointer(GL_FLOAT, 0, (const GLvoid *) norms); |
71 | - | glEnable(GL_TEXTURE_GEN_Q); |
71 | + | glEnableClientState(GL_VERTEX_ARRAY); |
72 | - | |
72 | + | glEnableClientState(GL_NORMAL_ARRAY); |
73 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
73 | + | |
74 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
74 | + | for (int j = 0; j < N-1; j++) { |
75 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
75 | + | for (int i = 0; i < N-1; i++) { |
76 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
76 | + | GLuint base = j * N + i; |
77 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); |
77 | + | indices[j][i][0] = base; |
78 | - | glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); |
78 | + | indices[j][i][1] = base + N; |
79 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); |
79 | + | indices[j][i][2] = base + N + 1; |
80 | - | |
80 | + | indices[j][i][3] = base + 1; |
81 | - | glEnable(GL_TEXTURE_2D); |
81 | + | } |
82 | - | glBindTexture(GL_TEXTURE_2D, shadowmap_); |
82 | + | } |
83 | } | |
84 | - | glEnable(GL_LIGHTING); |
84 | + | |
85 | - | glEnable(GL_LIGHT0); |
85 | + | void dump(void) |
86 | { | |
87 | - | renderSceneElements(); |
87 | + | unsigned char surface[H][W][3]; |
88 | ||
89 | - | glDisable(GL_LIGHTING); |
89 | + | glReadPixels(0, 0, H, W, GL_RGB, GL_UNSIGNED_BYTE, surface); |
90 | - | glDisable(GL_LIGHT0); |
90 | + | FILE *fp = fopen("dump.ppm","wb"); |
91 | fprintf(fp, "P6\n%d %d\n255\n", W, H); | |
92 | - | glDisable(GL_TEXTURE_2D); |
92 | + | fwrite(surface, W * 3, H, fp); |
93 | fclose(fp); | |
94 | - | glDisable(GL_TEXTURE_GEN_Q); |
94 | + | } |
95 | - | glDisable(GL_TEXTURE_GEN_R); |
95 | + | |
96 | - | glDisable(GL_TEXTURE_GEN_T); |
96 | + | void swap(float m[16], int i, int j) |
97 | - | glDisable(GL_TEXTURE_GEN_S); |
97 | + | { |
98 | float mi = m[i]; | |
99 | - | glPushMatrix(); |
99 | + | m[i] = m[j]; |
100 | - | glEnable(GL_TEXTURE_2D); |
100 | + | m[j] = mi; |
101 | - | //glBindTexture(GL_TEXTURE_2D, shadowmap_); |
101 | + | } |
102 | - | glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_NONE); |
102 | + | |
103 | - | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE); |
103 | + | void transposeMatrix16(float m[16]) |
104 | - | glTranslatef(3.0f, 2.0f, 5.0f); |
104 | + | { |
105 | - | glBegin(GL_QUADS); |
105 | + | swap(m, 1, 4); |
106 | - | glTexCoord2f(0.0f, 0.0f); |
106 | + | swap(m, 2, 8); |
107 | - | glVertex3f(0.0f, 0.0f, 0.0f); |
107 | + | swap(m, 3,12); |
108 | swap(m, 6, 9); | |
109 | - | glTexCoord2f(1.0f, 0.0f); |
109 | + | swap(m, 7,13); |
110 | - | glVertex3f(3.0f, 0.0f, 0.0f); |
110 | + | swap(m,11,14); |
111 | } | |
112 | - | glTexCoord2f(1.0f, 1.0f); |
112 | + | |
113 | - | glVertex3f(3.0f, 3.0f, 0.0f); |
113 | + | const char *error(void) |
114 | { | |
115 | - | glTexCoord2f(0.0f, 1.0f); |
115 | + | GLenum status = glGetError(); |
116 | - | glVertex3f(0.0f, 3.0f, 0.0f); |
116 | + | |
117 | - | glEnd(); |
117 | + | switch (status) |
118 | - | glDisable(GL_TEXTURE_2D); |
118 | + | { |
119 | - | glPopMatrix(); |
119 | + | case GL_NO_ERROR: return NULL; |
120 | case GL_INVALID_ENUM: return "Invalid Enum"; | |
121 | case GL_INVALID_VALUE: return "Invalid Value"; | |
122 | case GL_INVALID_OPERATION: return "Invalid Operation"; | |
123 | case GL_STACK_OVERFLOW: return "Stack Overflow"; | |
124 | case GL_STACK_UNDERFLOW: return "Stack Underflow"; | |
125 | case GL_OUT_OF_MEMORY: return "Out of Memory"; | |
126 | default: return "Unknown Error"; | |
127 | } | |
128 | } | |
129 | ||
130 | void check(void) | |
131 | { | |
132 | for (;;) { | |
133 | const char *msg = error(); | |
134 | if (!msg) | |
135 | break; | |
136 | fputs(msg, stderr); | |
137 | } | |
138 | } | |
139 | ||
140 | void init(void) | |
141 | { | |
142 | glFrontFace(GL_CCW); | |
143 | //glEnable(GL_CULL_FACE); | |
144 | ||
145 | glEnable(GL_DEPTH_TEST); | |
146 | glDepthFunc(GL_LEQUAL); | |
147 | ||
148 | glEnable(GL_LIGHTING); | |
149 | ||
150 | glMaterialfv(GL_FRONT, GL_EMISSION, material_emission); | |
151 | glMaterialfv(GL_FRONT, GL_AMBIENT, material_ambient); | |
152 | glMaterialfv(GL_FRONT, GL_DIFFUSE, material_diffuse); | |
153 | glMaterialfv(GL_FRONT, GL_SPECULAR, material_specular); | |
154 | glMaterialf( GL_FRONT, GL_SHININESS, material_shininess); | |
155 | ||
156 | glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); | |
157 | glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); | |
158 | glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); | |
159 | ||
160 | glEnable(GL_LIGHT0); | |
161 | ||
162 | make_data(); | |
163 | ||
164 | glGenTextures(1, &shadowmap_); | |
165 | glBindTexture(GL_TEXTURE_2D, shadowmap_); | |
166 | glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, W, H, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL); | |
167 | ||
168 | glGenRenderbuffers(1, &renderbuffer_); | |
169 | glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer_); | |
170 | glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, W, H); | |
171 | ||
172 | glGenFramebuffers(1, &framebuffer_); | |
173 | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_); | |
174 | glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_); | |
175 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowmap_, 0); | |
176 | ||
177 | GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); | |
178 | if (status != GL_FRAMEBUFFER_COMPLETE) { | |
179 | fprintf(stderr, "framebuffer fail\n"); | |
180 | exit(1); | |
181 | } | |
182 | ||
183 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
184 | ||
185 | check(); | |
186 | } | |
187 | ||
188 | void renderSceneElements(void) | |
189 | { | |
190 | glDrawElements(GL_QUADS, (N-1)*(N-1)*4, GL_UNSIGNED_INT, (const GLvoid*) indices); | |
191 | } | |
192 | ||
193 | void draw(void) | |
194 | { | |
195 | double lightAspect_ = 1.0 * width / height; | |
196 | ||
197 | // position the light | |
198 | glLightfv(GL_LIGHT0, GL_POSITION, lightPos_); | |
199 | ||
200 | // switch the framebuffer for the first pass | |
201 | glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_); | |
202 | glViewport(0, 0, W, H); | |
203 | glClearColor(0.5, 0.2, 0.1, 1.0f); | |
204 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
205 | ||
206 | ||
207 | // set up the projection parameters from the light's POV | |
208 | glMatrixMode(GL_PROJECTION); | |
209 | glPushMatrix(); | |
210 | glLoadIdentity(); | |
211 | gluPerspective(lightFOV_, lightAspect_, lightNear_, lightFar_); | |
212 | ||
213 | glMatrixMode(GL_MODELVIEW); | |
214 | glPushMatrix(); | |
215 | glLoadIdentity(); | |
216 | // translate to the light's position | |
217 | gluLookAt(lightPos_[0], lightPos_[1], lightPos_[2], 0.0, 0.0, -2.0, 0.0, 1.0, 0.0); | |
218 | ||
219 | // render the scene to get the depth information | |
220 | renderSceneElements(); | |
221 | glPopMatrix(); | |
222 | ||
223 | // end the projection modification | |
224 | glMatrixMode(GL_PROJECTION); | |
225 | glPopMatrix(); | |
226 | glMatrixMode(GL_MODELVIEW); | |
227 | ||
228 | // switch back to the system framebuffer for the second pass | |
229 | glBindFramebuffer(GL_FRAMEBUFFER, 0); | |
230 | glClearColor(1,1,1,1); | |
231 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
232 | glViewport(0, 0, W, H); | |
233 | ||
234 | // matrix defining the planes for S, T, R, Q components for texture generation | |
235 | float planeMatrix[16]; | |
236 | glPushMatrix(); | |
237 | glLoadIdentity(); | |
238 | // compensate for the eye-coordinate to texture coordinate conversion: [-1,1] to [0,1] | |
239 | glTranslatef(0.5f, 0.5f, 0.499f); | |
240 | glScalef(0.5f, 0.5f, 0.5f); | |
241 | ||
242 | // do the perspective projection and translate to the light's position | |
243 | gluPerspective(lightFOV_, lightAspect_, lightNear_, lightFar_); | |
244 | gluLookAt(lightPos_[0], lightPos_[1], lightPos_[2], 0.0, 0.0, -2.0, 0.0, 1.0, 0.0); | |
245 | ||
246 | glGetFloatv(GL_MODELVIEW_MATRIX, planeMatrix); | |
247 | glPopMatrix(); | |
248 | ||
249 | // go from OpenGL's column-major to row-major matrix form | |
250 | transposeMatrix16(planeMatrix); | |
251 | ||
252 | // set up the type for texture generation | |
253 | glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
254 | glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
255 | glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
256 | glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | |
257 | ||
258 | // data for texture generation | |
259 | glTexGenfv(GL_S, GL_OBJECT_PLANE, &planeMatrix[0]); | |
260 | glTexGenfv(GL_T, GL_OBJECT_PLANE, &planeMatrix[4]); | |
261 | glTexGenfv(GL_R, GL_OBJECT_PLANE, &planeMatrix[8]); | |
262 | glTexGenfv(GL_Q, GL_OBJECT_PLANE, &planeMatrix[12]); | |
263 | ||
264 | glEnable(GL_TEXTURE_GEN_S); | |
265 | glEnable(GL_TEXTURE_GEN_T); | |
266 | glEnable(GL_TEXTURE_GEN_R); | |
267 | glEnable(GL_TEXTURE_GEN_Q); | |
268 | ||
269 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
270 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
271 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
272 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
273 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); | |
274 | glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); | |
275 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); | |
276 | ||
277 | glEnable(GL_TEXTURE_2D); | |
278 | glBindTexture(GL_TEXTURE_2D, shadowmap_); | |
279 | ||
280 | glEnable(GL_LIGHTING); | |
281 | glEnable(GL_LIGHT0); | |
282 | ||
283 | renderSceneElements(); | |
284 | ||
285 | glDisable(GL_LIGHTING); | |
286 | glDisable(GL_LIGHT0); | |
287 | ||
288 | glDisable(GL_TEXTURE_2D); | |
289 | ||
290 | glDisable(GL_TEXTURE_GEN_Q); | |
291 | glDisable(GL_TEXTURE_GEN_R); | |
292 | glDisable(GL_TEXTURE_GEN_T); | |
293 | glDisable(GL_TEXTURE_GEN_S); | |
294 | ||
295 | glutSwapBuffers(); | |
296 | } | |
297 | ||
298 | void key(unsigned char key, int x, int y) | |
299 | { | |
300 | if (key == '\033') | |
301 | exit(0); | |
302 | } | |
303 | ||
304 | void special(int k, int x, int y) | |
305 | { | |
306 | if (k == GLUT_KEY_HOME) | |
307 | memcpy(lightPos_, light_position, sizeof(lightPos_)); | |
308 | key_state[k] = 1; | |
309 | glutPostRedisplay(); | |
310 | } | |
311 | ||
312 | void special_up(int k, int x, int y) | |
313 | { | |
314 | key_state[k] = 0; | |
315 | glutPostRedisplay(); | |
316 | } | |
317 | ||
318 | void idle(void) | |
319 | { | |
320 | struct timeval tv; | |
321 | gettimeofday(&tv, NULL); | |
322 | double now = tv.tv_sec + tv.tv_usec * 1.0e-6; | |
323 | ||
324 | if (last <= 0) | |
325 | last = now; | |
326 | double t = now - last; | |
327 | last = now; | |
328 | ||
329 | double move = 1.0; | |
330 | ||
331 | for (int k = 0; k < 0x100; k++) { | |
332 | if (!key_state[k]) | |
333 | continue; | |
334 | if (k == GLUT_KEY_LEFT) lightPos_[0] -= move * t; | |
335 | if (k == GLUT_KEY_RIGHT) lightPos_[0] += move * t; | |
336 | if (k == GLUT_KEY_DOWN) lightPos_[1] -= move * t; | |
337 | if (k == GLUT_KEY_UP) lightPos_[1] += move * t; | |
338 | if (k == GLUT_KEY_PAGE_DOWN) lightPos_[2] -= move * t; | |
339 | if (k == GLUT_KEY_PAGE_UP) lightPos_[2] += move * t; | |
340 | } | |
341 | ||
342 | glutPostRedisplay(); | |
343 | } | |
344 | ||
345 | void resize(int w, int h) | |
346 | { | |
347 | if (h == 0) | |
348 | h = 1; | |
349 | ||
350 | width = w; | |
351 | height = h; | |
352 | ||
353 | glViewport(0, 0, w, h); | |
354 | glPushAttrib(GL_TRANSFORM_BIT); | |
355 | glMatrixMode(GL_PROJECTION); | |
356 | glLoadIdentity(); | |
357 | gluPerspective(lightFOV_, 1.0 * w / h, lightNear_, lightFar_); | |
358 | glPopAttrib(); | |
359 | } | |
360 | ||
361 | int main(int argc, char **argv) | |
362 | { | |
363 | glutInit(&argc, argv); | |
364 | ||
365 | glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); | |
366 | glutInitWindowSize(W, H); | |
367 | ||
368 | glutCreateWindow("Shadow map"); | |
369 | ||
370 | glutDisplayFunc(draw); | |
371 | glutReshapeFunc(resize); | |
372 | glutKeyboardFunc(key); | |
373 | glutSpecialFunc(special); | |
374 | glutSpecialUpFunc(special_up); | |
375 | glutIdleFunc(idle); | |
376 | ||
377 | init(); | |
378 | ||
379 | glutMainLoop(); | |
380 | ||
381 | return 0; | |
382 | } |