home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / newopg.zip / SELECT.C < prev    next >
Text File  |  1995-03-04  |  9KB  |  444 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 DrawZoom(GLint x, GLint y)
  226. {
  227.  
  228.     glPushMatrix();
  229.  
  230.     glViewport(0, 0, windW, windH);
  231.     glGetIntegerv(GL_VIEWPORT, vp);
  232.  
  233.     glMatrixMode(GL_PROJECTION);
  234.     glLoadIdentity();
  235.     gluPickMatrix(x, windH-y, 4, 4, vp);
  236.     gluOrtho2D(-175., 175., -175., 175.);
  237.     glMatrixMode(GL_MODELVIEW);
  238.  
  239.     glClearColor(0.0, 0.0, 0.0, 0.0);
  240.     glClear(GL_COLOR_BUFFER_BIT);
  241.  
  242.     glScalef(zoom, zoom, zoom);
  243.     glRotatef(zRotation, 0, 0, 1);
  244.  
  245.     Render(GL_RENDER);
  246.  
  247.     glPopMatrix();
  248. }
  249.  
  250. static void DumpFeedbackVert(GLint *i, GLint n)
  251. {
  252.     GLint index;
  253.  
  254.     index = *i;
  255.     if (index+7 > n) {
  256.     *i = n;
  257.     printf("  ???\n");
  258.     return;
  259.     }
  260.     printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  261.        feedBuf[index],
  262.        feedBuf[index+1],
  263.        feedBuf[index+2],
  264.        feedBuf[index+3],
  265.        feedBuf[index+4],
  266.        feedBuf[index+5]);
  267.     index += 7;
  268.     *i = index;
  269. }
  270.  
  271. static void DrawFeedback(GLint n)
  272. {
  273.     GLint i;
  274.     GLint verts;
  275.  
  276.     printf("Feedback results (%d floats):\n", n);
  277.     for (i = 0; i < n; i++) {
  278.     switch ((GLint)feedBuf[i]) {
  279.       case GL_POLYGON_TOKEN:
  280.         printf("Polygon");
  281.         i++;
  282.         if (i < n) {
  283.         verts = (GLint)feedBuf[i];
  284.         i++;
  285.         printf(": %d vertices", verts);
  286.         } else {
  287.         verts = 0;
  288.         }
  289.         printf("\n");
  290.         while (verts) {
  291.         DumpFeedbackVert(&i, n);
  292.         verts--;
  293.         }
  294.         i--;
  295.         break;
  296.       case GL_LINE_TOKEN:
  297.         printf("Line:\n");
  298.         i++;
  299.         DumpFeedbackVert(&i, n);
  300.         DumpFeedbackVert(&i, n);
  301.         i--;
  302.         break;
  303.       case GL_LINE_RESET_TOKEN:
  304.         printf("Line Reset:\n");
  305.         i++;
  306.         DumpFeedbackVert(&i, n);
  307.         DumpFeedbackVert(&i, n);
  308.         i--;
  309.         break;
  310.       default:
  311.         printf("%9.2f\n", feedBuf[i]);
  312.         break;
  313.     }
  314.     }
  315.     if (i == MAXFEED) {
  316.     printf("...\n");
  317.     }
  318.     printf("\n");
  319. }
  320.  
  321. static void DoFeedback(void) 
  322. {
  323.     GLint x;
  324.  
  325.     glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  326.     (void)glRenderMode(GL_FEEDBACK);
  327.  
  328.     glPushMatrix();
  329.  
  330.     glViewport(0, 0, windW, windH);
  331.     glGetIntegerv(GL_VIEWPORT, vp);
  332.  
  333.     glMatrixMode(GL_PROJECTION);
  334.     glLoadIdentity();
  335.     gluOrtho2D(-175., 175., -175., 175.);
  336.     glMatrixMode(GL_MODELVIEW);
  337.  
  338.     glClearColor(0.0, 0.0, 0.0, 0.0);
  339.     glClear(GL_COLOR_BUFFER_BIT);
  340.  
  341.     glScalef(zoom, zoom, zoom);
  342.     glRotatef(zRotation, 0, 0, 1);
  343.  
  344.     Render(GL_FEEDBACK);
  345.  
  346.     glPopMatrix();
  347.     
  348.     x = glRenderMode(GL_RENDER); 
  349.     if (x == -1) {
  350.     x = MAXFEED;
  351.     }
  352.  
  353.     DrawFeedback((GLint)x);
  354. }
  355.  
  356. static GLenum Key(int key, GLenum mask)
  357. {
  358.     int mouseX, mouseY;
  359.  
  360.     switch (key) {
  361.       case TK_ESCAPE:
  362.     tkQuit();
  363.       case TK_LEFT:
  364.     zRotation += 0.5;
  365.     break;
  366.       case TK_RIGHT:
  367.     zRotation -= 0.5;
  368.     break;
  369.       case TK_Z:
  370.     zoom /= 0.75;
  371.     break;
  372.       case TK_z:
  373.     zoom *= 0.75;
  374.     break;
  375.       case TK_f:
  376.     DoFeedback();
  377.     break;
  378.       case TK_d:
  379.     tkGetMouseLoc(&mouseX, &mouseY);
  380.     DrawZoom((GLint)mouseX, (GLint)mouseY);
  381.     break;
  382.       case TK_l:
  383.     linePoly = !linePoly;
  384.     if (linePoly) {
  385.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  386.     } else {
  387.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  388.     }
  389.     break;
  390.       default:
  391.     return GL_FALSE;
  392.     }
  393.     return GL_TRUE;
  394. }
  395.  
  396. static GLenum Args(int argc, char **argv)
  397. {
  398.     GLint i;
  399.  
  400.     directRender = GL_TRUE;
  401.  
  402.     for (i = 1; i < argc; i++) {
  403.     if (strcmp(argv[i], "-dr") == 0) {
  404.         directRender = GL_TRUE;
  405.     } else if (strcmp(argv[i], "-ir") == 0) {
  406.         directRender = GL_FALSE;
  407.     } else {
  408.         printf("%s (Bad option).\n", argv[i]);
  409.         return GL_FALSE;
  410.     }
  411.     }
  412.     return GL_TRUE;
  413. }
  414.  
  415. void main(int argc, char **argv)
  416. {
  417.     GLenum type;
  418.  
  419.     if (Args(argc, argv) == GL_FALSE) {
  420.     tkQuit();
  421.     }
  422.  
  423.     windW = 300;
  424.     windH = 300;
  425.     tkInitPosition(0, 0, windW, windH);
  426.  
  427.     type = TK_RGB | TK_SINGLE;
  428.     type |= (directRender) ? TK_DIRECT : TK_INDIRECT;
  429.     tkInitDisplayMode(type);
  430.  
  431.     if (tkInitWindow("Select Test") == GL_FALSE) {
  432.     tkQuit();
  433.     }
  434.  
  435.     Init();
  436.  
  437.     tkExposeFunc(Reshape);
  438.     tkReshapeFunc(Reshape);
  439.     tkKeyDownFunc(Key);
  440.     tkMouseDownFunc(Mouse);
  441.     tkDisplayFunc(Draw);
  442.     tkExec();
  443. }
  444.