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

GIS编程

开发平台:

Visual C++

  1. #include <GL/glut.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <math.h>
  6. #include "texture.h"
  7. /* Some <math.h> files do not define M_PI... */
  8. #ifndef M_PI
  9. #define M_PI 3.14159265358979323846
  10. #endif
  11. #ifndef __sgi
  12. /* Most math.h's do not define float versions of the math functions. */
  13. #define sqrtf(x) (float)sqrt((x))
  14. #define cosf(x) (float)cos((x))
  15. #define sinf(x) (float)sin((x))
  16. #endif
  17. #ifdef GL_EXT_blend_subtract
  18. #if defined(_WIN32) && !defined(MESA)
  19. #include <windows.h>
  20. PFNGLBLENDEQUATIONEXTPROC glBlendEquationEXT = NULL;
  21. #endif
  22. static int hasBlendSubtract = 0;
  23. #else
  24. static const int hasBlendSubtract = 0;
  25. #endif
  26. int winWidth = 512;
  27. int winHeight = 512;
  28. #ifndef FALSE
  29. enum {FALSE, TRUE};
  30. #endif
  31. enum {S, T}; /* make array indexing more intuitive */
  32. enum {X, Y, Z, W};
  33. enum {R, G, B, A};
  34. enum {DEFAULT_TEX, ACCUM_TEX, ADD_TEX, SUB_TEX}; /* texture names */
  35. enum {LIGHT_XY, LIGHT_Z, PGON}; /* what should move */
  36. int dblbuf = TRUE;
  37. int accum = FALSE;
  38. int color = FALSE;
  39. int wire = FALSE;
  40. int textureOnly = FALSE;
  41. int lightOnly = FALSE;
  42. int bindtex = FALSE;
  43. int embossed = FALSE;
  44. int steps_xz = 20, steps_y = 20;
  45. int texture_width;
  46. int texture_height;
  47. /* is bumpmap shifting on? */
  48. int bumpEnabled = FALSE;
  49. int move = LIGHT_XY;
  50. /* current tangent vector */
  51. GLfloat curTangent[3];
  52. /* current texture coordinate */
  53. GLfloat curTex[2];
  54. /* current normal */
  55. GLfloat curNormal[3];
  56. /* current light position */
  57. GLfloat curLight[3];
  58. GLfloat lightpos[4] = {100.f, 100.f, 100.f, 1.f};
  59. GLfloat angles[2]; /* x and y angle */
  60. unsigned *bumptex; /* pointer to bumpmap texture */
  61. GLfloat bumpscale = .39f; /* scale down bumpmap texture (a smidgen under .4) */
  62. /* TEST PROGRAM */
  63. #if !defined(GL_VERSION_1_1) && !defined(GL_VERSION_1_2)
  64. #define glBindTexture glBindTextureEXT
  65. #endif
  66. #define CHECK_ERROR(str)                                           
  67. {                                                                  
  68.     GLenum error;                                                  
  69.     if(error = glGetError())                                       
  70.        printf("GL Error: %s (%s)n", gluErrorString(error), str);  
  71. }
  72. void
  73. bumpEnable(void)
  74. {
  75.     bumpEnabled = TRUE;
  76. }
  77. void
  78. bumpDisable(void)
  79. {
  80.     bumpEnabled = FALSE;
  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. mouse(int button, int state, int x, int y)
  91. {
  92.     if(state == GLUT_DOWN)
  93. switch(button)
  94. {
  95. case GLUT_LEFT_BUTTON: /* move the light */
  96.     move = LIGHT_XY;
  97.     lightpos[X] = (x - winWidth/2) * 300.f/winWidth;
  98.     lightpos[Y] = (winHeight/2 - y) * 300.f/winHeight;
  99.     glutPostRedisplay();
  100.     break;
  101. case GLUT_MIDDLE_BUTTON:
  102.     move = PGON;
  103.     angles[X] = (x - winWidth/2) * 180.f/winWidth;
  104.     angles[Y] = (y - winHeight/2) * 180.f/winHeight;
  105.     glutPostRedisplay();
  106.     break;
  107. case GLUT_RIGHT_BUTTON: /* move the polygon */
  108.     move = LIGHT_Z;
  109.     lightpos[Z] = (winHeight/2 - y) * 300.f/winWidth;
  110.     glutPostRedisplay();
  111.     break;
  112. }
  113. }
  114. void
  115. motion(int x, int y)
  116. {
  117.     switch(move)
  118.     {
  119.     case LIGHT_XY:
  120. lightpos[X] = (x - winWidth/2) * 300.f/winWidth;
  121. lightpos[Y] = (winHeight/2 - y) * 300.f/winHeight;
  122. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  123. glutPostRedisplay();
  124. break;
  125.     case LIGHT_Z:
  126. lightpos[Z] = (winHeight/2 - y) * 300.f/winWidth;
  127. glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  128. glutPostRedisplay();
  129. break;
  130.     case PGON:
  131. angles[X] = (x - winWidth/2) * 180.f/winWidth;
  132. angles[Y] = (y - winHeight/2) * 180.f/winHeight;
  133. glutPostRedisplay();
  134. break;
  135.     }
  136. }
  137. /*
  138. ** Create a single component texture map
  139. */
  140. GLfloat *make_texture(int maxs, int maxt)
  141. {
  142.     int s, t;
  143.     GLfloat *texture;
  144.     /* assumed format; LUMINANCE */
  145.     texture = (GLfloat *)malloc(maxs * maxt * sizeof(GLfloat));
  146.     for(t = 0; t < maxt; t++) {
  147. for(s = 0; s < maxs; s++) {
  148.     texture[s + maxs * t] = ((s >> 3) & 0x1) ^ ((t >> 3) & 0x1);
  149. }
  150.     }
  151.     return texture;
  152. }
  153. /* get current light position in object space */
  154. void
  155. bumpLightPos(GLfloat *x, GLfloat *y, GLfloat *z)
  156. {
  157.     GLdouble mvmatrix[16];
  158.     GLint viewport[4];
  159.     static GLdouble projmatrix[16]; /* to make them zero */
  160.     GLfloat light[4];
  161.     GLdouble Ex, Ey, Ez;
  162.     GLdouble Ox, Oy, Oz;
  163.     CHECK_ERROR("bumpLightPos");
  164.     glGetLightfv(GL_LIGHT0, GL_POSITION, light);
  165.     Ex = light[X]; Ey = light[Y]; Ez = (light[Z] + 1)/2.;
  166.     CHECK_ERROR("bumpLightPos");
  167.     glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
  168.     
  169.     /* identity projection matrix */
  170.     projmatrix[0] = projmatrix[5] = projmatrix[10] = projmatrix[15] = 1.;
  171.     /* identity viewport */
  172.     viewport[0] = viewport[1] = -1; 
  173.     viewport[2] = viewport[3] =  2;
  174.     /*
  175.     ** use the inverse of the modelview matrix to
  176.     ** transform light from eye to object space
  177.     */
  178.     gluUnProject(Ex, Ey, Ez, mvmatrix, projmatrix, viewport, &Ox, &Oy, &Oz);
  179.     *x = Ox; *y = Oy; *z = Oz;
  180.     CHECK_ERROR("bumpLightPos");
  181. }
  182. /* compute binormal from current normal and tangent vector, using cross prod */
  183. /* assuming normal and tangent are already normalized */
  184. void
  185. biNormal(GLfloat *x, GLfloat *y, GLfloat *z)
  186. {
  187.     /* normal <cross> tangent = binormal */
  188.     *x = curNormal[Y] * curTangent[Z] - curNormal[Z] * curTangent[Y];
  189.     *y = curNormal[Z] * curTangent[X] - curNormal[X] * curTangent[Z];
  190.     *z = curNormal[X] * curTangent[Y] - curNormal[Y] * curTangent[X];
  191. }
  192. void
  193. Normalize2f(GLfloat *x, GLfloat *y)
  194. {
  195.     GLfloat len;
  196.     len = *x * *x + *y * *y;
  197.     len = sqrtf(len);
  198.     *x /= len;
  199.     *y /= len;
  200. }
  201. /* rotate point by supplied rotatation matrix */
  202. void
  203. Rotate(GLfloat *rot, GLfloat *light, GLfloat *s, GLfloat *t)
  204. {
  205.     GLfloat r;
  206.     r = rot[3] * light[X] + rot[4] * light[Y] + rot[5] * light[Z];
  207.     if(r < 0.f) /* light below surface */
  208.     {
  209. *s = 0.f;
  210. *t = 0.f;
  211. return;
  212.     }
  213.     *s = rot[0] * light[X] + rot[1] * light[Y] + rot[2] * light[Z];
  214.     *t = rot[6] * light[X] + rot[7] * light[Y] + rot[8] * light[Z];
  215.     Normalize2f(s, t);
  216. }
  217. /* find out where the current normal is */
  218. void
  219. bumpNormal3f(GLfloat x, GLfloat y, GLfloat z)
  220. {
  221.     curNormal[X] = x;
  222.     curNormal[Y] = y;
  223.     curNormal[Z] = z;
  224.     glNormal3f(x, y, z);
  225. }
  226. void
  227. bumpTangent3f(GLfloat x, GLfloat y, GLfloat z)
  228. {
  229.     curTangent[X] = x;
  230.     curTangent[Y] = y;
  231.     curTangent[Z] = z;
  232. }
  233. /* save the texture coordinate call; will shift to do bumpmapping */
  234. void
  235. bumpTexCoord2f(GLfloat s, GLfloat t)
  236. {
  237.     curTex[S] = s;
  238.     curTex[T] = t;
  239. }
  240. /*
  241. ** use current tangent vector to compute texture coordinate shift
  242. ** then apply it by passing through vertex call
  243. */
  244. void
  245. bumpVertex3f(GLfloat x, GLfloat y, GLfloat z)
  246. {
  247.     GLfloat Light[3]; /* light in tangent space */
  248.     GLfloat length;
  249.     GLfloat s, t; /* tranformed light, used to shift */
  250.     GLfloat rot[9]; /* rotation matrix (just enought for x and y */
  251.     GLfloat Bx, By, Bz; /* binormal axis */
  252.     if(bumpEnabled)
  253.     {
  254. /* get current light position */
  255. Light[X] = curLight[X];
  256. Light[Y] = curLight[Y];
  257. Light[Z] = curLight[Z];
  258. /* find light vector from vertex */
  259. Light[X] -= x; Light[Y] -= y; Light[Z] -= z;
  260. length = 1.f/ sqrtf(Light[X] * Light[X] + 
  261.     Light[Y] * Light[Y] +
  262.     Light[Z] * Light[Z]);
  263. Light[X] *= length; Light[Y] *= length; Light[Z] *= length;
  264. /* create rotation matrix (rotate into tangent space) */
  265.     
  266. biNormal(&Bx, &By, &Bz); /* find binormal axis */
  267. rot[0] = curTangent[X]; rot[1] = curTangent[Y]; rot[2] = curTangent[Z];
  268. rot[3] = curNormal[X]; rot[4] = curNormal[Y]; rot[5] = curNormal[Z];
  269. rot[6] = Bx; rot[7] = By; rot[8] = Bz;
  270. Rotate(rot, Light, &s, &t);
  271. /* shift coordinates in opposite direction of desired texture shift */
  272. glTexCoord2f(curTex[S] - s/texture_width, curTex[T] - t/texture_height);
  273.     }
  274.     else
  275. glTexCoord2f(curTex[S], curTex[T]);
  276.     glVertex3f(x, y, z); /* pass on the vertex call */
  277. }
  278. void
  279. bumpBegin(GLenum prim)
  280. {
  281.     if(bumpEnabled)
  282.     {
  283. /* get light position; map back from eye to object space */
  284. bumpLightPos(&curLight[X], &curLight[Y], &curLight[Z]);
  285.     }
  286.     glBegin(prim);
  287. }
  288. void draw(void)
  289. {
  290.     int i, j;
  291.     GLfloat Vx, Vy, Vz; /* vertex */
  292.     GLfloat Tx, Ty, Tz; /* tangent */
  293.     GLfloat Nx, Ny, Nz; /* normal */
  294.     GLfloat c, s; /* cos, sin */
  295.     CHECK_ERROR("start of draw()");
  296.     Ny = 0.f;
  297.     Ty = 0.f;
  298.     /* v(i, j) v(i+1, j), v(i+1, j+1), v(i, j+1) */
  299.     bumpBegin(GL_QUADS);
  300.     for(j = 0; j < steps_y; j ++)
  301. for(i = 0; i < steps_xz; i++) /* 180 -> 0 degrees */
  302. {
  303.     /* v(i, j) */
  304.     c = cosf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1)));
  305.     s = sinf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1)));
  306.     Vx = 100 * c;
  307.     Vy = j * 200.f/steps_y - 100.f;
  308.     Vz = 100 * s - 100.f;
  309.     Nx = c;
  310.     Nz = s;
  311.     Tx = s;
  312.     Ty = -c;
  313. Tz = 0;
  314.     bumpNormal3f(Nx, Ny, Nz);
  315.     bumpTangent3f(Tx, Ty, Tz);
  316.     bumpTexCoord2f(i/(GLfloat)steps_xz, j/(GLfloat)steps_y);
  317.     bumpVertex3f(Vx, Vy, Vz);
  318.     /* v(i+1, j) */
  319.     c = cosf(M_PI * (1.f - (GLfloat)(i + 1)/(steps_xz - 1)));
  320.     s = sinf(M_PI * (1.f - (GLfloat)(i + 1)/(steps_xz - 1)));
  321.     Vx = 100 * c;
  322.     Vz = 100 * s - 100.f;
  323.     Nx = c;
  324.     Nz = s;
  325.     Tx = s;
  326.     Ty = -c;
  327.     bumpNormal3f(Nx, Ny, Nz);
  328.     bumpTangent3f(Tx, Ty, Tz);
  329.     bumpTexCoord2f((i + 1)/(GLfloat)steps_xz, j/(GLfloat)steps_y);
  330.     bumpVertex3f(Vx, Vy, Vz);
  331.     /* v(i+1, j+1) */
  332.     Vy = (j + 1) * 200.f/steps_y - 100.f;
  333.     bumpNormal3f(Nx, Ny, Nz);
  334.     bumpTangent3f(Tx, Ty, Tz);
  335.     bumpTexCoord2f((i + 1)/(GLfloat)steps_xz, (j + 1)/(GLfloat)steps_y);
  336.     bumpVertex3f(Vx, Vy, Vz);
  337.     /* v(i, j+1) */
  338.     c = cosf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1)));
  339.     s = sinf(M_PI * (1.f - (GLfloat)i/(steps_xz - 1)));
  340.     Vx = 100 * c;
  341.     Vz = 100 * s - 100.f;
  342.     Nx = c;
  343.     Nz = s;
  344.     Tx = s;
  345.     Ty = -c;
  346.     bumpNormal3f(Nx, Ny, Nz);
  347.     bumpTangent3f(Tx, Ty, Tz);
  348.     bumpTexCoord2f(i/(GLfloat)steps_xz, (j + 1)/(GLfloat)steps_y);
  349.     bumpVertex3f(Vx, Vy, Vz);
  350. }
  351.     glEnd();
  352.     CHECK_ERROR("end of draw()");
  353. }
  354. /* Called when window needs to be redrawn */
  355. void redraw_blendext(void)
  356. {
  357.     GLUquadricObj *obj;
  358.     void draw(void);
  359.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  360.     glLoadIdentity();
  361.     gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.);
  362.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  363.     glPushMatrix();
  364.     glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]);
  365.     obj = gluNewQuadric();
  366.     gluSphere(obj, 7., 10, 10);
  367.     gluDeleteQuadric(obj);
  368.     glPopMatrix();
  369.     glRotatef(angles[X], 0.f, 1.f, 0.f);
  370.     glRotatef(angles[Y], 1.f, 0.f, 0.f);
  371.     if(textureOnly)
  372.     {
  373. glEnable(GL_TEXTURE_2D);
  374. draw();
  375. glDisable(GL_TEXTURE_2D);
  376.     }
  377.     else if(lightOnly)
  378.     {
  379. /* draw "z" diffuse component */
  380. glEnable(GL_LIGHTING);
  381. glEnable(GL_LIGHT0);
  382. draw();
  383. glDisable(GL_LIGHTING);
  384.     }
  385.     else /* bumpmapping */
  386.     {
  387. /* find N dot L */
  388. /* draw "z" diffuse component */
  389. /* also do ambient here */
  390. if(!embossed)
  391. {
  392.     glEnable(GL_LIGHTING);
  393.     glEnable(GL_LIGHT0);
  394.     draw();
  395.     glDisable(GL_LIGHTING);
  396. }
  397. /* add in shifted values */
  398. glEnable(GL_TEXTURE_2D);
  399. glEnable(GL_BLEND);
  400. glBlendFunc(GL_ONE, GL_ONE);
  401. bumpEnable(); /* shift texture coords */
  402. draw();
  403. bumpDisable();
  404. #ifdef GL_EXT_blend_subtract
  405.         if (hasBlendSubtract) {
  406.        /* subtract unshifted */
  407.     glBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT);
  408.     draw();
  409.     glBlendEquationEXT(GL_FUNC_ADD_EXT);
  410. }
  411. #endif
  412. glDisable(GL_BLEND);
  413. glDisable(GL_TEXTURE_2D);
  414. if(color)
  415. {
  416.     /* Modulate the color texture with N dot L */
  417.     glEnable(GL_TEXTURE_2D);
  418.     glEnable(GL_BLEND);
  419.     glBlendFunc(GL_DST_COLOR, GL_ZERO);
  420.     glBindTexture(GL_TEXTURE_2D, 1); /* use color texture */
  421.     draw();
  422.     glBindTexture(GL_TEXTURE_2D, 0);
  423.     glDisable(GL_BLEND);
  424.     glDisable(GL_TEXTURE_2D);
  425. }
  426.     }
  427.     /* scale up the image */
  428.     glPixelTransferf(GL_RED_SCALE, 2.f);
  429.     glPixelTransferf(GL_GREEN_SCALE, 2.f);
  430.     glPixelTransferf(GL_BLUE_SCALE, 2.f);
  431.     glCopyPixels(0, 0, winWidth, winHeight, GL_COLOR);
  432.     CHECK_ERROR("OpenGL Error in redraw()");
  433.     if(dblbuf)
  434. glutSwapBuffers(); 
  435.     else
  436. glFlush(); 
  437. }
  438. /* Called when window needs to be redrawn */
  439. void redraw_accum(void)
  440. {
  441.     GLUquadricObj *obj;
  442.     void draw(void);
  443.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  444.     glLoadIdentity();
  445.     gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.);
  446.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  447.     glRotatef(angles[X], 0.f, 1.f, 0.f);
  448.     glRotatef(angles[Y], 1.f, 0.f, 0.f);
  449.     if(textureOnly)
  450.     {
  451. glEnable(GL_TEXTURE_2D);
  452. draw();
  453. glDisable(GL_TEXTURE_2D);
  454.     }
  455.     else if(lightOnly)
  456.     {
  457. /* draw "z" diffuse component */
  458. glEnable(GL_LIGHTING);
  459. glEnable(GL_LIGHT0);
  460. draw();
  461. glDisable(GL_LIGHTING);
  462.     }
  463.     else /* bumpmapping */
  464.     {
  465. CHECK_ERROR("start");
  466. /* draw "z" diffuse component */
  467. glEnable(GL_LIGHTING);
  468. glEnable(GL_LIGHT0);
  469. draw();
  470. glAccum(GL_LOAD, .5f);
  471. CHECK_ERROR("load");
  472. glDisable(GL_LIGHTING);
  473. /* draw shifted */
  474. glEnable(GL_TEXTURE_2D);
  475. bumpEnable();
  476. draw();
  477. glAccum(GL_ACCUM, .5f);
  478. bumpDisable();
  479. /* subtract unshifted */
  480. draw();
  481. glAccum(GL_ACCUM, -.5f);
  482. glDisable(GL_TEXTURE_2D);
  483. glAccum(GL_RETURN, 2.f);
  484. if(color)
  485. {
  486.     /* Modulate the color texture with N dot L */
  487.     glEnable(GL_TEXTURE_2D);
  488.     glEnable(GL_BLEND);
  489.     glBlendFunc(GL_DST_COLOR, GL_ZERO);
  490.     glBindTexture(GL_TEXTURE_2D, 1); /* use color texture */
  491.     draw();
  492.     glBindTexture(GL_TEXTURE_2D, 0);
  493.     glDisable(GL_BLEND);
  494.     glDisable(GL_TEXTURE_2D);
  495. }
  496.     }
  497.     
  498.     CHECK_ERROR("OpenGL Error in redraw()");
  499.     glPushMatrix();
  500.     glLoadIdentity();
  501.     gluLookAt(0., 0., 650., 0., 0., 0., 0., 1., 0.);
  502.     glTranslatef(lightpos[X], lightpos[Y], lightpos[Z]);
  503.     obj = gluNewQuadric();
  504.     gluSphere(obj, 7., 10, 10);
  505.     gluDeleteQuadric(obj);
  506.     glPopMatrix();
  507.     if(dblbuf)
  508. glutSwapBuffers(); 
  509.     else
  510. glFlush(); 
  511. }
  512. /* ARGSUSED1 */
  513. void key(unsigned char key, int x, int y)
  514. {
  515.     switch(key)
  516.     {
  517.     case 't':
  518. if(textureOnly)
  519.     textureOnly = FALSE;
  520. else
  521.     textureOnly = TRUE;
  522. glutPostRedisplay();
  523. break;
  524.     case 'l':
  525. if(lightOnly)
  526.     lightOnly = FALSE;
  527. else
  528.     lightOnly = TRUE;
  529. glutPostRedisplay();
  530. break;
  531.     case 'e':
  532. if(embossed)
  533.     embossed = FALSE;
  534. else
  535.     embossed = TRUE;
  536. glutPostRedisplay();
  537. break;
  538.     case 'B': /* make bumps taller */
  539. bumpscale += .01f;
  540. printf("bump map scale = %.2fn", bumpscale);
  541. glPixelTransferf(GL_RED_SCALE, bumpscale);
  542. glPixelTransferf(GL_GREEN_SCALE, bumpscale);
  543. glPixelTransferf(GL_BLUE_SCALE, bumpscale);
  544. glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
  545.      texture_width, texture_height, 0, GL_RGBA,
  546.      GL_UNSIGNED_BYTE, bumptex);
  547. glutPostRedisplay();
  548. break;
  549.     case 'b': /* make bumps flatter */
  550. bumpscale -= .01f;
  551. if(bumpscale < 0.f)
  552.     bumpscale = 0.f;
  553. printf("bump map scale = %.2fn", bumpscale);
  554. glPixelTransferf(GL_RED_SCALE, bumpscale);
  555. glPixelTransferf(GL_GREEN_SCALE, bumpscale);
  556. glPixelTransferf(GL_BLUE_SCALE, bumpscale);
  557. glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
  558.      texture_width, texture_height, 0, GL_RGBA,
  559.      GL_UNSIGNED_BYTE, bumptex);
  560. glutPostRedisplay();
  561. break;
  562.     case 'c':
  563. if(color == TRUE)
  564.     color = FALSE;
  565. else
  566.     color = TRUE;
  567. glutPostRedisplay();
  568. break;
  569.     case 'w':
  570. if(wire == TRUE)
  571. {
  572.     glPolygonMode(GL_FRONT, GL_FILL);
  573.     wire = FALSE;
  574. }
  575. else
  576. {
  577.     glPolygonMode(GL_FRONT, GL_LINE);
  578.     wire = TRUE;
  579. }
  580. glutPostRedisplay();
  581. break;
  582.     case 'x':
  583. steps_xz -= 2;
  584. if(steps_xz < 1)
  585.     steps_xz = 1;
  586. glutPostRedisplay();
  587. break;
  588.     case 'X':
  589. steps_xz += 2;
  590. glutPostRedisplay();
  591. break;
  592.     case 'y':
  593. steps_y -= 2;
  594. if(steps_y < 1)
  595.     steps_y = 1;
  596. glutPostRedisplay();
  597. break;
  598.     case 'Y':
  599. steps_y += 2;
  600. glutPostRedisplay();
  601. break;
  602.     case '33':
  603. exit(0);
  604. break;
  605.     case 'h':
  606.     case '?':
  607.     default:
  608. fprintf(stderr, 
  609. "Keyboard commands:n"
  610. "t-texture onlyn"
  611. "l-light onlyn"
  612. "c-color texturen"
  613. "e-embossed (horizontal part)n"
  614. "w-toggle wireframen"
  615. "B-increase bumps b-decrease bumpsn");
  616. break;
  617.     }
  618. }
  619. main(int argc, char *argv[])
  620. {
  621.     unsigned *tex;
  622.     GLfloat lightpos[4];
  623.     GLfloat diffuse[4];
  624.     GLboolean valid;
  625.     int texcomps, texwid, texht;
  626.     const char *version;
  627.     char varray[32];
  628.     glutInit(&argc, argv);
  629.     glutInitWindowSize(winWidth, winHeight);
  630.     if(argc > 1)
  631.     {
  632. char *args = argv[1];
  633. int done = FALSE;
  634. while(!done)
  635. {
  636.     switch(*args)
  637.     {
  638.     case 's': /* single buffer */
  639. printf("Single Bufferedn");
  640. dblbuf = FALSE;
  641. break;
  642.     case 'a': /* use accumulation buffer */
  643. printf("Use accumulation buffern");
  644. accum = TRUE;
  645. break;
  646.     case '-': /* do nothing */
  647. break;
  648.     case 0:
  649. done = TRUE;
  650. break;
  651.     }
  652.     args++;
  653. }
  654.     }
  655.     if(dblbuf)
  656. if(accum)
  657.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH|GLUT_ACCUM);
  658.         else
  659.     glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
  660.     else
  661. if(accum)
  662.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH|GLUT_ACCUM);
  663.         else
  664.     glutInitDisplayMode(GLUT_RGBA|GLUT_DEPTH);
  665.     (void)glutCreateWindow("bump mapping example program");
  666.     if(accum)
  667. glutDisplayFunc(redraw_accum);
  668.     else
  669. glutDisplayFunc(redraw_blendext);
  670.     glutKeyboardFunc(key);
  671.     glutMouseFunc(mouse);
  672.     glutMotionFunc(motion);
  673.     glutReshapeFunc(reshape);
  674.     
  675.     version = (char *) glGetString(GL_VERSION);
  676.     strncpy(varray, version, strcspn(version, " "));
  677.     printf("%sn", version);
  678.     if(atof(varray) > 1.f)
  679. bindtex = TRUE;
  680.     else
  681. bindtex = FALSE;
  682.     glRasterPos3i(-1, -1, -1);
  683.     glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
  684.     if(!valid)
  685. printf("invalid raster position!n");
  686.     /* draw a perspective scene */
  687.     glMatrixMode(GL_PROJECTION);
  688.     glFrustum(-150., 150., -150., 150., 500., 800.);
  689.     glMatrixMode(GL_MODELVIEW);
  690.     /* turn on features */
  691.     glEnable(GL_DEPTH_TEST);
  692.     glDepthFunc(GL_LEQUAL);
  693.     /* remove back faces to speed things up */
  694.     glCullFace(GL_BACK);
  695.     diffuse[R] = diffuse[G] = diffuse[B] = .4f;
  696.     diffuse[A] = 1.f;
  697.     glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
  698.     bumptex = read_texture("../data/opengl.bw", &texture_width, 
  699.        &texture_height, &texcomps);
  700.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  701.     if(!accum)
  702.     {
  703. /* scale to match maximum z (default Kd = .8, default Ld = 1. */
  704. /* divide by 2 to stay in range of 0 to 1 */
  705. glPixelTransferf(GL_RED_SCALE, bumpscale);
  706. glPixelTransferf(GL_GREEN_SCALE, bumpscale);
  707. glPixelTransferf(GL_BLUE_SCALE, bumpscale);
  708.     }
  709.     glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
  710.  texture_width, texture_height, 0, GL_RGBA,
  711.  GL_UNSIGNED_BYTE, bumptex);
  712.     tex = read_texture("../data/plank.rgb", &texwid, &texht, &texcomps);
  713.     glBindTexture(GL_TEXTURE_2D, 1); /* for color */
  714.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  715.     glPixelTransferf(GL_RED_SCALE, 1.f);
  716.     glPixelTransferf(GL_GREEN_SCALE, 1.f);
  717.     glPixelTransferf(GL_BLUE_SCALE, 1.f);
  718.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
  719.  texwid, texht, 0, GL_RGBA,
  720.  GL_UNSIGNED_BYTE, tex);
  721.     glBindTexture(GL_TEXTURE_2D, 0);
  722.     free(tex);
  723.     lightpos[X] = lightpos[Y] = 0.f;
  724.     lightpos[Z] = -90.f;
  725.     lightpos[W] = 1.f;
  726.     glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
  727.     glDisable(GL_DITHER);
  728.     CHECK_ERROR("end of main");
  729. #ifdef GL_EXT_blend_subtract
  730.     if(!glutExtensionSupported("GL_EXT_blend_subtract")) {
  731.       fprintf(stderr,
  732.         "bump: requires OpenGL blend subtract extension to operate correctly.n");
  733.       hasBlendSubtract = 0;
  734.     } else {
  735.       hasBlendSubtract = 1;
  736. #if defined(_WIN32) && !defined(MESA)
  737.       glBlendEquationEXT = (PFNGLBLENDEQUATIONEXTPROC) wglGetProcAddress("glBlendEquationEXT");
  738.       if (glBlendEquationEXT == NULL) {
  739.         hasBlendSubtract = 0;
  740.       }
  741. #endif
  742.     }
  743. #endif
  744.     key('?', 0, 0); /* startup message */
  745.     glutMainLoop();
  746.     return(0);
  747. }