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

GIS编程

开发平台:

Visual C++

  1. #include <math.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <GL/glut.h>
  5. #include "texture.h"
  6. /* Some <math.h> files do not define M_PI... */
  7. #ifndef M_PI
  8. #define M_PI 3.14159265358979323846
  9. #endif
  10. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  11. #define glBindTexture glBindTextureEXT
  12. #endif
  13. #define CHECK_ERROR(str)                                           
  14. {                                                                  
  15.     GLenum error;                                                  
  16.     if(error = glGetError())                                       
  17.        printf("GL Error: %s (%s)n", gluErrorString(error), str);  
  18. }
  19. #ifndef FALSE
  20. enum {FALSE, TRUE};
  21. #endif
  22. enum {X, Y, Z, W};
  23. enum {OBJ_ANGLE, LIGHT_ANGLE, OBJ_TRANSLATE};
  24. enum {SURF_TEX, HIGHLIGHT_TEX};
  25. /* window dimensions */
  26. int winWidth = 512;
  27. int winHeight = 512;
  28. int active;
  29. int dblbuf = TRUE;
  30. int highlight = TRUE;
  31. int gouraud = FALSE;
  32. int texmap = FALSE;
  33. int notex = FALSE; /* don't texture gouraud */
  34. int object = 2;
  35. int maxobject = 2;
  36. GLfloat lightangle[2] = {0.f, 0.f};
  37. GLfloat objangle[2] = {0.f, 0.f};
  38. GLfloat objpos[2] = {0.f, 0.f};
  39. GLfloat color[4] = {1.f, 1.f, 1.f, 1.f};
  40. GLfloat zero[4] = {0.f, 0.f, 0.f, 1.f};
  41. GLfloat one[4] = {1.f, 1.f, 1.f, 1.f};
  42. int texdim = 128;
  43. GLfloat *lighttex = 0;
  44. GLfloat lightpos[4] = {0.f, 0.f, 1.f, 0.f};
  45. GLboolean lightchanged[2] = {GL_TRUE, GL_TRUE};
  46. enum {UPDATE_OGL, UPDATE_TEX};
  47. /* draw a highly tesselated sphere with a specular highlight */
  48. void
  49. makeHighlight(int shinyness)
  50. {
  51.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  52.     glPushMatrix(); /* starts as modelview */
  53.     glLoadIdentity();
  54.     glTranslatef(0.f, 0.f, -texdim/2.f);
  55.     glMatrixMode(GL_PROJECTION);
  56.     glPushMatrix();
  57.     glLoadIdentity();
  58.     glOrtho(-texdim/2., texdim/2., -texdim/2., texdim/2., 0., texdim/2.);
  59.     glPushAttrib(GL_LIGHTING_BIT|GL_VIEWPORT_BIT);
  60.     glViewport(0, 0, texdim, texdim);
  61.     glEnable(GL_LIGHTING);
  62.     glLightfv(GL_LIGHT0, GL_DIFFUSE, zero);
  63.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* light direction */
  64.     /* XXX TODO, range check an report errors */
  65.     glMateriali(GL_FRONT, GL_SHININESS, shinyness); /* cosine power */
  66.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); 
  67.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); 
  68.     glMaterialfv(GL_FRONT, GL_SPECULAR, color);
  69.     glDisable(GL_TEXTURE_2D);
  70.     glCallList(1);
  71.     glEnable(GL_TEXTURE_2D);
  72.     glPopAttrib();
  73.     glPopMatrix();
  74.     glMatrixMode(GL_MODELVIEW);
  75.     glPopMatrix();
  76.     glReadPixels(0, 0, texdim, texdim, GL_RGB, GL_FLOAT, lighttex);
  77.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  78.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  79.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texdim, texdim, 0, GL_RGB,
  80.  GL_FLOAT, lighttex);
  81. }
  82. void
  83. reshape(int wid, int ht)
  84. {
  85.     winWidth = wid;
  86.     winHeight = ht;
  87.     glViewport(0, 0, wid, ht);
  88. }
  89. void
  90. motion(int x, int y)
  91. {
  92.     switch(active)
  93.     {
  94.     case OBJ_ANGLE:
  95. objangle[X] = (x - winWidth/2) * 360./winWidth;
  96. objangle[Y] = (y - winHeight/2) * 360./winHeight;
  97. glutPostRedisplay();
  98. break;
  99.     case LIGHT_ANGLE:
  100. lightangle[X] = (x - winWidth/2) * 2 * M_PI/winWidth;
  101. lightangle[Y] = (winHeight/2 - y) * 2 * M_PI/winHeight;
  102. lightpos[Y] = sin(lightangle[Y]);
  103. lightpos[X] = cos(lightangle[Y]) * sin(lightangle[X]);
  104. lightpos[Z] = cos(lightangle[Y]) * cos(lightangle[X]);
  105. lightpos[W] = 0.;
  106. lightchanged[UPDATE_OGL] = GL_TRUE;
  107. lightchanged[UPDATE_TEX] = GL_TRUE;
  108. glutPostRedisplay();
  109. break;
  110.     case OBJ_TRANSLATE:
  111. objpos[X] = (x - winWidth/2) * 100./winWidth;
  112. objpos[Y] = (winHeight/2 - y) * 100./winHeight;
  113. glutPostRedisplay();
  114. break;
  115.     }
  116. }
  117. void
  118. mouse(int button, int state, int x, int y)
  119. {
  120.     if(state == GLUT_DOWN)
  121. switch(button)
  122. {
  123. case GLUT_LEFT_BUTTON: /* move the light */
  124.     active = OBJ_ANGLE;
  125.     motion(x, y);
  126.     break;
  127. case GLUT_MIDDLE_BUTTON:
  128.     active = LIGHT_ANGLE;
  129.     motion(x, y);
  130.     break;
  131. case GLUT_RIGHT_BUTTON: /* move the polygon */
  132.     active = OBJ_TRANSLATE;
  133.     motion(x, y);
  134.     break;
  135. }
  136. }
  137. /* draw the object unlit without surface texture */
  138. void redraw_white(void)
  139. {
  140.     glPushMatrix(); /* assuming modelview */
  141.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  142.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  143.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  144.     
  145.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  146.     
  147.     glDisable(GL_LIGHTING);
  148.     glDisable(GL_TEXTURE_2D);
  149.     /* draw the specular highlight */
  150.     
  151.     glCallList(object);
  152.     glEnable(GL_TEXTURE_2D);
  153.     glPopMatrix(); /* assuming modelview */
  154.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  155.     if(dblbuf)
  156. glutSwapBuffers(); 
  157.     else
  158. glFlush(); 
  159. }
  160. /* just draw textured highlight */
  161. void redraw_tex_highlight(void)
  162. {
  163.     if(lightchanged[UPDATE_TEX])
  164.     {
  165. makeHighlight(128);
  166. lightchanged[UPDATE_TEX] = GL_FALSE;
  167.     }
  168.     glPushMatrix(); /* assuming modelview */
  169.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  170.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  171.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  172.     
  173.     glClearColor(.1f, .1f, .1f, 1.f);
  174.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  175.     glClearColor(0.f, 0.f, 0.f, 1.f);
  176.     
  177.     /* draw the specular highlight */
  178.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  179.     glEnable(GL_TEXTURE_GEN_S);
  180.     glEnable(GL_TEXTURE_GEN_T);
  181.     
  182.     glCallList(object);
  183.     glDisable(GL_TEXTURE_GEN_S);
  184.     glDisable(GL_TEXTURE_GEN_T);
  185.     glPopMatrix(); /* assuming modelview */
  186.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  187.     if(dblbuf)
  188. glutSwapBuffers(); 
  189.     else
  190. glFlush(); 
  191. }
  192. /* just draw opengl highlight */
  193. void redraw_gouraud_highlight(void)
  194. {
  195.     if(lightchanged[UPDATE_OGL])
  196.     {
  197. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  198. lightchanged[UPDATE_OGL] = GL_FALSE;
  199.     }
  200.     glPushAttrib(GL_LIGHTING);
  201.     glPushMatrix(); /* assuming modelview */
  202.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  203.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  204.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  205.     
  206.     glClearColor(.1f, .1f, .1f, 1.f);
  207.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  208.     glClearColor(0.f, 0.f, 0.f, 1.f);
  209.     
  210.     /* draw the specular highlight */
  211.     glEnable(GL_LIGHTING);
  212.     glDisable(GL_TEXTURE_2D);
  213.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  214.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
  215.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
  216.     /* draw the specular highlight */
  217.     glCallList(object);
  218.     glEnable(GL_TEXTURE_2D);
  219.     glPopMatrix(); /* assuming modelview */
  220.     glPopAttrib();
  221.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  222.     if(dblbuf)
  223. glutSwapBuffers(); 
  224.     else
  225. glFlush(); 
  226. }
  227. /* show highlight texture map */
  228. void redraw_map(void)
  229. {
  230.     if(lightchanged[UPDATE_TEX])
  231.     {
  232. makeHighlight(128);
  233. lightchanged[UPDATE_TEX] = GL_FALSE;
  234.     }
  235.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  236.     glMatrixMode(GL_MODELVIEW);
  237.     glPushMatrix();
  238.     glLoadIdentity();
  239.     glMatrixMode(GL_PROJECTION);
  240.     glPushMatrix();
  241.     glLoadIdentity();
  242.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  243.     glDisable(GL_LIGHTING);
  244.     glBegin(GL_QUADS);
  245.     glTexCoord2i(0, 0);
  246.     glVertex2i(-1, -1);
  247.     glTexCoord2i(1, 0);
  248.     glVertex2i(1, -1);
  249.     glTexCoord2i(1, 1);
  250.     glVertex2i(1,  1);
  251.     glTexCoord2i(0, 1);
  252.     glVertex2i(-1,  1);
  253.     glEnd();
  254.     glEnable(GL_LIGHTING);
  255.     glPopMatrix();
  256.     glMatrixMode(GL_MODELVIEW);
  257.     glPopMatrix();
  258.     CHECK_ERROR("OpenGL Error in redraw_map()");
  259.     if(dblbuf)
  260. glutSwapBuffers(); 
  261.     else
  262. glFlush(); 
  263. }
  264. /* multipass, use texture to make highlight */
  265. void redraw_tex(void)
  266. {
  267.     if(lightchanged[UPDATE_TEX])
  268.     {
  269. makeHighlight(128);
  270. lightchanged[UPDATE_TEX] = GL_FALSE;
  271.     }
  272.     if(lightchanged[UPDATE_OGL])
  273.     {
  274. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  275. lightchanged[UPDATE_OGL] = GL_FALSE;
  276.     }
  277.     glPushMatrix(); /* assuming modelview */
  278.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  279.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  280.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  281.     
  282.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  283.     
  284.     /* draw the diffuse portion of the light */
  285.     glEnable(GL_LIGHTING);
  286.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  287.     if(notex)
  288. glDisable(GL_TEXTURE_2D);
  289.     glCallList(object);
  290.     if(notex)
  291. glEnable(GL_TEXTURE_2D);
  292.     glDisable(GL_LIGHTING);
  293.     /* draw the specular highlight */
  294.     glEnable(GL_BLEND);
  295.     glBindTexture(GL_TEXTURE_2D, HIGHLIGHT_TEX);
  296.     glEnable(GL_TEXTURE_GEN_S);
  297.     glEnable(GL_TEXTURE_GEN_T);
  298.     glDepthFunc(GL_LEQUAL);
  299.     
  300.     glCallList(object);
  301.     glDepthFunc(GL_LESS);
  302.     glDisable(GL_TEXTURE_GEN_S);
  303.     glDisable(GL_TEXTURE_GEN_T);
  304.     glDisable(GL_BLEND);
  305.     glPopMatrix(); /* assuming modelview */
  306.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  307.     if(dblbuf)
  308. glutSwapBuffers(); 
  309.     else
  310. glFlush(); 
  311. }
  312. /* multipass; use opengl to make highlight */
  313. void redraw_phong(void)
  314. {
  315.     if(lightchanged[UPDATE_OGL])
  316.     {
  317. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  318. lightchanged[UPDATE_OGL] = GL_FALSE;
  319.     }
  320.     glPushAttrib(GL_LIGHTING);
  321.     glPushMatrix(); /* assuming modelview */
  322.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  323.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  324.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  325.     
  326.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  327.     
  328.     /* draw the diffuse portion of the light */
  329.     glEnable(GL_LIGHTING);
  330.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  331.     if(notex)
  332. glDisable(GL_TEXTURE_2D);
  333.     glCallList(object);
  334.     if(notex)
  335. glEnable(GL_TEXTURE_2D);
  336.     /* turn off texturing so phong highlight color is pure */
  337.     glDisable(GL_TEXTURE_2D); 
  338.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  339.     glMaterialfv(GL_FRONT, GL_DIFFUSE, zero); /* turn off ogl diffuse */
  340.     glMaterialfv(GL_FRONT, GL_AMBIENT, zero); /* turn off ogl diffuse */
  341.     /* draw the specular highlight */
  342.     glEnable(GL_BLEND);
  343.     glDepthFunc(GL_LEQUAL);
  344.     
  345.     glCallList(object);
  346.     glEnable(GL_TEXTURE_2D); 
  347.     glDepthFunc(GL_LESS);
  348.     glDisable(GL_BLEND);
  349.     glPopMatrix(); /* assuming modelview */
  350.     glPopAttrib();
  351.     CHECK_ERROR("OpenGL Error in redraw_tex()");
  352.     if(dblbuf)
  353. glutSwapBuffers(); 
  354.     else
  355. glFlush(); 
  356. }
  357. /* Use OpenGL lighting to get highlight */
  358. void redraw_original(void)
  359. {
  360.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  361.     
  362.     glPushMatrix(); /* assuming modelview */
  363.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  364.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  365.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  366.     
  367.     if(lightchanged[UPDATE_OGL])
  368.     {
  369. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  370. lightchanged[UPDATE_OGL] = GL_FALSE;
  371.     }
  372.     glEnable(GL_LIGHTING);
  373.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  374.     glMaterialfv(GL_FRONT, GL_SPECULAR, color); /* turn on ogl highlights */
  375.     if(notex)
  376. glDisable(GL_TEXTURE_2D);
  377.     glCallList(object);
  378.     if(notex)
  379. glEnable(GL_TEXTURE_2D);
  380.     glMaterialfv(GL_FRONT, GL_SPECULAR, zero);
  381.     glDisable(GL_LIGHTING);
  382.     glPopMatrix(); /* assuming modelview */
  383.     CHECK_ERROR("OpenGL Error in redraw()");
  384.     if(dblbuf)
  385. glutSwapBuffers(); 
  386.     else
  387. glFlush(); 
  388. }
  389. /* Draw with no highlight */
  390. void redraw_diffuse(void)
  391. {
  392.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  393.     
  394.     glPushMatrix(); /* assuming modelview */
  395.     glTranslatef(objpos[X], objpos[Y], 0.f); /* translate object */
  396.     glRotatef(objangle[X], 0.f, 1.f, 0.f); /* rotate object */
  397.     glRotatef(objangle[Y], 1.f, 0.f, 0.f);
  398.     
  399.     if(lightchanged[UPDATE_OGL])
  400.     {
  401. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  402. lightchanged[UPDATE_OGL] = GL_FALSE;
  403.     }
  404.     /* draw the diffuse portion of the light */
  405.     glEnable(GL_LIGHTING);
  406.     glBindTexture(GL_TEXTURE_2D, SURF_TEX);
  407.     glCallList(object);
  408.     glDisable(GL_LIGHTING);
  409.     glPopMatrix(); /* assuming modelview */
  410.     CHECK_ERROR("OpenGL Error in redraw()");
  411.     if(dblbuf)
  412. glutSwapBuffers(); 
  413.     else
  414. glFlush(); 
  415. }
  416. /* ARGSUSED1 */
  417. void key(unsigned char key, int x, int y)
  418. {
  419.     switch(key)
  420.     {
  421.     case 'u': /* unmodified highlight */
  422. printf("Use unmodified gouraud highlightn");
  423. glutDisplayFunc(redraw_original);
  424. glutPostRedisplay();
  425. break;
  426.     case 'd':
  427. printf("Draw diffuse onlyn");
  428. glutDisplayFunc(redraw_diffuse);
  429. glutPostRedisplay();
  430. break;
  431.     case 'g': /* separate gouraud shaded highlight */
  432. printf("Use separate gouraud shaded highlightn");
  433. glutDisplayFunc(redraw_phong);
  434. glutPostRedisplay();
  435. break;
  436.     case 't': /* separate textured highlight */
  437. printf("Use separate texture highlightn");
  438. glutDisplayFunc(redraw_tex);
  439. glutPostRedisplay();
  440. break;
  441.     case 'o':
  442. /* toggle object type */
  443. object++;
  444. if(object > maxobject)
  445.     object = 2;
  446. glutPostRedisplay();
  447. break;
  448.     case 'm':
  449. /* show highlight texture map */
  450. printf("Show highlight texture mapn");
  451. glutDisplayFunc(redraw_map);
  452. glutPostRedisplay();
  453. break;
  454.     case 'n':
  455. if(notex)
  456.     notex = FALSE;
  457. else
  458.     notex = TRUE;
  459. glutPostRedisplay();
  460. break;
  461.     case 'h':
  462. printf("Show textured phong highlightn");
  463. glutDisplayFunc(redraw_tex_highlight);
  464. glutPostRedisplay();
  465. break;
  466.     case 'p':
  467. printf("Show gouraud-shaded phong highlightn");
  468. glutDisplayFunc(redraw_gouraud_highlight);
  469. glutPostRedisplay();
  470. break;
  471.     case 'w':
  472. printf("Show white objectn");
  473. glutDisplayFunc(redraw_white);
  474. glutPostRedisplay();
  475. break;
  476.     case '33':
  477. exit(0);
  478. break;
  479.     default:
  480. fprintf(stderr, "Keyboard commands:nn"
  481. "u - (unmodified opengl lighting)n"
  482. "d - diffuse onlyn"
  483. "g - multipass gouraud highlightn"
  484. "t - multipass texture highlightn"
  485. "o - toggle objectn"
  486. "m - show highlight texture mapn"
  487. "n - toggle surface texturingn"
  488. "h - show textured phong highlightn"
  489. "p - show gouraud-shaded phong highlightn"
  490. "w - show unlit white objectn");
  491. break;
  492.     }
  493. }
  494. main(int argc, char *argv[])
  495. {
  496.     GLuint *tex;
  497.     int texwid, texht, texcomps;
  498.     GLUquadricObj *quadric;
  499.     glutInitWindowSize(winWidth, winHeight);
  500.     glutInit(&argc, argv);
  501.     if(argc > 1)
  502.     {
  503. char *args = argv[1];
  504. int done = FALSE;
  505. while(!done)
  506. {
  507.     switch(*args)
  508.     {
  509.     case 's': /* single buffer */
  510. printf("Single Bufferedn");
  511. dblbuf = FALSE;
  512. break;
  513.     case '-': /* do nothing */
  514. break;
  515.     case 0:
  516. done = TRUE;
  517. break;
  518.     }
  519.     args++;
  520. }
  521.     }
  522.     if(dblbuf)
  523. glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_DOUBLE);
  524.     else
  525. glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH);
  526.     (void)glutCreateWindow("example program");
  527.     glutDisplayFunc(redraw_original);
  528.     glutReshapeFunc(reshape);
  529.     glutMouseFunc(mouse);
  530.     glutMotionFunc(motion);
  531.     glutKeyboardFunc(key);
  532.     /* draw a perspective scene */
  533.     glMatrixMode(GL_PROJECTION);
  534.     glFrustum(-100., 100., -100., 100., 300., 600.); 
  535.     glMatrixMode(GL_MODELVIEW);
  536.     /* look at scene from (0, 0, 450) */
  537.     gluLookAt(0., 0., 450., 0., 0., 0., 0., 1., 0.);
  538.     /* turn on features */
  539.     glEnable(GL_DEPTH_TEST);
  540.     glEnable(GL_TEXTURE_2D);
  541.     glEnable(GL_LIGHTING);
  542.     glEnable(GL_LIGHT0);
  543.     
  544.     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  545.     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  546.     glMateriali(GL_FRONT, GL_SHININESS, 128); /* cosine power */
  547.     /* remove back faces to speed things up */
  548.     glCullFace(GL_BACK);
  549.     glBlendFunc(GL_ONE, GL_ONE);
  550.     lightchanged[UPDATE_TEX] = GL_TRUE;
  551.     lightchanged[UPDATE_OGL] = GL_TRUE;
  552.     /* load pattern for current 2d texture */
  553.     tex = read_texture("../data/wood.rgb", &texwid, &texht, &texcomps);
  554.     gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, texwid, texht, GL_RGBA,
  555.       GL_UNSIGNED_BYTE, tex);
  556.     free(tex);
  557.     CHECK_ERROR("end of main");
  558.     lighttex = (GLfloat *)malloc(texdim * texdim * sizeof(GL_FLOAT) * 3);
  559.     /* XXX TODO use display list to avoid retesselating */
  560.     glNewList(1, GL_COMPILE);
  561.     glutSolidSphere((GLdouble)texdim/2., 50, 50);
  562.     glEndList();
  563.     glNewList(2, GL_COMPILE);
  564.     glutSolidTeapot(70.);
  565.     glEndList();
  566.     quadric = gluNewQuadric();
  567.     gluQuadricTexture(quadric, GL_TRUE);
  568.     glNewList(3, GL_COMPILE);
  569.     gluSphere(quadric, 70., 20, 20);
  570.     glEndList();
  571.     gluDeleteQuadric(quadric);
  572.     maxobject = 3;
  573.     glutMainLoop();
  574.     return 0;
  575. }