View difference between Paste ID: JQzGr1Rk and MHGDxsSf
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
}