home *** CD-ROM | disk | FTP | other *** search
/ IRIX Patches 1995 June / SGI IRIX Patches 1995 Jun.iso / 5.3_patches / patchSG0000154 / patchSG0000154.idb / usr / share / src / OpenGL / samples / select.c.z / select.c
Encoding:
C/C++ Source or Header  |  1995-06-12  |  7.4 KB  |  415 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <string.h>
  5. #include <time.h>
  6. #include "tk.h"
  7.  
  8.  
  9. #define MAXOBJS 10000
  10. #define MAXSELECT 100
  11. #define MAXFEED 300
  12. #define    SOLID 1
  13. #define    LINE 2
  14. #define    POINT 3
  15.  
  16.  
  17. GLenum directRender;
  18. GLint windW, windH;
  19.  
  20. GLuint selectBuf[MAXSELECT];
  21. GLfloat feedBuf[MAXFEED];
  22. GLint vp[4];
  23. float zRotation = 90.0;
  24. float zoom = 1.0;
  25. GLint objectCount;
  26. GLint numObjects;
  27. struct object {
  28.     float v1[2];
  29.     float v2[2];
  30.     float v3[2];
  31.     float color[3];
  32. } objects[MAXOBJS];
  33. GLenum linePoly = GL_FALSE;
  34.  
  35.  
  36. static void InitObjects(GLint num)
  37. {
  38.     GLint i;
  39.     float x, y;
  40.  
  41.     if (num > MAXOBJS) {
  42.     num = MAXOBJS;
  43.     }
  44.     if (num < 1) {
  45.     num = 1;
  46.     }
  47.     objectCount = num;
  48.  
  49.     srand((unsigned int)time(NULL));
  50.     for (i = 0; i < num; i++) {
  51.     x = (rand() % 300) - 150;
  52.     y = (rand() % 300) - 150;
  53.  
  54.     objects[i].v1[0] = x + (rand() % 50) - 25;
  55.     objects[i].v2[0] = x + (rand() % 50) - 25;
  56.     objects[i].v3[0] = x + (rand() % 50) - 25;
  57.     objects[i].v1[1] = y + (rand() % 50) - 25;
  58.     objects[i].v2[1] = y + (rand() % 50) - 25;
  59.     objects[i].v3[1] = y + (rand() % 50) - 25;
  60.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  61.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  62.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  63.     }
  64. }
  65.  
  66. static void Init(void)
  67. {
  68.  
  69.     numObjects = 10;
  70.     InitObjects(numObjects);
  71.     glGetIntegerv(GL_VIEWPORT, vp);
  72. }
  73.  
  74. static void Reshape(int width, int height)
  75. {
  76.  
  77.     windW = (GLint)width;
  78.     windH = (GLint)height;
  79. }
  80.  
  81. static void Render(GLenum mode)
  82. {
  83.     GLint i;
  84.  
  85.     for (i = 0; i < objectCount; i++) {
  86.     if (mode == GL_SELECT) {
  87.         glLoadName(i);
  88.     }
  89.     glColor3fv(objects[i].color);
  90.     glBegin(GL_POLYGON);
  91.         glVertex2fv(objects[i].v1);
  92.         glVertex2fv(objects[i].v2);
  93.         glVertex2fv(objects[i].v3);
  94.     glEnd();
  95.     }
  96. }
  97.  
  98. static GLint DoSelect(GLint x, GLint y)
  99. {
  100.     GLint hits;
  101.  
  102.     glSelectBuffer(MAXSELECT, selectBuf);
  103.     (void)glRenderMode(GL_SELECT);
  104.     glInitNames();
  105.     glPushName(~0);
  106.  
  107.     glPushMatrix();
  108.  
  109.     glViewport(0, 0, windW, windH);
  110.     glGetIntegerv(GL_VIEWPORT, vp);
  111.  
  112.     glMatrixMode(GL_PROJECTION);
  113.     glLoadIdentity();
  114.     gluPickMatrix(x, windH-y, 4, 4, vp);
  115.     gluOrtho2D(-175, 175, -175, 175);
  116.     glMatrixMode(GL_MODELVIEW);
  117.  
  118.     glClearColor(0.0, 0.0, 0.0, 0.0);
  119.     glClear(GL_COLOR_BUFFER_BIT);
  120.  
  121.     glScalef(zoom, zoom, zoom);
  122.     glRotatef(zRotation, 0, 0, 1);
  123.  
  124.     Render(GL_SELECT);
  125.  
  126.     glPopMatrix();
  127.     
  128.     hits = glRenderMode(GL_RENDER); 
  129.     if (hits <= 0) {
  130.     return -1;
  131.     }
  132.  
  133.     return selectBuf[(hits-1)*4+3];
  134. }
  135.  
  136. static void RecolorTri(GLint h)
  137. {
  138.  
  139.     objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  140.     objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  141.     objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  142. }
  143.  
  144. static void DeleteTri(GLint h)
  145. {
  146.  
  147.     objects[h] = objects[objectCount-1];
  148.     objectCount--;
  149. }
  150.  
  151. static void GrowTri(GLint h)
  152. {
  153.     float v[2];
  154.     float *oldV;
  155.     GLint i;
  156.  
  157.     v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  158.     v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  159.     v[0] /= 3;
  160.     v[1] /= 3;
  161.  
  162.     for (i = 0; i < 3; i++) {
  163.     switch (i) {
  164.       case 0:
  165.         oldV = objects[h].v1;
  166.         break;
  167.       case 1:
  168.         oldV = objects[h].v2;
  169.         break;
  170.       case 2:
  171.         oldV = objects[h].v3;
  172.         break;
  173.     }
  174.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  175.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  176.     }
  177. }
  178.  
  179. static GLenum Mouse(int mouseX, int mouseY, GLenum button)
  180. {
  181.     GLint hit;
  182.  
  183.     hit = DoSelect((GLint)mouseX, (GLint)mouseY);
  184.     if (hit != -1) {
  185.     if (button & TK_LEFTBUTTON) {
  186.         RecolorTri(hit);
  187.     }
  188.     if (button & TK_MIDDLEBUTTON) {
  189.         GrowTri(hit);
  190.     }
  191.     if (button & TK_RIGHTBUTTON) {
  192.         DeleteTri(hit);
  193.     }
  194.     return GL_TRUE;
  195.     }
  196.     return GL_FALSE;
  197. }
  198.  
  199. static void Draw(void)
  200. {
  201.  
  202.     glPushMatrix();
  203.  
  204.     glViewport(0, 0, windW, windH);
  205.     glGetIntegerv(GL_VIEWPORT, vp);
  206.  
  207.     glMatrixMode(GL_PROJECTION);
  208.     glLoadIdentity();
  209.     gluOrtho2D(-175, 175, -175, 175);
  210.     glMatrixMode(GL_MODELVIEW);
  211.  
  212.     glClearColor(0.0, 0.0, 0.0, 0.0);
  213.     glClear(GL_COLOR_BUFFER_BIT);
  214.  
  215.     glScalef(zoom, zoom, zoom);
  216.     glRotatef(zRotation, 0, 0, 1);
  217.  
  218.     Render(GL_RENDER);
  219.  
  220.     glPopMatrix();
  221.  
  222.     glFlush();
  223. }
  224.  
  225. static void DumpFeedbackVert(GLint *i, GLint n)
  226. {
  227.     GLint index;
  228.  
  229.     index = *i;
  230.     if (index+7 > n) {
  231.     *i = n;
  232.     printf("  ???\n");
  233.     return;
  234.     }
  235.     printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  236.        feedBuf[index],
  237.        feedBuf[index+1],
  238.        feedBuf[index+2],
  239.        feedBuf[index+3],
  240.        feedBuf[index+4],
  241.        feedBuf[index+5]);
  242.     index += 7;
  243.     *i = index;
  244. }
  245.  
  246. static void DrawFeedback(GLint n)
  247. {
  248.     GLint i;
  249.     GLint verts;
  250.  
  251.     printf("Feedback results (%d floats):\n", n);
  252.     for (i = 0; i < n; i++) {
  253.     switch ((GLint)feedBuf[i]) {
  254.       case GL_POLYGON_TOKEN:
  255.         printf("Polygon");
  256.         i++;
  257.         if (i < n) {
  258.         verts = (GLint)feedBuf[i];
  259.         i++;
  260.         printf(": %d vertices", verts);
  261.         } else {
  262.         verts = 0;
  263.         }
  264.         printf("\n");
  265.         while (verts) {
  266.         DumpFeedbackVert(&i, n);
  267.         verts--;
  268.         }
  269.         i--;
  270.         break;
  271.       case GL_LINE_TOKEN:
  272.         printf("Line:\n");
  273.         i++;
  274.         DumpFeedbackVert(&i, n);
  275.         DumpFeedbackVert(&i, n);
  276.         i--;
  277.         break;
  278.       case GL_LINE_RESET_TOKEN:
  279.         printf("Line Reset:\n");
  280.         i++;
  281.         DumpFeedbackVert(&i, n);
  282.         DumpFeedbackVert(&i, n);
  283.         i--;
  284.         break;
  285.       default:
  286.         printf("%9.2f\n", feedBuf[i]);
  287.         break;
  288.     }
  289.     }
  290.     if (i == MAXFEED) {
  291.     printf("...\n");
  292.     }
  293.     printf("\n");
  294. }
  295.  
  296. static void DoFeedback(void) 
  297. {
  298.     GLint x;
  299.  
  300.     glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  301.     (void)glRenderMode(GL_FEEDBACK);
  302.  
  303.     glPushMatrix();
  304.  
  305.     glViewport(0, 0, windW, windH);
  306.     glGetIntegerv(GL_VIEWPORT, vp);
  307.  
  308.     glMatrixMode(GL_PROJECTION);
  309.     glLoadIdentity();
  310.     gluOrtho2D(-175, 175, -175, 175);
  311.     glMatrixMode(GL_MODELVIEW);
  312.  
  313.     glClearColor(0.0, 0.0, 0.0, 0.0);
  314.     glClear(GL_COLOR_BUFFER_BIT);
  315.  
  316.     glScalef(zoom, zoom, zoom);
  317.     glRotatef(zRotation, 0, 0, 1);
  318.  
  319.     Render(GL_FEEDBACK);
  320.  
  321.     glPopMatrix();
  322.     
  323.     x = glRenderMode(GL_RENDER); 
  324.     if (x == -1) {
  325.     x = MAXFEED;
  326.     }
  327.  
  328.     DrawFeedback((GLint)x);
  329. }
  330.  
  331. static GLenum Key(int key, GLenum mask)
  332. {
  333.     int mouseX, mouseY;
  334.  
  335.     switch (key) {
  336.       case TK_ESCAPE:
  337.     tkQuit();
  338.       case TK_LEFT:
  339.     zRotation += 0.5;
  340.     break;
  341.       case TK_RIGHT:
  342.     zRotation -= 0.5;
  343.     break;
  344.       case TK_Z:
  345.     zoom /= 0.75;
  346.     break;
  347.       case TK_z:
  348.     zoom *= 0.75;
  349.     break;
  350.       case TK_f:
  351.     DoFeedback();
  352.     break;
  353.       case TK_l:
  354.     linePoly = !linePoly;
  355.     if (linePoly) {
  356.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  357.     } else {
  358.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  359.     }
  360.     break;
  361.       default:
  362.     return GL_FALSE;
  363.     }
  364.     return GL_TRUE;
  365. }
  366.  
  367. static GLenum Args(int argc, char **argv)
  368. {
  369.     GLint i;
  370.  
  371.     directRender = GL_TRUE;
  372.  
  373.     for (i = 1; i < argc; i++) {
  374.     if (strcmp(argv[i], "-dr") == 0) {
  375.         directRender = GL_TRUE;
  376.     } else if (strcmp(argv[i], "-ir") == 0) {
  377.         directRender = GL_FALSE;
  378.     } else {
  379.         printf("%s (Bad option).\n", argv[i]);
  380.         return GL_FALSE;
  381.     }
  382.     }
  383.     return GL_TRUE;
  384. }
  385.  
  386. void main(int argc, char **argv)
  387. {
  388.     GLenum type;
  389.  
  390.     if (Args(argc, argv) == GL_FALSE) {
  391.     tkQuit();
  392.     }
  393.  
  394.     windW = 300;
  395.     windH = 300;
  396.     tkInitPosition(0, 0, windW, windH);
  397.  
  398.     type = TK_RGB | TK_SINGLE;
  399.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  400.     tkInitDisplayMode(type);
  401.  
  402.     if (tkInitWindow("Select Test") == GL_FALSE) {
  403.     tkQuit();
  404.     }
  405.  
  406.     Init();
  407.  
  408.     tkExposeFunc(Reshape);
  409.     tkReshapeFunc(Reshape);
  410.     tkKeyDownFunc(Key);
  411.     tkMouseDownFunc(Mouse);
  412.     tkDisplayFunc(Draw);
  413.     tkExec();
  414. }
  415.