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

GIS编程

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <GL/glut.h>
  5. /* Some <math.h> files do not define M_PI... */
  6. #ifndef M_PI
  7. #define M_PI 3.14159265358979323846
  8. #endif
  9. #define TRUE 1
  10. #define FALSE 0
  11. int whichSurface = 0;
  12. int takeSnapshot = 0;
  13. int  winWidth, winHeight;
  14. GLfloat  *depthSave = NULL;
  15. GLubyte  *stencilSave = NULL;
  16. GLubyte  *colorSave = NULL;
  17. void resizeBuffers(void)
  18. {
  19.     colorSave = realloc(colorSave, winWidth * winHeight * 4 * sizeof(GLubyte));
  20.     depthSave = realloc(depthSave, winWidth * winHeight * 4 * sizeof(GLfloat));
  21.     stencilSave = (GLubyte *)depthSave;
  22. }
  23. void pushOrthoView(float left, float right, float bottom, float top,
  24.     float znear, float zfar)
  25. {
  26.     glPushMatrix();
  27.     glLoadIdentity();
  28.     glMatrixMode(GL_PROJECTION);
  29.     glPushMatrix();
  30.     glLoadIdentity();
  31.     glOrtho(left, right, bottom, top, znear, zfar);
  32. }
  33. void popView(void)
  34. {
  35.     glPopMatrix();
  36.     glMatrixMode(GL_MODELVIEW);
  37.     glPopMatrix();
  38. }
  39. void copyDepthToColor(GLenum whichColorBuffer)
  40. {
  41.     int x, y;
  42.     GLfloat max, min;
  43.     GLint previousColorBuffer;
  44.     glReadPixels(0, 0, winWidth, winHeight, GL_DEPTH_COMPONENT, GL_FLOAT,
  45.         depthSave);
  46.     /* I'm sure this could be done much better with OpenGL */
  47.     max = 0;
  48.     min = 1;
  49.     for(y = 0; y < winHeight; y++)
  50. for(x = 0; x < winWidth; x++) {
  51.     if(depthSave[winWidth * y + x] < min)
  52. min = depthSave[winWidth * y + x];
  53.     if(depthSave[winWidth * y + x] > max && depthSave[winWidth * y + x] < .999)
  54. max = depthSave[winWidth * y + x];
  55. }
  56.     for(y = 0; y < winHeight; y++)
  57. for(x = 0; x < winWidth; x++) {
  58.     if(depthSave[winWidth * y + x] <= max)
  59. depthSave[winWidth * y + x] = 1 -  (depthSave[winWidth * y + x] - min) / (max - min);
  60.     else
  61. depthSave[winWidth * y + x] = 0;
  62. }
  63.     pushOrthoView(0, 1, 0, 1, 0, 1);
  64.     glRasterPos3f(0, 0, -.5);
  65.     glDisable(GL_DEPTH_TEST);
  66.     glDisable(GL_STENCIL_TEST);
  67.     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  68.     glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer);
  69.     glDrawBuffer(whichColorBuffer);
  70.     glDrawPixels(winWidth, winHeight, GL_LUMINANCE , GL_FLOAT, depthSave);
  71.     glDrawBuffer(previousColorBuffer);
  72.     glEnable(GL_DEPTH_TEST);
  73.     popView();
  74. }
  75. unsigned char colors[][3] =
  76. {
  77.     {255, 0, 0}, /* red */
  78.     {255, 218, 0}, /* yellow */
  79.     {72, 255, 0}, /* yellowish green */
  80.     {0, 255, 145}, /* bluish cyan */
  81.     {0, 145, 255}, /* cyanish blue */
  82.     {72, 0, 255}, /* purplish blue */
  83.     {255, 0, 218}, /* reddish purple */
  84. };
  85. void copyStencilToColor(GLenum whichColorBuffer)
  86. {
  87.     int x, y;
  88.     GLint previousColorBuffer;
  89.     glReadPixels(0, 0, winWidth, winHeight, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
  90.         stencilSave);
  91.     /* I'm sure this could be done much better with OpenGL */
  92.     for(y = 0; y < winHeight; y++)
  93. for(x = 0; x < winWidth; x++) {
  94.     int stencilValue;
  95.     
  96.     stencilValue = stencilSave[winWidth * y + x];
  97.     colorSave[(winWidth * y + x) * 3 + 0] = colors[stencilValue % 7][0];
  98.     colorSave[(winWidth * y + x) * 3 + 1] = colors[stencilValue % 7][1];
  99.     colorSave[(winWidth * y + x) * 3 + 2] = colors[stencilValue % 7][2];
  100. }
  101.     pushOrthoView(0, 1, 0, 1, 0, 1);
  102.     glRasterPos3f(0, 0, -.5);
  103.     glDisable(GL_DEPTH_TEST);
  104.     glDisable(GL_STENCIL_TEST);
  105.     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  106.     glGetIntegerv(GL_DRAW_BUFFER, &previousColorBuffer);
  107.     glDrawBuffer(whichColorBuffer);
  108.     glDrawPixels(winWidth, winHeight, GL_RGB, GL_UNSIGNED_BYTE, colorSave);
  109.     glDrawBuffer(previousColorBuffer);
  110.     glEnable(GL_DEPTH_TEST);
  111.     popView();
  112. }
  113. #if 0
  114. GLushort rrow[1280], grow[1280], brow[1280], arow[1280];
  115. #define iopen junk
  116. #include <gl/image.h>
  117. #undef iopen
  118. IMAGE *iopen(char *file, char *mode, ...);
  119. int putrow(IMAGE *image, unsigned short *buff, int y, int z);
  120. int iclose(IMAGE *);
  121. void saveSGIImage(char *name, int doAlphaToo)
  122. {
  123.     IMAGE *img;
  124.     FILE *fp;
  125.     GLubyte *pixels; 
  126.     int x, y;
  127.     int numComp = doAlphaToo ? 4 : 3;
  128.     pixels = malloc(winWidth * winHeight * numComp * sizeof(GLubyte));
  129.     glReadPixels(0, 0, winWidth, winHeight, doAlphaToo ? GL_RGBA : GL_RGB,
  130.         GL_UNSIGNED_BYTE, pixels);
  131.     img = iopen(name, "w", RLE(1), numComp, winWidth, winHeight, numComp);
  132.     for(y = 0; y < winHeight; y++) {
  133.         for(x = 0; x < winWidth; x++) {
  134.     rrow[x] = pixels[(y * winWidth + x) * numComp + 0];
  135.     grow[x] = pixels[(y * winWidth + x) * numComp + 1];
  136.     brow[x] = pixels[(y * winWidth + x) * numComp + 2];
  137.     if(doAlphaToo)
  138. arow[x] = pixels[(y * winWidth + x) * numComp + 3];
  139. }
  140.         putrow(img, rrow, y, 0);
  141.         putrow(img, grow, y, 1);
  142.         putrow(img, brow, y, 2);
  143. if(doAlphaToo)
  144.     putrow(img, arow, y, 3);
  145.     }
  146.     iclose(img);
  147.     free(pixels);
  148. }
  149. #endif
  150. struct transformation {
  151.     float translation[3];
  152.     float rotation[4];
  153.     float scale[3];
  154. };
  155. void drawXform(struct transformation *xform, int applyScale)
  156. {
  157.     glTranslatef(xform->translation[0], xform->translation[1], xform->translation[2]);
  158.     glRotatef(xform->rotation[3] / M_PI * 180, xform->rotation[0], xform->rotation[1], xform->rotation[2]);
  159.     if(applyScale)
  160. glScalef(xform->scale[0], xform->scale[1], xform->scale[2]);
  161. }
  162. enum trackballModeEnum {
  163.     ROTATE,
  164.     TRANSLATEXY,
  165.     TRANSLATEZ,
  166.     SCALEX,
  167.     SCALEY,
  168.     SCALEZ
  169. } trackballMode = ROTATE;
  170. struct transformation xform = 
  171. {
  172.     0, 0, 0,
  173.     -0.65, -0.75, -0.04, 0.89,
  174.     .7, .7, 2,
  175. };
  176. void axisamountToMat(float aa[], float mat[])
  177. {
  178.     float c, s, t;
  179.     c = (float)cos(aa[3]);
  180.     s = (float)sin(aa[3]);
  181.     t = 1.0f - c;
  182.     mat[0] = t * aa[0] * aa[0] + c;
  183.     mat[1] = t * aa[0] * aa[1] + s * aa[2];
  184.     mat[2] = t * aa[0] * aa[2] - s * aa[1];
  185.     mat[3] = t * aa[0] * aa[1] - s * aa[2];
  186.     mat[4] = t * aa[1] * aa[1] + c;
  187.     mat[5] = t * aa[1] * aa[2] + s * aa[0];
  188.     mat[6] = t * aa[0] * aa[2] + s * aa[1];
  189.     mat[7] = t * aa[1] * aa[2] - s * aa[0];
  190.     mat[8] = t * aa[2] * aa[2] + c;
  191. }
  192. void matToAxisamount(float mat[], float aa[])
  193. {
  194.     float c;
  195.     float s;
  196.     c = (mat[0] + mat[4] + mat[8] - 1.0f) / 2.0f;
  197.     aa[3] = (float)acos(c);
  198.     s = (float)sin(aa[3]);
  199.     if(fabs(s / M_PI - (int)(s / M_PI)) < .0000001)
  200.     {
  201.         aa[0] = 0.0f;
  202.         aa[1] = 1.0f;
  203.         aa[2] = 0.0f;
  204.     }
  205.     else
  206.     {
  207. aa[0] = (mat[5] - mat[7]) / (2.0f * s);
  208. aa[1] = (mat[6] - mat[2]) / (2.0f * s);
  209. aa[2] = (mat[1] - mat[3]) / (2.0f * s);
  210.     }
  211. }
  212. void multMat(float m1[], float m2[], float r[])
  213. {
  214.     float t[9];
  215.     int i;
  216.     t[0] = m1[0] * m2[0] + m1[1] * m2[3] + m1[2] * m2[6];
  217.     t[1] = m1[0] * m2[1] + m1[1] * m2[4] + m1[2] * m2[7];
  218.     t[2] = m1[0] * m2[2] + m1[1] * m2[5] + m1[2] * m2[8];
  219.     t[3] = m1[3] * m2[0] + m1[4] * m2[3] + m1[5] * m2[6];
  220.     t[4] = m1[3] * m2[1] + m1[4] * m2[4] + m1[5] * m2[7];
  221.     t[5] = m1[3] * m2[2] + m1[4] * m2[5] + m1[5] * m2[8];
  222.     t[6] = m1[6] * m2[0] + m1[7] * m2[3] + m1[8] * m2[6];
  223.     t[7] = m1[6] * m2[1] + m1[7] * m2[4] + m1[8] * m2[7];
  224.     t[8] = m1[6] * m2[2] + m1[7] * m2[5] + m1[8] * m2[8];
  225.     for(i = 0; i < 9; i++)
  226.     {
  227.         r[i] = t[i];
  228.     }
  229. }
  230. void rotateTrackball(int dx, int dy, float rotation[4])
  231. {
  232.     float dist;
  233.     float oldMat[9];
  234.     float rotMat[9];
  235.     float newRot[4];
  236.     dist = (float)sqrt((double)(dx * dx + dy * dy));
  237.     if(fabs(dist) < 0.99)
  238.         return;
  239.     newRot[0] = (float) dy / dist;
  240.     newRot[1] = (float) dx / dist;
  241.     newRot[2] = 0.0f;
  242.     newRot[3] = (float)M_PI * dist / winWidth;
  243.     axisamountToMat(rotation, oldMat);
  244.     axisamountToMat(newRot, rotMat);
  245.     multMat(oldMat, rotMat, oldMat);
  246.     matToAxisamount(oldMat, rotation);
  247.     dist = (float)sqrt(rotation[0] * rotation[0] + rotation[1] * rotation[1] +
  248.         rotation[2] * rotation[2]);
  249.     rotation[0] /= dist;
  250.     rotation[1] /= dist;
  251.     rotation[2] /= dist;
  252. }
  253. int stage = 6;
  254. typedef enum {COLOR, DEPTH, STENCIL} BufferInterest;
  255. BufferInterest bufferInterest = COLOR;
  256. void init(void)
  257. {
  258.     GLfloat defaultMat[] = {.75, .25, .25, 1};
  259.     glEnable(GL_DEPTH_TEST);
  260.     glEnable(GL_CULL_FACE);
  261.     glCullFace(GL_BACK);
  262.     glMatrixMode(GL_PROJECTION);
  263.     glFrustum(-.33, .33, -.33, .33, .5, 40);
  264.     glMatrixMode(GL_MODELVIEW);
  265.     gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
  266.     glEnable(GL_LIGHTING);
  267.     glEnable(GL_LIGHT0);
  268.     /* glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); */
  269.     glEnable(GL_NORMALIZE);
  270.     glEnable(GL_STENCIL_TEST);
  271.     glStencilOp(GL_INCR, GL_INCR, GL_INCR);
  272.     glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, defaultMat);
  273.     glLineWidth(3);
  274.     glShadeModel(GL_FLAT);
  275. }
  276. void redraw(void)
  277. {
  278.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  279.     
  280.     glPushMatrix();
  281.     drawXform(&xform, TRUE);
  282.     glEnable(GL_STENCIL_TEST);
  283.     if(whichSurface < 2)
  284. glStencilFunc(GL_EQUAL, whichSurface, 0xff);
  285.     else
  286. glStencilFunc(GL_ALWAYS, 0, 0);
  287.     glutSolidTorus(2, 4, 20, 20);
  288.     /* glDisable(GL_STENCIL_TEST); */
  289.     /* glDisable(GL_LIGHTING); */
  290.     /* glColor3f(1, 1, 1); */
  291.     /* glutWireTorus(2, 4, 20, 20); */
  292.     /* glEnable(GL_LIGHTING); */
  293.     glPopMatrix();
  294.     switch(bufferInterest) {
  295.         case COLOR:
  296.     break; /* color already in back buffer */
  297. case STENCIL:
  298.     copyStencilToColor(GL_BACK);
  299.     break;
  300. case DEPTH:
  301.     copyDepthToColor(GL_BACK);
  302.     break;
  303.     }
  304.     if(takeSnapshot) {
  305.         takeSnapshot = 0;
  306. /* saveSGIImage("snap.rgb", FALSE); */
  307. /* printf("Saved RGBA image in snap.rgban"); */
  308.     }
  309.     glutSwapBuffers();
  310. }
  311. void reshape(int width, int height)
  312. {
  313.     glViewport(0, 0, width, height);
  314.     winWidth = width;
  315.     winHeight = height;
  316.     resizeBuffers();
  317.     glutPostRedisplay();
  318. }
  319. void changeData(int data)
  320. {
  321.     char *s;
  322.     bufferInterest = (BufferInterest) data;
  323.     glutPostRedisplay();
  324.     switch(data) {
  325.         case COLOR:
  326.     s = "color";
  327.     break;
  328.         case STENCIL:
  329.     s = "stencil";
  330.     break;
  331.         case DEPTH:
  332.     s = "depth";
  333.     break;
  334.     }
  335.     printf("Now displaying %s datan", s);
  336. }
  337. int mainMenu;
  338. /* ARGSUSED1 */
  339. void keyboard(unsigned char key, int x, int y)
  340. {
  341.     switch(key)
  342.     {
  343.         case '1':
  344.         case '2':
  345.         case '3':
  346.     whichSurface = key - '1';
  347.     glutPostRedisplay();
  348.     break;
  349.         case 'r':
  350.     trackballMode = ROTATE;
  351.     break;
  352. case 't':
  353.     trackballMode = TRANSLATEXY;
  354.     break;
  355. case 'T':
  356.     trackballMode = TRANSLATEZ;
  357.     break;
  358. case 'x':
  359.     trackballMode = SCALEX;
  360.     break;
  361. case 'y':
  362.     trackballMode = SCALEY;
  363.     break;
  364. case 'z':
  365.     trackballMode = SCALEZ;
  366.     break;
  367. case 'q': case 'Q': case '33':
  368.     exit(0);
  369.     break;
  370. case '+': case '=':
  371.     stage++;
  372.     glutPostRedisplay();
  373.     break;
  374. case '-': case '_':
  375.     stage--;
  376.     glutPostRedisplay();
  377.     break;
  378. case 's':
  379.     printf("%f %f %f %fn", xform.rotation[0], xform.rotation[1],
  380.         xform.rotation[2], xform.rotation[3]);
  381.     glutPostRedisplay();
  382.     break;
  383.     }
  384. }
  385. static int ox, oy;
  386. /* ARGSUSED */
  387. void button(int b, int state, int x, int y)
  388. {
  389.     ox = x;
  390.     oy = y;
  391. }
  392. void motion(int x, int y)
  393. {
  394.     int dx, dy;
  395.     dx = x - ox;
  396.     dy = y - oy;
  397.     ox = x;
  398.     oy = y;
  399.     switch(trackballMode) {
  400. case ROTATE:
  401.     rotateTrackball(dx, dy, xform.rotation);
  402.     break;
  403. case SCALEX:
  404.     xform.scale[0] += (dx + dy) / 20.0f;
  405.     break;
  406. case SCALEY:
  407.     xform.scale[1] += (dx + dy) / 20.0f;
  408.     break;
  409. case SCALEZ:
  410.     xform.scale[2] += (dx + dy) / 20.0f;
  411.     break;
  412. case TRANSLATEXY:
  413.     xform.translation[0] += dx / 20.0f;
  414.     xform.translation[1] -= dy / 20.0f;
  415.     break;
  416. case TRANSLATEZ:
  417.     xform.translation[2] += (dx + dy) / 20.0f;
  418.     break;
  419.     }
  420.     glutPostRedisplay();
  421. }
  422. /* ARGSUSED */
  423. void mainMenuFunc(int menu)
  424. {
  425.     /* */
  426. }
  427. int main(int argc, char **argv)
  428. {
  429.     int bufferMenu;
  430.     int stenSize;
  431.     glutInit(&argc, argv);
  432.     glutInitWindowSize(winWidth = 256, winHeight = 256);
  433.     glutInitDisplayMode(GLUT_DOUBLE|GLUT_STENCIL|GLUT_DEPTH|GLUT_ALPHA);
  434.     (void)glutCreateWindow("torus depth");
  435.     glutDisplayFunc(redraw);
  436.     glutKeyboardFunc(keyboard);
  437.     glutMotionFunc(motion);
  438.     glutMouseFunc(button);
  439.     glutReshapeFunc(reshape);
  440.     resizeBuffers();
  441.     glGetIntegerv(GL_STENCIL_BITS, &stenSize);
  442.     fprintf(stderr, "(%d bits of stencil available in this visual)n", stenSize);
  443.     fprintf(stderr, "Hit 'h' for help messagen");
  444.     bufferMenu = glutCreateMenu(changeData);
  445.     glutAddMenuEntry("Color data", COLOR);
  446.     glutAddMenuEntry("Stencil data", STENCIL);
  447.     glutAddMenuEntry("Depth data", DEPTH);
  448.     mainMenu = glutCreateMenu(mainMenuFunc);
  449.     glutAddSubMenu("Visible buffer", bufferMenu);
  450.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  451.     init();
  452.     glutMainLoop();
  453.     return 0;
  454. }