00001
00002 #include <GL/glut.h>
00003 #include <GL/glu.h>
00004 #include <stdlib.h>
00005 #include <math.h>
00006
00007 #ifdef WIN32
00008 #define near zNear
00009 #define far zFar
00010 #endif
00011
00012 #define PI_ 3.14159265358979323846
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021 #include "math.h"
00022
00023 typedef struct Point3Struct {
00024 double x, y, z;
00025 } Point3;
00026
00027
00028 bool normalize ( double[3]);
00029 void add ( double[3], double[3]);
00030
00031 void renderMirrorSurfacePolygons(void);
00032 void draw_scene(void);
00033 void renderMirrorSurfacePolygons(void);
00034 void mirrorMatrix(GLfloat [4][4],
00035 GLfloat [3],
00036 GLfloat [3]);
00037 void computeReflectionMatrixForMirror(GLfloat [4][4]);
00038 void computeMirrorClipPlane(GLdouble [4]);
00039 void drawBorder(void);
00040
00041
00042
00043 float z = 15.0;
00044
00045 bool changed = false;
00046
00047 bool FillPolygons = true;
00048
00049 GLfloat colorWhite[4] = {1,1,1,1};
00050 GLfloat colorDarkGrey[4] = { 0.2, 0.2, 0.2, 0.0 };
00051
00052 GLfloat ambient[] = { 0.1, 0.1, 0.1, 1.0 };
00053 GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
00054 GLfloat no_specular[] = { .0, .0, .0, 1.0 };
00055
00056 bool Specular = false;
00057 bool Lighting = true;
00058
00059 GLfloat LightPos[4] = {5.00, 5.0, 5.0, 1.0};
00060 GLfloat LightPos2[4] = {-10, -10, -10, 1};
00061
00062 GLfloat mirror_vertices[4][3] = { {-2, -2, -7}, {-2, 2, -7}, {2, 2, -7}, {2, -2, -7} };
00063 GLfloat mirror_center[3] = {0, 0, -7};
00064 GLfloat mirror_normal[3];
00065
00066 GLfloat border_vertices[4][3] = { {-2.5, -2.5, -7}, {-2.5, 2.5, -7}, {2.5, 2.5, -7}, {2.5, -2.5, -7} };
00067
00068 bool RotateMirrorUp = false, RotateMirrorDown = false, RotateMirrorLeft = false, RotateMirrorRight = false;
00069 bool MoveMirrorForward = false, MoveMirrorBackward = false;
00070
00071
00072 float AngleX=0, AngleY=0;
00073 bool RotateUp = false, RotateDown = false, RotateLeft = false, RotateRight = false;
00074
00075 float CameraX = 0, CameraY = 0, CameraZ = 5.0f;
00076
00077 int LastTime = 0;
00078 int TimerDelay = 50;
00079 float FPS = 0;
00080
00081 void computeMirrorClipPlane(GLdouble plane[4])
00082 {
00083 Point3 vertex[3];
00084 Point3Struct * vertex_ptr;
00085 Point3 normal;
00086 Point3Struct * normal_ptr;
00087 double A, B, C, D;
00088
00089 vertex[0].x = mirror_vertices[0][0];
00090 vertex[0].y = mirror_vertices[0][1];
00091 vertex[0].z = mirror_vertices[0][2];
00092
00093 vertex[1].x = mirror_vertices[1][0];
00094 vertex[1].y = mirror_vertices[1][1];
00095 vertex[1].z = mirror_vertices[1][2];
00096
00097 vertex[2].x = mirror_vertices[2][0];
00098 vertex[2].y = mirror_vertices[2][1];
00099 vertex[2].z = mirror_vertices[2][2];
00100
00101
00102
00103
00104 A = ( (vertex[1].y - vertex[0].y)*(vertex[2].z - vertex[0].z) ) - ( (vertex[1].z - vertex[0].z)*(vertex[2].y - vertex[0].y) );
00105 B = ( (vertex[1].z - vertex[0].z)*(vertex[2].x - vertex[0].x) ) - ( (vertex[2].z - vertex[0].z)*(vertex[1].x - vertex[0].x) );
00106 C = ( (vertex[1].x - vertex[0].x)*(vertex[2].y - vertex[0].y) ) - ( (vertex[1].y - vertex[0].y)*(vertex[2].x - vertex[0].x) );
00107 D = - ( vertex[0].x*A + vertex[0].y*B + vertex[0].z*C );
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 plane[0] = A;
00119 plane[1] = B;
00120 plane[2] = C;
00121 plane[3] = D;
00122
00123
00124 Point3 vertexa, vertexb, vertexc;
00125 double vector[3], vector2[3];
00126
00127 vertexa.x = mirror_vertices[0][0];
00128 vertexa.y = mirror_vertices[0][1];
00129 vertexa.z = mirror_vertices[0][2];
00130 vertexb.x = mirror_center[0];
00131 vertexb.y = mirror_center[1];
00132 vertexb.z = mirror_center[2];
00133 vertexc.x = mirror_vertices[1][0];
00134 vertexc.y = mirror_vertices[1][1];
00135 vertexc.z = mirror_vertices[1][2];
00136
00137
00138 vector[0] = vertexb.x - vertexa.x;
00139 vector[1] = vertexb.y - vertexa.y;
00140 vector[2] = vertexb.z - vertexa.z;
00141
00142
00143 vector2[0] = vertexc.x - vertexb.x;
00144 vector2[1] = vertexc.y - vertexb.y;
00145 vector2[2] = vertexc.z - vertexb.z;
00146
00147
00148 normal.x = (vector[1]*vector2[2] - vector[2]*vector2[1]);
00149 normal.y = (vector[2]*vector2[0] - vector[0]*vector2[2]);
00150 normal.z = (vector[0]*vector2[1] - vector[1]*vector2[0]);
00151
00152
00153 vector[0] = normal.x;
00154 vector[1] = normal.y;
00155 vector[2] = normal.z;
00156
00157
00158 if ( normalize ( vector ) )
00159 {
00160 printf(" normal is zero!\n");
00161 }
00162 mirror_normal[0] = vector[0];
00163 mirror_normal[1] = vector[1];
00164 mirror_normal[2] = vector[2];
00165
00166
00167 float k;
00168
00169 k = (A*LightPos[0] + B*LightPos[1] + C*LightPos[2] + D) / ( -(A*A + B*B + C*C) );
00170
00171 LightPos2[0] = LightPos[0] + 2*k*A;
00172 LightPos2[1] = LightPos[1] + 2*k*B;
00173 LightPos2[2] = LightPos[2] + 2*k*C;
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 }
00188
00189 void add ( double v[3], double v2[3])
00190 {
00191
00192 v[0] += v2[0];
00193 v[1] += v2[1];
00194 v[2] += v2[2];
00195
00196 }
00197
00198 bool normalize ( double v[3])
00199 {
00200 double d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
00201 if (d != 0.0)
00202 {
00203 v[0] /= d;
00204 v[1] /= d;
00205 v[2] /= d;
00206 return (false);
00207 }
00208 else
00209 printf(" zero normal?! hmm, strange... %f \n", d);
00210
00211 return (true);
00212
00213 }
00214
00215
00216
00217 void glutString( char *pstr )
00218 {
00219 while (*pstr!=char(0)) {
00220 glutBitmapCharacter( GLUT_BITMAP_8_BY_13, int( *pstr ));
00221 pstr++;
00222 }
00223 }
00224
00225 GLuint teapotList;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 void accFrustum(GLdouble left, GLdouble right, GLdouble bottom,
00243 GLdouble top, GLdouble near, GLdouble far, GLdouble pixdx,
00244 GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
00245 {
00246 GLdouble xwsize, ywsize;
00247 GLdouble dx, dy;
00248 GLint viewport[4];
00249
00250 glGetIntegerv (GL_VIEWPORT, viewport);
00251
00252 xwsize = right - left;
00253 ywsize = top - bottom;
00254
00255 dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*near/focus);
00256 dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*near/focus);
00257
00258 glMatrixMode(GL_PROJECTION);
00259 glLoadIdentity();
00260 glFrustum (left + dx, right + dx, bottom + dy, top + dy, near, far);
00261 glTranslatef(-0.5, -0.5, -5);
00262 glRotatef( AngleY, 0, 1, 0);
00263 glRotatef( AngleX, 1, 0, 0);
00264 glTranslatef(0.5, 0.5, 5);
00265 glMatrixMode(GL_MODELVIEW);
00266 glLoadIdentity();
00267 glTranslatef (-eyedx, -eyedy, 0.0);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 void accPerspective(GLdouble fovy, GLdouble aspect,
00284 GLdouble near, GLdouble far, GLdouble pixdx, GLdouble pixdy,
00285 GLdouble eyedx, GLdouble eyedy, GLdouble focus)
00286 {
00287 GLdouble fov2,left,right,bottom,top;
00288
00289 fov2 = ((fovy*PI_) / 180.0) / 2.0;
00290
00291 top = near / (cos(fov2) / sin(fov2));
00292 bottom = -top;
00293
00294 right = top * aspect;
00295 left = -right;
00296
00297 accFrustum (left, right, bottom, top, near, far,
00298 pixdx, pixdy, eyedx, eyedy, focus);
00299 }
00300
00301 void initGL(void)
00302 {
00303 GLenum performance = GL_NICEST;
00304 glHint(GL_POINT_SMOOTH_HINT, performance );
00305 glHint(GL_LINE_SMOOTH_HINT, performance );
00306 glHint(GL_POLYGON_SMOOTH_HINT, performance );
00307 glHint(GL_FOG_HINT, performance );
00308 glHint(GL_PERSPECTIVE_CORRECTION_HINT, performance );
00309
00310
00311
00312 glShadeModel(GL_SMOOTH);
00313 if (Lighting) glEnable(GL_LIGHTING);
00314
00315 glEnable( GL_NORMALIZE );
00316 glDisable(GL_CULL_FACE);
00317
00318 glLightfv(GL_LIGHT0, GL_DIFFUSE, colorWhite );
00319 glLightfv(GL_LIGHT0, GL_AMBIENT, colorDarkGrey );
00320 glLightfv(GL_LIGHT0, GL_SPECULAR, no_specular);
00321
00322 glLightfv(GL_LIGHT1, GL_DIFFUSE, colorWhite );
00323 glLightfv(GL_LIGHT1, GL_AMBIENT, colorDarkGrey );
00324 glLightfv(GL_LIGHT1, GL_SPECULAR, no_specular);
00325
00326
00327
00328 glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, .001);
00329 glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, .001);
00330
00331 GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
00332 GLfloat local_view[] = { 0.0 };
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 glFrontFace (GL_CW);
00345 if (Lighting) glEnable(GL_LIGHTING);
00346
00347
00348 glEnable(GL_NORMALIZE);
00349 glEnable(GL_DEPTH_TEST);
00350
00351 glClearColor(0.0, 0.0, 0.0, 0.0);
00352 glClearAccum(0.0, 0.0, 0.0, 0.0);
00353
00354 teapotList = glGenLists(1);
00355 glNewList (teapotList, GL_COMPILE);
00356 glutSolidTeapot (0.5);
00357 glEndList ();
00358 }
00359
00360 void renderTeapot (GLfloat x, GLfloat y, GLfloat z,
00361 GLfloat ambr, GLfloat ambg, GLfloat ambb,
00362 GLfloat difr, GLfloat difg, GLfloat difb,
00363 GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine)
00364 {
00365 GLfloat mat[4];
00366
00367 glPushMatrix();
00368 glTranslatef (x, y, z);
00369 mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0;
00370 glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
00371 mat[0] = difr; mat[1] = difg; mat[2] = difb;
00372 glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
00373 mat[0] = specr; mat[1] = specg; mat[2] = specb;
00374 glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
00375 glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
00376 glCallList(teapotList);
00377 glPopMatrix();
00378 }
00379
00380 void draw_scene(void)
00381 {
00382 renderTeapot (-1.1, -0.5, -4.5, 0.1745, 0.01175,
00383 0.01175, 0.61424, 0.04136, 0.04136,
00384 0.727811, 0.626959, 0.626959, 0.6);
00385 renderTeapot (-0.5, -0.5, -5.0, 0.24725, 0.1995,
00386 0.0745, 0.75164, 0.60648, 0.22648,
00387 0.628281, 0.555802, 0.366065, 0.4);
00388 renderTeapot (0.2, -0.5, -5.5, 0.19225, 0.19225,
00389 0.19225, 0.50754, 0.50754, 0.50754,
00390 0.508273, 0.508273, 0.508273, 0.4);
00391 renderTeapot (1.0, -0.5, -6.0, 0.0215, 0.1745, 0.0215,
00392 0.07568, 0.61424, 0.07568, 0.633,
00393 0.727811, 0.633, 0.6);
00394 renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0,
00395 0.50980392, 0.50980392, 0.50196078,
00396 0.50196078, 0.50196078, .25);
00397 }
00398
00399 void renderMirrorSurfacePolygons(void)
00400 {
00401
00402 glBegin(GL_TRIANGLES);
00403 glVertex3fv(mirror_vertices[0]);
00404 glVertex3fv(mirror_center);
00405 glVertex3fv(mirror_vertices[1]);
00406
00407 glVertex3fv(mirror_vertices[1]);
00408 glVertex3fv(mirror_center);
00409 glVertex3fv(mirror_vertices[2]);
00410
00411 glVertex3fv(mirror_vertices[2]);
00412 glVertex3fv(mirror_center);
00413 glVertex3fv(mirror_vertices[3]);
00414
00415 glVertex3fv(mirror_vertices[3]);
00416 glVertex3fv(mirror_center);
00417 glVertex3fv(mirror_vertices[0]);
00418 glEnd();
00419 }
00420
00421 void drawBorder(void)
00422 {
00423 glColor4f(.5,.5,.5, 0.5);
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 glBegin(GL_QUADS);
00443 glVertex3fv(border_vertices[0]);
00444 glVertex3fv(mirror_vertices[0]);
00445 glVertex3fv(mirror_vertices[1]);
00446 glVertex3fv(border_vertices[1]);
00447
00448 glVertex3fv(border_vertices[1]);
00449 glVertex3fv(mirror_vertices[1]);
00450 glVertex3fv(mirror_vertices[2]);
00451 glVertex3fv(border_vertices[2]);
00452
00453 glVertex3fv(border_vertices[2]);
00454 glVertex3fv(mirror_vertices[2]);
00455 glVertex3fv(mirror_vertices[3]);
00456 glVertex3fv(border_vertices[3]);
00457
00458 glVertex3fv(border_vertices[3]);
00459 glVertex3fv(mirror_vertices[3]);
00460 glVertex3fv(mirror_vertices[0]);
00461 glVertex3fv(border_vertices[0]);
00462
00463 glEnd();
00464 }
00465
00466 void mirrorMatrix(GLfloat m[4][4],
00467 GLfloat p[3],
00468 GLfloat v[3])
00469 {
00470
00471 GLfloat dot = p[0]*v[0] + p[1]*v[1] + p[2]*v[2];
00472
00473 m[0][0] = 1 - 2*v[0]*v[0];
00474 m[1][0] = - 2*v[0]*v[1];
00475 m[2][0] = - 2*v[0]*v[2];
00476 m[3][0] = 2*dot*v[0];
00477
00478 m[0][1] = - 2*v[1]*v[0];
00479 m[1][1] = 1 - 2*v[1]*v[1];
00480 m[2][1] = - 2*v[1]*v[2];
00481 m[3][1] = 2*dot*v[1];
00482
00483 m[0][2] = - 2*v[2]*v[0];
00484 m[1][2] = - 2*v[2]*v[1];
00485 m[2][2] = 1 - 2*v[2]*v[2];
00486 m[3][2] = 2*dot*v[2];
00487
00488 m[0][3] = 0;
00489 m[1][3] = 0;
00490 m[2][3] = 0;
00491 m[3][3] = 1;
00492
00493 }
00494
00495 void computeReflectionMatrixForMirror(GLfloat matrix[4][4])
00496 {
00497
00498 mirrorMatrix((GLfloat (*)[4])&matrix[0][0],
00499 &mirror_vertices[0][0],
00500 &mirror_normal[0]);
00501 }
00502
00503 void display(void)
00504 {
00505 GLint viewport[4];
00506 if (Lighting) glEnable(GL_LIGHTING);
00507
00508
00509
00510 glClearColor(0.0, 0.0, 0.0, 0.0);
00511
00512
00513 glGetIntegerv (GL_VIEWPORT, viewport);
00514
00515
00516 accPerspective (45.0,
00517 (GLdouble) viewport[2]/(GLdouble) viewport[3],
00518 1.0, 15.0, 0.0, 0.0,
00519 0, 0, z);
00520
00521
00522 glClearStencil(0);
00523 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00524
00525 glEnable(GL_STENCIL_BUFFER_BIT);
00526 glEnable(GL_DEPTH_BUFFER_BIT);
00527 glEnable(GL_DEPTH_TEST);
00528 glDisable(GL_STENCIL_TEST);
00529
00530
00531
00532
00533
00534
00535
00536 GLfloat matrix[4][4];
00537 GLdouble clipPlane[4];
00538
00539
00540 computeMirrorClipPlane(&clipPlane[0]);
00541
00542 glLightfv(GL_LIGHT1, GL_POSITION, LightPos2);
00543 glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
00544 glEnable(GL_LIGHT1);
00545 glDisable(GL_LIGHT0);
00546
00547
00548
00549
00550
00551 glEnable(GL_STENCIL_TEST);
00552 glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
00553 glStencilFunc(GL_ALWAYS, 1, ~0);
00554 glColorMask(0, 0, 0, 0);
00555 renderMirrorSurfacePolygons();
00556
00557
00558 glDepthRange(1,1);
00559 glDepthFunc(GL_ALWAYS);
00560 glStencilFunc(GL_EQUAL, 1, ~0);
00561 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
00562 renderMirrorSurfacePolygons();
00563
00564
00565 glDepthFunc(GL_LESS);
00566 glColorMask(1,1,1,1);
00567 glDepthRange(0,1);
00568
00569
00570
00571 glPushMatrix();
00572
00573
00574
00575
00576 glClipPlane(GL_CLIP_PLANE0, &clipPlane[0]);
00577 glEnable(GL_CLIP_PLANE0);
00578
00579 computeReflectionMatrixForMirror(
00580 (GLfloat (*) [4])&matrix[0][0]);
00581
00582 glMultMatrixf(&matrix[0][0]);
00583
00584 glCullFace(GL_FRONT);
00585
00586
00587
00588
00589
00590 draw_scene();
00591 drawBorder();
00592
00593 glCullFace(GL_BACK);
00594 glDisable(GL_CLIP_PLANE0);
00595 glPopMatrix();
00596
00597
00598
00599 glColorMask(0, 0, 0, 0);
00600 glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
00601 glDepthFunc(GL_ALWAYS);
00602 renderMirrorSurfacePolygons();
00603 glDepthFunc(GL_LESS);
00604 glColorMask(1,1,1,1);
00605
00606 glCullFace(GL_FRONT);
00607 glDepthFunc(GL_LESS);
00608 glDisable(GL_STENCIL_TEST);
00609
00610 glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
00611 glEnable(GL_LIGHT0);
00612 glDisable(GL_LIGHT1);
00613
00614 draw_scene();
00615 drawBorder();
00616
00617
00618
00619
00620
00621
00622 glDepthFunc(GL_LESS);
00623
00624
00625
00626
00627 glDisable(GL_BLEND);
00628
00629
00630 glPushMatrix();
00631 char buf[100];
00632 sprintf( buf, " %0.2f fps, X=%f, Y=%f, Z=%f, alpha=%f, beta=%f ", FPS, CameraX, CameraY, CameraZ,
00633 AngleX, AngleY );
00634 glMatrixMode( GL_PROJECTION );
00635 glLoadIdentity();
00636 glMatrixMode( GL_MODELVIEW );
00637 glLoadIdentity();
00638 glDisable( GL_DEPTH_TEST );
00639 glDisable( GL_LIGHTING );
00640 glColor3f( 1.0f, 1.0f, 1.0f );
00641 glRasterPos2f( -1,-1 );
00642 glutString( buf );
00643 glEnable( GL_DEPTH_TEST );
00644 if (Lighting) glEnable(GL_LIGHTING);
00645 glPopMatrix();
00646
00647 glutSwapBuffers();
00648 }
00649
00650 void reshape(int w, int h)
00651 {
00652 changed = true;
00653 glViewport(0, 0, (GLsizei) w, (GLsizei) h);
00654 glutPostRedisplay();
00655 }
00656
00657 void keyboard(unsigned char key, int x, int y)
00658 {
00659 switch (key) {
00660 case 27:
00661 case 'q':
00662 exit(0);
00663 break;
00664 case ' ':
00665 glutPostRedisplay();
00666 break;
00667 case 'a':
00668 RotateLeft = true;
00669 RotateRight = false;
00670 break;
00671 case 'd':
00672 RotateRight = true;
00673 RotateLeft = false;
00674 break;
00675 case 'w':
00676 RotateUp = true;
00677 RotateDown = false;
00678 break;
00679 case 's':
00680 RotateDown = true;
00681 RotateUp = false;
00682 break;
00683 case 't':
00684 RotateMirrorUp = true;
00685 RotateMirrorDown = false;
00686 break;
00687 case 'g':
00688 RotateMirrorDown = true;
00689 RotateMirrorUp = false;
00690 break;
00691 case 'f':
00692 RotateMirrorLeft = true;
00693 RotateMirrorRight = false;
00694 break;
00695 case 'h':
00696 RotateMirrorRight = true;
00697 RotateMirrorLeft = false;
00698 break;
00699 case 'v':
00700 MoveMirrorForward = true;
00701 MoveMirrorBackward = false;
00702 break;
00703 case 'b':
00704 MoveMirrorForward = false;
00705 MoveMirrorBackward = true;
00706 break;
00707 case 'o':
00708 Specular = !Specular;
00709 if (!Specular)
00710 {
00711 glLightfv(GL_LIGHT0, GL_SPECULAR, no_specular);
00712 glLightfv(GL_LIGHT1, GL_SPECULAR, no_specular);
00713 }
00714 else
00715 {
00716 glLightfv(GL_LIGHT0, GL_SPECULAR, colorWhite );
00717 glLightfv(GL_LIGHT1, GL_SPECULAR, colorWhite );
00718 };
00719 break;
00720 case 'l': Lighting = !Lighting;
00721 if (Lighting)
00722 glEnable(GL_LIGHTING);
00723 else
00724 glDisable(GL_LIGHTING);
00725 break;
00726
00727 case 'p': FillPolygons = !FillPolygons;
00728 glPolygonMode( GL_FRONT_AND_BACK, (FillPolygons ? GL_FILL : GL_LINE) );
00729 break;
00730 }
00731 }
00732
00733
00734 static void timerCallback(int)
00735 {
00736
00737 int nc = glutGet(GLUT_ELAPSED_TIME);
00738 float fSec = float(nc-LastTime) / 1000.0f;
00739
00740 FPS = (19.0f*FPS + 1.0f / fSec) / 20.0f;
00741 LastTime = nc;
00742
00743 float fCamArc = fSec * 180.0f;
00744 if (RotateLeft) AngleY -= fCamArc/4;
00745 if (RotateRight) AngleY += fCamArc/4;
00746 if (RotateUp) AngleX += fCamArc/4;
00747 if (RotateDown) AngleX -= fCamArc/4;
00748
00749 GLfloat angle = fCamArc/4;
00750 GLfloat rotatematrix[16];
00751 GLfloat translatematrix[16];
00752
00753 if ((RotateMirrorLeft) || (RotateMirrorRight) )
00754 {
00755
00756 if (RotateMirrorLeft) angle = -angle;
00757
00758
00759 angle = angle * M_PI/180.0f;
00760
00761
00762
00763
00764
00765
00766
00767
00768 rotatematrix[0] = cos(angle); rotatematrix[1] = 0; rotatematrix[2] = sin(angle); rotatematrix[3] = 0;
00769 rotatematrix[4] = 0; rotatematrix[5] = 1; rotatematrix[6] = 0; rotatematrix[7] = 0;
00770 rotatematrix[8] = -sin(angle); rotatematrix[9] = 0; rotatematrix[10] = cos(angle); rotatematrix[11] = 0;
00771 rotatematrix[12] = 0; rotatematrix[13] = 0; rotatematrix[14] = 0; rotatematrix[15] = 1;
00772
00773 translatematrix[0] = 1; translatematrix[1] = 0; translatematrix[2] = 0; translatematrix[3] = -mirror_center[0];
00774 translatematrix[4] = 0; translatematrix[5] = 1; translatematrix[6] = 0; translatematrix[7] = -mirror_center[1];
00775 translatematrix[8] = 0; translatematrix[9] = 0; translatematrix[10] = 1; translatematrix[11] = -mirror_center[2];
00776 translatematrix[12] = 0; translatematrix[13] = 0; translatematrix[14] = 0; translatematrix[15] = 1;
00777
00778 GLfloat vector[4];
00779
00780 for (int i=0; i<4; i++)
00781 {
00782
00783 mirror_vertices[i][0] -= mirror_center[0];
00784 mirror_vertices[i][1] -= mirror_center[1];
00785 mirror_vertices[i][2] -= mirror_center[2];
00786
00787 border_vertices[i][0] -= mirror_center[0];
00788 border_vertices[i][1] -= mirror_center[1];
00789 border_vertices[i][2] -= mirror_center[2];
00790
00791
00792 Multiply<GLfloat> (rotatematrix, mirror_vertices[i], vector);
00793 mirror_vertices[i][0] = vector[0];
00794 mirror_vertices[i][1] = vector[1];
00795 mirror_vertices[i][2] = vector[2];
00796 mirror_vertices[i][3] = vector[3];
00797 Multiply<GLfloat> (rotatematrix, border_vertices[i], vector);
00798 border_vertices[i][0] = vector[0];
00799 border_vertices[i][1] = vector[1];
00800 border_vertices[i][2] = vector[2];
00801 border_vertices[i][3] = vector[3];
00802
00803
00804 mirror_vertices[i][0] += mirror_center[0];
00805 mirror_vertices[i][1] += mirror_center[1];
00806 mirror_vertices[i][2] += mirror_center[2];
00807
00808 border_vertices[i][0] += mirror_center[0];
00809 border_vertices[i][1] += mirror_center[1];
00810 border_vertices[i][2] += mirror_center[2];
00811 }
00812 }
00813
00814
00815 if ((RotateMirrorUp) || (RotateMirrorDown) )
00816 {
00817
00818 if (RotateMirrorDown) angle = -angle;
00819
00820
00821 angle = angle * M_PI/180.0f;
00822
00823
00824 rotatematrix[0] = 1; rotatematrix[1] = 0; rotatematrix[2] = 0; rotatematrix[3] = 0;
00825 rotatematrix[4] = 0; rotatematrix[5] = cos(angle); rotatematrix[6] = -sin(angle); rotatematrix[7] = 0;
00826 rotatematrix[8] = 0; rotatematrix[9] = sin(angle); rotatematrix[10] = cos(angle); rotatematrix[11] = 0;
00827 rotatematrix[12] = 0; rotatematrix[13] = 0; rotatematrix[14] = 0; rotatematrix[15] = 1;
00828
00829
00830
00831
00832
00833
00834
00835 translatematrix[0] = 1; translatematrix[1] = 0; translatematrix[2] = 0; translatematrix[3] = -mirror_center[0];
00836 translatematrix[4] = 0; translatematrix[5] = 1; translatematrix[6] = 0; translatematrix[7] = -mirror_center[1];
00837 translatematrix[8] = 0; translatematrix[9] = 0; translatematrix[10] = 1; translatematrix[11] = -mirror_center[2];
00838 translatematrix[12] = 0; translatematrix[13] = 0; translatematrix[14] = 0; translatematrix[15] = 1;
00839
00840 GLfloat vector[4];
00841
00842 for (int i=0; i<4; i++)
00843 {
00844
00845 mirror_vertices[i][0] -= mirror_center[0];
00846 mirror_vertices[i][1] -= mirror_center[1];
00847 mirror_vertices[i][2] -= mirror_center[2];
00848
00849 border_vertices[i][0] -= mirror_center[0];
00850 border_vertices[i][1] -= mirror_center[1];
00851 border_vertices[i][2] -= mirror_center[2];
00852
00853
00854 Multiply<GLfloat> (rotatematrix, mirror_vertices[i], vector);
00855 mirror_vertices[i][0] = vector[0];
00856 mirror_vertices[i][1] = vector[1];
00857 mirror_vertices[i][2] = vector[2];
00858 mirror_vertices[i][3] = vector[3];
00859 Multiply<GLfloat> (rotatematrix, border_vertices[i], vector);
00860 border_vertices[i][0] = vector[0];
00861 border_vertices[i][1] = vector[1];
00862 border_vertices[i][2] = vector[2];
00863 border_vertices[i][3] = vector[3];
00864
00865
00866 mirror_vertices[i][0] += mirror_center[0];
00867 mirror_vertices[i][1] += mirror_center[1];
00868 mirror_vertices[i][2] += mirror_center[2];
00869
00870 border_vertices[i][0] += mirror_center[0];
00871 border_vertices[i][1] += mirror_center[1];
00872 border_vertices[i][2] += mirror_center[2];
00873 }
00874 }
00875
00876 float distance = .10f;
00877 if ((MoveMirrorForward) || (MoveMirrorBackward))
00878 {
00879 distance = (MoveMirrorForward ? distance : -distance );
00880
00881 for (int i=0; i<4; i++)
00882 {
00883
00884 mirror_vertices[i][0] += mirror_normal[0] * distance;
00885 mirror_vertices[i][1] += mirror_normal[1] * distance;
00886 mirror_vertices[i][2] += mirror_normal[2] * distance;
00887
00888
00889 border_vertices[i][0] += mirror_normal[0] * distance;
00890 border_vertices[i][1] += mirror_normal[1] * distance;
00891 border_vertices[i][2] += mirror_normal[2] * distance;
00892 }
00893
00894
00895 mirror_center[0] += mirror_normal[0] * distance;
00896 mirror_center[1] += mirror_normal[1] * distance;
00897 mirror_center[2] += mirror_normal[2] * distance;
00898
00899 }
00900
00901 glutPostRedisplay();
00902 glutTimerFunc(TimerDelay, timerCallback, 0);
00903
00904 }
00905
00906
00907
00908
00909
00910
00911
00912 void keyboardUp(unsigned char key, int, int)
00913 {
00914 switch (key)
00915 {
00916 case 'a': RotateLeft = false; break;
00917 case 'd': RotateRight = false; break;
00918 case 'w': RotateUp = false; break;
00919 case 's': RotateDown = false; break;
00920 case 't': RotateMirrorUp = false; break;
00921 case 'g': RotateMirrorDown = false; break;
00922 case 'f': RotateMirrorLeft = false; break;
00923 case 'h': RotateMirrorRight = false; break;
00924 case 'v': MoveMirrorForward = false; break;
00925 case 'b': MoveMirrorBackward = false; break;
00926 }
00927
00928 }
00929
00930 int main(int argc, char** argv)
00931 {
00932
00933 printf(" Keys: \n");
00934 printf("\ta,d,w,s -- to rotate about gold teapot.\n");
00935 printf("\tf,h,t,g -- to rotate mirror.\n");
00936 printf("\tv,b -- to move mirro back and force.\n");
00937 printf("\tp -- to toggle polygon fill mode.\n");
00938 printf("\tl -- to toggle lighting.\n");
00939 printf("\to -- to toggle specular lighting.\n");
00940 printf("\tq -- to Quit.\n");
00941
00942 glutInit(&argc, argv);
00943 glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB
00944 | GLUT_STENCIL | GLUT_DEPTH);
00945 glutInitWindowSize (400, 400);
00946 glutInitWindowPosition (100, 100);
00947 glutCreateWindow (argv[0]);
00948 initGL();
00949 glutReshapeFunc(reshape);
00950 glutDisplayFunc(display);
00951 glutKeyboardFunc(keyboard);
00952 glutKeyboardUpFunc(keyboardUp);
00953 LastTime = glutGet (GLUT_ELAPSED_TIME );
00954 glutTimerFunc ( TimerDelay, timerCallback, 0);
00955 glutMainLoop();
00956 return 0;
00957 }
00958