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