projtex.c
上传用户:xk288cn
上传日期:2007-05-28
资源大小:4876k
文件大小:21k
源码类别:

GIS编程

开发平台:

Visual C++

  1. /*
  2. ** Demonstrates simple projective texture mapping.
  3. **
  4. ** Button1 changes view, Button2 moves texture.
  5. **
  6. ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli
  7. **  "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92)
  8. **
  9. ** 1994,1995 -- David G Yu
  10. **
  11. ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm
  12. */
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <math.h>
  16. #include <GL/glut.h>
  17. #include "texture.h"
  18. /* Some <math.h> files do not define M_PI... */
  19. #ifndef M_PI
  20. #define M_PI 3.14159265358979323846
  21. #endif
  22. int winWidth, winHeight;
  23. GLboolean redrawContinuously;
  24. float angle, axis[3];
  25. enum MoveModes { MoveNone, MoveView, MoveObject, MoveTexture };
  26. enum MoveModes mode = MoveNone;
  27. GLfloat objectXform[4][4];
  28. GLfloat textureXform[4][4];
  29. void (*drawObject)(void);
  30. void (*loadTexture)(void);
  31. GLboolean textureEnabled = GL_TRUE;
  32. GLboolean showProjection = GL_TRUE;
  33. GLboolean linearFilter = GL_TRUE;
  34. char *texFilename = NULL;
  35. GLfloat zoomFactor = 1.0;
  36. /*****************************************************************/
  37. /* matrix = identity */
  38. void
  39. matrixIdentity(GLfloat matrix[16])
  40. {
  41.     matrix[ 0] = 1.0;
  42.     matrix[ 1] = 0.0;
  43.     matrix[ 2] = 0.0;
  44.     matrix[ 3] = 0.0;
  45.     matrix[ 4] = 0.0;
  46.     matrix[ 5] = 1.0;
  47.     matrix[ 6] = 0.0;
  48.     matrix[ 7] = 0.0;
  49.     matrix[ 8] = 0.0;
  50.     matrix[ 9] = 0.0;
  51.     matrix[10] = 1.0;
  52.     matrix[11] = 0.0;
  53.     matrix[12] = 0.0;
  54.     matrix[13] = 0.0;
  55.     matrix[14] = 0.0;
  56.     matrix[15] = 1.0;
  57. }
  58. /* matrix2 = transpose(matrix1) */
  59. void
  60. matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16])
  61. {
  62.     matrix2[ 0] = matrix1[ 0];
  63.     matrix2[ 1] = matrix1[ 4];
  64.     matrix2[ 2] = matrix1[ 8];
  65.     matrix2[ 3] = matrix1[12];
  66.     matrix2[ 4] = matrix1[ 1];
  67.     matrix2[ 5] = matrix1[ 5];
  68.     matrix2[ 6] = matrix1[ 9];
  69.     matrix2[ 7] = matrix1[13];
  70.     matrix2[ 8] = matrix1[ 2];
  71.     matrix2[ 9] = matrix1[ 6];
  72.     matrix2[10] = matrix1[10];
  73.     matrix2[11] = matrix1[14];
  74.     matrix2[12] = matrix1[ 3];
  75.     matrix2[13] = matrix1[ 7];
  76.     matrix2[14] = matrix1[14];
  77.     matrix2[15] = matrix1[15];
  78. }
  79. /*****************************************************************/
  80. /* load SGI .rgb image (pad with a border of the specified width and color) */
  81. static void
  82. imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4],
  83. int *wOut, int *hOut, GLubyte **imgOut)
  84. {
  85.     int border = borderIn;
  86.     int width, height;
  87.     int w, h;
  88.     GLubyte *image, *img, *p;
  89.     int i, j, components;
  90.     image = (GLubyte *)read_texture(filenameIn, &width, &height, &components);
  91.     w = width + 2*border;
  92.     h = height + 2*border;
  93.     img = (GLubyte *) calloc(w*h, 4*sizeof(unsigned char));
  94.     p = img;
  95.     for (j=-border; j<height+border; ++j) {
  96. for (i=-border; i<width+border; ++i) {
  97.     if (0 <= j && j <= height-1 && 0 <= i && i <= width-1) {
  98. p[0] = image[4*(j*width+i)+0];
  99. p[1] = image[4*(j*width+i)+1];
  100. p[2] = image[4*(j*width+i)+2];
  101. p[3] = 0xff;
  102.     } else {
  103. p[0] = borderColorIn[0] * 0xff;
  104. p[1] = borderColorIn[1] * 0xff;
  105. p[2] = borderColorIn[2] * 0xff;
  106. p[3] = borderColorIn[3] * 0xff;
  107.     }
  108.     p += 4;
  109. }
  110.     }
  111.     free(image);
  112.     *wOut = w;
  113.     *hOut = h;
  114.     *imgOut = img;
  115. }
  116. /*****************************************************************/
  117. /* Load the image file specified on the command line as the current texture */
  118. void
  119. loadImageTexture(void)
  120. {
  121.     static int texWidth, texHeight;
  122.     static GLubyte *texData; 
  123.     GLfloat borderColor[4] = { 1.0, 1.0, 1.0, 1.0 };
  124.     if (!texData) {
  125. imgLoad(texFilename, 2, borderColor, &texWidth, &texHeight, &texData);
  126.     }
  127.     if (linearFilter) {
  128. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  129. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  130.     } else {
  131. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  132. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  133.     }
  134.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
  135.     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight,
  136.       GL_RGBA, GL_UNSIGNED_BYTE, texData);
  137. }
  138. /* Create a simple spotlight pattern and make it the current texture */
  139. void
  140. loadSpotlightTexture(void)
  141. {
  142.     static int texWidth = 64, texHeight = 64;
  143.     static GLubyte *texData; 
  144.     GLfloat borderColor[4] = { 0.1, 0.1, 0.1, 1.0 };
  145.     if (!texData) {
  146. GLubyte *p;
  147. int i, j;
  148. texData = (GLubyte *) malloc(texWidth*texHeight*4*sizeof(GLubyte));
  149. p = texData;
  150. for (j=0; j<texHeight; ++j) {
  151.     float dy = (texHeight*0.5 - j+0.5) / (texHeight*0.5);
  152.     for (i=0; i<texWidth; ++i) {
  153. float dx = (texWidth*0.5 - i+0.5) / (texWidth*0.5);
  154. float r = cos(M_PI/2.0 * sqrt(dx*dx +dy*dy));
  155. float c;
  156. r = (r < 0) ? 0 : r*r;
  157. c = 0xff * (r + borderColor[0]);
  158. p[0] = (c <= 0xff) ? c : 0xff;
  159. c = 0xff * (r + borderColor[1]);
  160. p[1] = (c <= 0xff) ? c : 0xff;
  161. c = 0xff * (r + borderColor[2]);
  162. p[2] = (c <= 0xff) ? c : 0xff;
  163. c = 0xff * (r + borderColor[3]);
  164. p[3] = (c <= 0xff) ? c : 0xff;
  165. p += 4;
  166.     }
  167. }
  168.     }
  169.     if (linearFilter) {
  170. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  171. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  172.     } else {
  173. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  174. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  175.     }
  176.     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
  177.     gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight,
  178.       GL_RGBA, GL_UNSIGNED_BYTE, texData);
  179. }
  180. /*****************************************************************/
  181. void
  182. checkErrors(void)
  183. {
  184.     GLenum error;
  185.     while ((error = glGetError()) != GL_NO_ERROR) {
  186. fprintf(stderr, "Error: %sn", (char *) gluErrorString(error));
  187.     }
  188. }
  189. void
  190. drawCube(void)
  191. {
  192.     glBegin(GL_QUADS);
  193.     glNormal3f(-1.0, 0.0, 0.0 );
  194.     glColor3f(0.80, 0.50, 0.50);
  195.     glVertex3f(-0.5,-0.5,-0.5 ); glVertex3f(-0.5,-0.5, 0.5 );
  196.     glVertex3f(-0.5, 0.5, 0.5 ); glVertex3f(-0.5, 0.5,-0.5 );
  197.     glNormal3f( 1.0, 0.0, 0.0 );
  198.     glColor3f(0.50, 0.80, 0.50);
  199.     glVertex3f( 0.5, 0.5, 0.5 ); glVertex3f( 0.5,-0.5, 0.5 );
  200.     glVertex3f( 0.5,-0.5,-0.5 ); glVertex3f( 0.5, 0.5,-0.5 );
  201.     glNormal3f( 0.0,-1.0, 0.0 );
  202.     glColor3f(0.50, 0.50, 0.80);
  203.     glVertex3f(-0.5,-0.5,-0.5 ); glVertex3f( 0.5,-0.5,-0.5 );
  204.     glVertex3f( 0.5,-0.5, 0.5 ); glVertex3f(-0.5,-0.5, 0.5 );
  205.     glNormal3f( 0.0, 1.0, 0.0 );
  206.     glColor3f(0.50, 0.80, 0.80);
  207.     glVertex3f( 0.5, 0.5, 0.5 ); glVertex3f( 0.5, 0.5,-0.5 );
  208.     glVertex3f(-0.5, 0.5,-0.5 ); glVertex3f(-0.5, 0.5, 0.5 );
  209.     glNormal3f( 0.0, 0.0,-1.0 );
  210.     glColor3f(0.80, 0.50, 0.80);
  211.     glVertex3f(-0.5,-0.5,-0.5 ); glVertex3f(-0.5, 0.5,-0.5 );
  212.     glVertex3f( 0.5, 0.5,-0.5 ); glVertex3f( 0.5,-0.5,-0.5 );
  213.     glNormal3f( 0.0, 0.0, 1.0 );
  214.     glColor3f(1.00, 0.80, 0.50);
  215.     glVertex3f( 0.5, 0.5, 0.5 ); glVertex3f(-0.5, 0.5, 0.5 );
  216.     glVertex3f(-0.5,-0.5, 0.5 ); glVertex3f( 0.5,-0.5, 0.5 );
  217.     glEnd();
  218. }
  219. void
  220. drawDodecahedron(void)
  221. {
  222. #define A (0.5 * 1.61803) /* (sqrt(5) + 1) / 2 */
  223. #define B (0.5 * 0.61803) /* (sqrt(5) - 1) / 2 */
  224. #define C (0.5 * 1.0)
  225.     GLfloat vertexes[20][3] = {
  226. {-A, 0.0, B }, {-A, 0.0,-B }, { A, 0.0,-B }, { A, 0.0, B },
  227. { B,-A, 0.0 }, {-B,-A, 0.0 }, {-B, A, 0.0 }, { B, A, 0.0 },
  228. { 0.0, B,-A }, { 0.0,-B,-A }, { 0.0,-B, A }, { 0.0, B, A },
  229. {-C,-C, C }, {-C,-C,-C }, { C,-C,-C }, { C,-C, C },
  230. {-C, C, C }, {-C, C,-C }, { C, C,-C }, { C, C, C },
  231.     };
  232. #undef A
  233. #undef B
  234. #undef C
  235.     GLint polygons[12][5] = {
  236. {  0, 12, 10, 11, 16 },
  237. {  1, 17,  8,  9, 13 },
  238. {  2, 14,  9,  8, 18 },
  239. {  3, 19, 11, 10, 15 },
  240. {  4, 14,  2,  3, 15 },
  241. {  5, 12,  0,  1, 13 },
  242. {  6, 17,  1,  0, 16 },
  243. {  7, 19,  3,  2, 18 },
  244. {  8, 17,  6,  7, 18 },
  245. {  9, 14,  4,  5, 13 },
  246. { 10, 12,  5,  4, 15 },
  247. { 11, 19,  7,  6, 16 },
  248.     };
  249.     int i;
  250.     glColor3f(0.75, 0.75, 0.75);
  251.     for (i=0; i<12; ++i) {
  252. GLfloat *p0, *p1, *p2, d;
  253. GLfloat u[3], v[3], n[3];
  254. p0 = &vertexes[polygons[i][0]][0];
  255. p1 = &vertexes[polygons[i][1]][0];
  256. p2 = &vertexes[polygons[i][2]][0];
  257. u[0] = p2[0] - p1[0];
  258. u[1] = p2[1] - p1[1];
  259. u[2] = p2[2] - p1[2];
  260. v[0] = p0[0] - p1[0];
  261. v[1] = p0[1] - p1[1];
  262. v[2] = p0[2] - p1[2];
  263. n[0] = u[1]*v[2] - u[2]*v[1];
  264. n[1] = u[2]*v[0] - u[0]*v[2];
  265. n[2] = u[0]*v[1] - u[1]*v[0];
  266. d = 1.0 / sqrt(n[0]*n[0] + n[1]*n[1] + n[2]*n[2]);
  267. n[0] *= d;
  268. n[1] *= d;
  269. n[2] *= d;
  270. glBegin(GL_POLYGON);
  271. glNormal3fv(n);
  272. glVertex3fv(p0);
  273. glVertex3fv(p1);
  274. glVertex3fv(p2);
  275. glVertex3fv(vertexes[polygons[i][3]]);
  276. glVertex3fv(vertexes[polygons[i][4]]);
  277. glEnd();
  278.     }
  279. }
  280. void
  281. drawSphere(void)
  282. {
  283.     int numMajor = 24;
  284.     int numMinor = 32;
  285.     float radius = 0.8;
  286.     double majorStep = (M_PI / numMajor);
  287.     double minorStep = (2.0*M_PI / numMinor);
  288.     int i, j;
  289.     glColor3f(0.50, 0.50, 0.50);
  290.     for (i=0; i<numMajor; ++i) {
  291. double a = i * majorStep;
  292. double b = a + majorStep;
  293. double r0 = radius * sin(a);
  294. double r1 = radius * sin(b);
  295. GLfloat z0 = radius * cos(a);
  296. GLfloat z1 = radius * cos(b);
  297. glBegin(GL_TRIANGLE_STRIP);
  298. for (j=0; j<=numMinor; ++j) {
  299.     double c = j * minorStep;
  300.     GLfloat x = cos(c);
  301.     GLfloat y = sin(c);
  302.     glNormal3f((x*r0)/radius, (y*r0)/radius, z0/radius);
  303.     glTexCoord2f(j/(GLfloat) numMinor, i/(GLfloat) numMajor);
  304.     glVertex3f(x*r0, y*r0, z0);
  305.     glNormal3f((x*r1)/radius, (y*r1)/radius, z1/radius);
  306.     glTexCoord2f(j/(GLfloat) numMinor, (i+1)/(GLfloat) numMajor);
  307.     glVertex3f(x*r1, y*r1, z1);
  308. }
  309. glEnd();
  310.     }
  311. }
  312. /*****************************************************************/
  313. float xmin = -0.035, xmax = 0.035;
  314. float ymin = -0.035, ymax = 0.035;
  315. float znear = 0.1;
  316. float zfar = 1.9;
  317. float distance = -1.0;
  318. static void
  319. loadTextureProjection(GLfloat m[16])
  320. {
  321.     GLfloat mInverse[4][4];
  322.     /*
  323.     ** Should use true inverse, but since m consists only
  324.     ** of rotations, we can just use the transpose.
  325.     */
  326.     matrixTranspose((GLfloat *) mInverse, m);
  327.     glMatrixMode(GL_TEXTURE);
  328.     glLoadIdentity();
  329.     glTranslatef(0.5, 0.5, 0.0);
  330.     glScalef(0.5, 0.5, 1.0);
  331.     glFrustum(xmin, xmax, ymin, ymax, znear, zfar);
  332.     glTranslatef(0.0, 0.0, distance);
  333.     glMultMatrixf((GLfloat *) mInverse);
  334.     glMatrixMode(GL_MODELVIEW);
  335. }
  336. static void
  337. drawTextureProjection(void)
  338. {
  339.     float t = zfar / znear;
  340.     GLfloat n[4][3];
  341.     GLfloat f[4][3];
  342.     n[0][0] = xmin;
  343.     n[0][1] = ymin;
  344.     n[0][2] = -(znear + distance);
  345.     n[1][0] = xmax;
  346.     n[1][1] = ymin;
  347.     n[1][2] = -(znear + distance);
  348.     n[2][0] = xmax;
  349.     n[2][1] = ymax;
  350.     n[2][2] = -(znear + distance);
  351.     n[3][0] = xmin;
  352.     n[3][1] = ymax;
  353.     n[3][2] = -(znear + distance);
  354.     f[0][0] = xmin * t;
  355.     f[0][1] = ymin * t;
  356.     f[0][2] = -(zfar + distance);
  357.     f[1][0] = xmax * t;
  358.     f[1][1] = ymin * t;
  359.     f[1][2] = -(zfar + distance);
  360.     f[2][0] = xmax * t;
  361.     f[2][1] = ymax * t;
  362.     f[2][2] = -(zfar + distance);
  363.     f[3][0] = xmin * t;
  364.     f[3][1] = ymax * t;
  365.     f[3][2] = -(zfar + distance);
  366.     glColor3f(1.0, 1.0, 0.0);
  367.     glBegin(GL_LINE_LOOP);
  368.       glVertex3fv(n[0]);
  369.       glVertex3fv(n[1]);
  370.       glVertex3fv(n[2]);
  371.       glVertex3fv(n[3]);
  372.       glVertex3fv(f[3]);
  373.       glVertex3fv(f[2]);
  374.       glVertex3fv(f[1]);
  375.       glVertex3fv(f[0]);
  376.       glVertex3fv(n[0]);
  377.       glVertex3fv(n[1]);
  378.       glVertex3fv(f[1]);
  379.       glVertex3fv(f[0]);
  380.       glVertex3fv(f[3]);
  381.       glVertex3fv(f[2]);
  382.       glVertex3fv(n[2]);
  383.       glVertex3fv(n[3]);
  384.     glEnd();
  385. }
  386. /*****************************************************************/
  387. void
  388. initialize(void)
  389. {
  390.     GLfloat light0Pos[4] = { 0.3, 0.3, 0.0, 1.0 };
  391.     GLfloat matAmb[4] = { 0.01, 0.01, 0.01, 1.00 };
  392.     GLfloat matDiff[4] = { 0.65, 0.65, 0.65, 1.00 };
  393.     GLfloat matSpec[4] = { 0.30, 0.30, 0.30, 1.00 };
  394.     GLfloat matShine = 10.0;
  395.     GLfloat eyePlaneS[] = { 1.0, 0.0, 0.0, 0.0 };
  396.     GLfloat eyePlaneT[] = { 0.0, 1.0, 0.0, 0.0 };
  397.     GLfloat eyePlaneR[] = { 0.0, 0.0, 1.0, 0.0 };
  398.     GLfloat eyePlaneQ[] = { 0.0, 0.0, 0.0, 1.0 };
  399.     /*
  400.     ** Setup Misc.
  401.     */
  402.     glClearColor(0.41, 0.41, 0.31, 0.0);
  403.     glEnable(GL_DEPTH_TEST);
  404.     glLineWidth(2.0);
  405.     glCullFace(GL_FRONT);
  406.     glEnable(GL_CULL_FACE);
  407.     glMatrixMode(GL_PROJECTION);
  408.     glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3);
  409.     glMatrixMode(GL_MODELVIEW);
  410.     glTranslatef(0, 0, -2);
  411.     matrixIdentity((GLfloat *) objectXform);
  412.     matrixIdentity((GLfloat *) textureXform);
  413.     glMatrixMode(GL_PROJECTION);
  414.     glPushMatrix();
  415.     glLoadIdentity();
  416.     glOrtho(0, 1, 0, 1, -1, 1);
  417.     glMatrixMode(GL_MODELVIEW);
  418.     glPushMatrix();
  419.     glLoadIdentity();
  420.     glRasterPos2i(0, 0);
  421.     glPopMatrix();
  422.     glMatrixMode(GL_PROJECTION);
  423.     glPopMatrix();
  424.     glMatrixMode(GL_MODELVIEW);
  425.     /*
  426.     ** Setup Lighting
  427.     */
  428.     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb);
  429.     glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
  430.     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec);
  431.     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine);
  432.     glEnable(GL_COLOR_MATERIAL);
  433.     glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
  434.     glEnable(GL_LIGHT0);
  435.     glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
  436.     glEnable(GL_LIGHTING);
  437.     /*
  438.     ** Setup Texture
  439.     */
  440.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  441.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  442.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  443.     (*loadTexture)();
  444.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  445.     glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
  446.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  447.     glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
  448.     glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  449.     glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
  450.     glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  451.     glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
  452. }
  453. void
  454. display(void)
  455. {
  456.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  457.     if (textureEnabled) {
  458. if (mode == MoveTexture || mode == MoveView) {
  459.     /* Have OpenGL compute the new transformation (simple but slow). */
  460.     glPushMatrix();
  461.     glLoadIdentity();
  462.     glRotatef(angle, axis[0], axis[1], axis[2]);
  463.     glMultMatrixf((GLfloat *) textureXform);
  464.     glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform);
  465.     glPopMatrix();
  466. }
  467. loadTextureProjection((GLfloat *) textureXform);
  468. if (showProjection) {
  469.     glPushMatrix();
  470.     glMultMatrixf((GLfloat *) textureXform);
  471.     glDisable(GL_LIGHTING);
  472.     drawTextureProjection();
  473.     glEnable(GL_LIGHTING);
  474.     glPopMatrix();
  475. }
  476. glEnable(GL_TEXTURE_2D);
  477. glEnable(GL_TEXTURE_GEN_S);
  478. glEnable(GL_TEXTURE_GEN_T);
  479. glEnable(GL_TEXTURE_GEN_R);
  480. glEnable(GL_TEXTURE_GEN_Q);
  481.     }
  482.     if (mode == MoveObject || mode == MoveView) {
  483. /* Have OpenGL compute the new transformation (simple but slow). */
  484. glPushMatrix();
  485. glLoadIdentity();
  486. glRotatef(angle, axis[0], axis[1], axis[2]);
  487. glMultMatrixf((GLfloat *) objectXform);
  488. glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform);
  489. glPopMatrix();
  490.     }
  491.     glPushMatrix();
  492.     glMultMatrixf((GLfloat *) objectXform);
  493.     (*drawObject)();
  494.     glPopMatrix();
  495.     glDisable(GL_TEXTURE_2D);
  496.     glDisable(GL_TEXTURE_GEN_S);
  497.     glDisable(GL_TEXTURE_GEN_T);
  498.     glDisable(GL_TEXTURE_GEN_R);
  499.     glDisable(GL_TEXTURE_GEN_Q);
  500.     if (zoomFactor > 1.0) {
  501. glDisable(GL_DEPTH_TEST);
  502. glCopyPixels(0, 0, winWidth/zoomFactor, winHeight/zoomFactor, GL_COLOR);
  503. glEnable(GL_DEPTH_TEST);
  504.     }
  505.     glFlush();
  506.     glutSwapBuffers();
  507.     checkErrors();
  508. }
  509. /*****************************************************************/
  510. /* simple trackball-like motion control */
  511. GLboolean trackingMotion = GL_FALSE;
  512. float lastPos[3];
  513. int lastTime;
  514. void
  515. ptov(int x, int y, int width, int height, float v[3])
  516. {
  517.     float d, a;
  518.     /* project x,y onto a hemi-sphere centered within width, height */
  519.     v[0] = (2.0*x - width) / width;
  520.     v[1] = (height - 2.0*y) / height;
  521.     d = sqrt(v[0]*v[0] + v[1]*v[1]);
  522.     v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0));
  523.     a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
  524.     v[0] *= a;
  525.     v[1] *= a;
  526.     v[2] *= a;
  527. }
  528. void
  529. startMotion(int x, int y, int but, int time)
  530. {
  531.     if (but == GLUT_LEFT_BUTTON) {
  532. mode = MoveView;
  533.     } else if (but == GLUT_RIGHT_BUTTON) {
  534. mode = MoveTexture;
  535.     } else {
  536. return;
  537.     }
  538.     trackingMotion = GL_TRUE;
  539.     redrawContinuously = GL_FALSE;
  540.     lastTime = time;
  541.     ptov(x, y, winWidth, winHeight, lastPos);
  542. }
  543. /*ARGSUSED*/
  544. void
  545. stopMotion(int x, int y, int but, int time)
  546. {
  547.     if ((but == GLUT_LEFT_BUTTON && mode == MoveView) ||
  548. (but == GLUT_RIGHT_BUTTON && mode == MoveTexture))
  549.     {
  550. trackingMotion = GL_FALSE;
  551.     } else {
  552. return;
  553.     }
  554.     if (time == lastTime) {
  555. redrawContinuously = GL_TRUE;
  556. glutIdleFunc(display);
  557.     } else {
  558. angle = 0.0;
  559. redrawContinuously = GL_FALSE;
  560. glutIdleFunc(0);
  561.     }
  562.     if (!redrawContinuously) {
  563. mode = MoveNone;
  564.     }
  565. }
  566. void
  567. trackMotion(int x, int y)
  568. {
  569.     if (trackingMotion) {
  570. float curPos[3], dx, dy, dz;
  571. ptov(x, y, winWidth, winHeight, curPos);
  572. dx = curPos[0] - lastPos[0];
  573. dy = curPos[1] - lastPos[1];
  574. dz = curPos[2] - lastPos[2];
  575. angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
  576. axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
  577. axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
  578. axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
  579. lastTime = glutGet(GLUT_ELAPSED_TIME);
  580. lastPos[0] = curPos[0];
  581. lastPos[1] = curPos[1];
  582. lastPos[2] = curPos[2];
  583. glutPostRedisplay();
  584.     }
  585. }
  586. /*****************************************************************/
  587. void
  588. object(void)
  589. {
  590.     static int object;
  591.     object++; object %= 3;
  592.     switch (object) {
  593.       case 0:
  594. drawObject = drawCube;
  595. break;
  596.       case 1:
  597. drawObject = drawDodecahedron;
  598. break;
  599.       case 2:
  600. drawObject = drawSphere;
  601. break;
  602.       default:
  603. break;
  604.     }
  605. }
  606. void
  607. texture(void)
  608. {
  609.     static int texture;
  610.     texture++; texture %= 3;
  611.     switch (texture) {
  612.       case 0:
  613. loadTexture = NULL;
  614. textureEnabled = GL_FALSE;
  615. break;
  616.       case 1:
  617. loadTexture = loadImageTexture;
  618. (*loadTexture)();
  619. textureEnabled = GL_TRUE;
  620. break;
  621.       case 2:
  622. loadTexture = loadSpotlightTexture;
  623. (*loadTexture)();
  624. textureEnabled = GL_TRUE;
  625. break;
  626.       default:
  627. break;
  628.     }
  629. }
  630. void help(void) {
  631.     printf("'h'   - helpn");
  632.     printf("'l'   - toggle linear/nearest filtern");
  633.     printf("'s'   - toggle projection frustumn");
  634.     printf("'t'   - toggle projected texturen");
  635.     printf("'o'   - toggle objectn");
  636.     printf("'z'   - increase zoom factorn");
  637.     printf("'Z'   - decrease zoom factorn");
  638.     printf("left mouse    - move viewn");
  639.     printf("right mouse   - move projectionn");
  640. }
  641. /*ARGSUSED1*/
  642. void
  643. key(unsigned char key, int x, int y) {
  644.     switch(key) {
  645.     case '33':
  646. exit(EXIT_SUCCESS);
  647. break;
  648.     case 'l':
  649. linearFilter = !linearFilter;
  650. (*loadTexture)();
  651. break;
  652.     case 's':
  653. showProjection = !showProjection;
  654. break;
  655.     case 't':
  656. texture();
  657. break;
  658.     case 'o':
  659. object();
  660. break;
  661.     case 'z':
  662. zoomFactor += 1.0;
  663. glPixelZoom(zoomFactor, zoomFactor);
  664. glViewport(0, 0, winWidth/zoomFactor, winHeight/zoomFactor);
  665. break;
  666.     case 'Z':
  667. zoomFactor -= 1.0;
  668. if (zoomFactor < 1.0) zoomFactor = 1.0;
  669. glPixelZoom(zoomFactor, zoomFactor);
  670. glViewport(0, 0, winWidth/zoomFactor, winHeight/zoomFactor);
  671. break;
  672.     case 'h': help(); break;
  673.     }
  674.     glutPostRedisplay();
  675. }
  676. void
  677. mouse(int button, int state, int x, int y) {
  678.     if(state == GLUT_DOWN)
  679. startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
  680.     else if (state == GLUT_UP)
  681. stopMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
  682.     glutPostRedisplay();
  683. }
  684. void
  685. reshape(int w, int h)
  686. {
  687.     winWidth = w;
  688.     winHeight = h;
  689.     glViewport(0, 0, w/zoomFactor, h/zoomFactor);
  690. }
  691. void
  692. usage(char **argv)
  693. {
  694.     fprintf(stderr, "usage: %s <image-filename>n", argv[0]);
  695.     fprintf(stderr, "n");
  696. }
  697. int
  698. main(int argc, char **argv)
  699. {
  700.     glutInitWindowSize(512, 512);
  701.     glutInit(&argc, argv);
  702.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  703.     (void)glutCreateWindow("projtex");
  704.     if (argc > 1) {
  705. texFilename = argv[argc-1];
  706.     } else {
  707. texFilename = "../data/fendi.rgb";
  708.     }
  709.     loadTexture = loadImageTexture;
  710.     drawObject = drawCube;
  711.     initialize();
  712.     glutDisplayFunc(display);
  713.     glutKeyboardFunc(key);
  714.     glutReshapeFunc(reshape);
  715.     glutMouseFunc(mouse);
  716.     glutMotionFunc(trackMotion);
  717.     glutMainLoop();
  718.     return 0;
  719. }