home *** CD-ROM | disk | FTP | other *** search
/ Amiga Magazin: Amiga-CD 2000 April & May / AMIGA_2000_04.iso / patches / mesa3.1 / samples / select.c < prev    next >
C/C++ Source or Header  |  2000-01-01  |  9KB  |  457 lines

  1. /*
  2.  * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
  3.  *
  4.  * Permission to use, copy, modify, distribute, and sell this software and
  5.  * its documentation for any purpose is hereby granted without fee, provided
  6.  * that (i) the above copyright notices and this permission notice appear in
  7.  * all copies of the software and related documentation, and (ii) the name of
  8.  * Silicon Graphics may not be used in any advertising or
  9.  * publicity relating to the software without the specific, prior written
  10.  * permission of Silicon Graphics.
  11.  *
  12.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
  13.  * ANY KIND,
  14.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  15.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  16.  *
  17.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
  18.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  19.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  20.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
  21.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  22.  * OF THIS SOFTWARE.
  23.  */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <math.h>
  28. #include <string.h>
  29. #include <time.h>
  30. #include <GL/glut.h>
  31.  
  32.  
  33. #define MAXOBJS 10000
  34. #define MAXSELECT 100
  35. #define MAXFEED 300
  36. #define    SOLID 1
  37. #define    LINE 2
  38. #define    POINT 3
  39.  
  40.  
  41. GLint windW, windH;
  42.  
  43. GLuint selectBuf[MAXSELECT];
  44. GLfloat feedBuf[MAXFEED];
  45. GLint vp[4];
  46. float zRotation = 90.0;
  47. float zoom = 1.0;
  48. GLint objectCount;
  49. GLint numObjects;
  50. struct object {
  51.     float v1[2];
  52.     float v2[2];
  53.     float v3[2];
  54.     float color[3];
  55. } objects[MAXOBJS];
  56. GLenum linePoly = GL_FALSE;
  57.  
  58.  
  59. static void InitObjects(GLint num)
  60. {
  61.     GLint i;
  62.     float x, y;
  63.  
  64.     if (num > MAXOBJS) {
  65.     num = MAXOBJS;
  66.     }
  67.     if (num < 1) {
  68.     num = 1;
  69.     }
  70.     objectCount = num;
  71.  
  72.     srand((unsigned int)time(NULL));
  73.     for (i = 0; i < num; i++) {
  74.     x = (rand() % 300) - 150;
  75.     y = (rand() % 300) - 150;
  76.  
  77.     objects[i].v1[0] = x + (rand() % 50) - 25;
  78.     objects[i].v2[0] = x + (rand() % 50) - 25;
  79.     objects[i].v3[0] = x + (rand() % 50) - 25;
  80.     objects[i].v1[1] = y + (rand() % 50) - 25;
  81.     objects[i].v2[1] = y + (rand() % 50) - 25;
  82.     objects[i].v3[1] = y + (rand() % 50) - 25;
  83.     objects[i].color[0] = ((rand() % 100) + 50) / 150.0;
  84.     objects[i].color[1] = ((rand() % 100) + 50) / 150.0;
  85.     objects[i].color[2] = ((rand() % 100) + 50) / 150.0;
  86.     }
  87. }
  88.  
  89. static void Init(void)
  90. {
  91.  
  92.     numObjects = 10;
  93.     InitObjects(numObjects);
  94.     glGetIntegerv(GL_VIEWPORT, vp);
  95. }
  96.  
  97. static void Reshape(int width, int height)
  98. {
  99.  
  100.     windW = (GLint)width;
  101.     windH = (GLint)height;
  102. }
  103.  
  104. static void Render(GLenum mode)
  105. {
  106.     GLint i;
  107.  
  108.     for (i = 0; i < objectCount; i++) {
  109.     if (mode == GL_SELECT) {
  110.         glLoadName(i);
  111.     }
  112.     glColor3fv(objects[i].color);
  113.     glBegin(GL_POLYGON);
  114.         glVertex2fv(objects[i].v1);
  115.         glVertex2fv(objects[i].v2);
  116.         glVertex2fv(objects[i].v3);
  117.     glEnd();
  118.     }
  119. }
  120.  
  121. static GLint DoSelect(GLint x, GLint y)
  122. {
  123.     GLint hits;
  124.  
  125.     glSelectBuffer(MAXSELECT, selectBuf);
  126.     (void)glRenderMode(GL_SELECT);
  127.     glInitNames();
  128.     glPushName(~0);
  129.  
  130.     glPushMatrix();
  131.  
  132.     glViewport(0, 0, windW, windH);
  133.     glGetIntegerv(GL_VIEWPORT, vp);
  134.  
  135.     glMatrixMode(GL_PROJECTION);
  136.     glLoadIdentity();
  137.     gluPickMatrix(x, windH-y, 4, 4, vp);
  138.     gluOrtho2D(-175, 175, -175, 175);
  139.     glMatrixMode(GL_MODELVIEW);
  140.  
  141.     glClearColor(0.0, 0.0, 0.0, 0.0);
  142.     glClear(GL_COLOR_BUFFER_BIT);
  143.  
  144.     glScalef(zoom, zoom, zoom);
  145.     glRotatef(zRotation, 0, 0, 1);
  146.  
  147.     Render(GL_SELECT);
  148.  
  149.     glPopMatrix();
  150.     
  151.     hits = glRenderMode(GL_RENDER); 
  152.     if (hits <= 0) {
  153.     return -1;
  154.     }
  155.  
  156.     return selectBuf[(hits-1)*4+3];
  157. }
  158.  
  159. static void RecolorTri(GLint h)
  160. {
  161.  
  162.     objects[h].color[0] = ((rand() % 100) + 50) / 150.0;
  163.     objects[h].color[1] = ((rand() % 100) + 50) / 150.0;
  164.     objects[h].color[2] = ((rand() % 100) + 50) / 150.0;
  165. }
  166.  
  167. static void DeleteTri(GLint h)
  168. {
  169.  
  170.     objects[h] = objects[objectCount-1];
  171.     objectCount--;
  172. }
  173.  
  174. static void GrowTri(GLint h)
  175. {
  176.     float v[2];
  177.     float *oldV;
  178.     GLint i;
  179.  
  180.     v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0];
  181.     v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1];
  182.     v[0] /= 3;
  183.     v[1] /= 3;
  184.  
  185.     for (i = 0; i < 3; i++) {
  186.     switch (i) {
  187.       case 0:
  188.         oldV = objects[h].v1;
  189.         break;
  190.       case 1:
  191.         oldV = objects[h].v2;
  192.         break;
  193.       case 2:
  194.         oldV = objects[h].v3;
  195.         break;
  196.     }
  197.     oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0];
  198.     oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1];
  199.     }
  200. }
  201.  
  202. static void Mouse(int button, int state, int mouseX, int mouseY)
  203. {
  204.     GLint hit;
  205.  
  206.     if (state != GLUT_DOWN)
  207.     return;
  208.  
  209.     hit = DoSelect((GLint)mouseX, (GLint)mouseY);
  210.     if (hit != -1) {
  211.     if (button == GLUT_LEFT_BUTTON) {
  212.         RecolorTri(hit);
  213.     }
  214.     if (button == GLUT_MIDDLE_BUTTON) {
  215.         GrowTri(hit);
  216.     }
  217.     if (button == GLUT_RIGHT_BUTTON) {
  218.         DeleteTri(hit);
  219.     }
  220.     }
  221.  
  222.     glutPostRedisplay();
  223. }
  224.  
  225. static void Draw(void)
  226. {
  227.  
  228.     glPushMatrix();
  229.  
  230.     glViewport(0, 0, windW, windH);
  231.     glGetIntegerv(GL_VIEWPORT, vp);
  232.  
  233.     glMatrixMode(GL_PROJECTION);
  234.     glLoadIdentity();
  235.     gluOrtho2D(-175, 175, -175, 175);
  236.     glMatrixMode(GL_MODELVIEW);
  237.  
  238.     glClearColor(0.0, 0.0, 0.0, 0.0);
  239.     glClear(GL_COLOR_BUFFER_BIT);
  240.  
  241.     glScalef(zoom, zoom, zoom);
  242.     glRotatef(zRotation, 0, 0, 1);
  243.  
  244.     Render(GL_RENDER);
  245.  
  246.     glPopMatrix();
  247.  
  248.     glFlush();
  249. }
  250.  
  251. static void DrawZoom(GLint x, GLint y)
  252. {
  253.  
  254.     glPushMatrix();
  255.  
  256.     glViewport(0, 0, windW, windH);
  257.     glGetIntegerv(GL_VIEWPORT, vp);
  258.  
  259.     glMatrixMode(GL_PROJECTION);
  260.     glLoadIdentity();
  261.     gluPickMatrix(x, windH-y, 4, 4, vp);
  262.     gluOrtho2D(-175, 175, -175, 175);
  263.     glMatrixMode(GL_MODELVIEW);
  264.  
  265.     glClearColor(0.0, 0.0, 0.0, 0.0);
  266.     glClear(GL_COLOR_BUFFER_BIT);
  267.  
  268.     glScalef(zoom, zoom, zoom);
  269.     glRotatef(zRotation, 0, 0, 1);
  270.  
  271.     Render(GL_RENDER);
  272.  
  273.     glPopMatrix();
  274. }
  275.  
  276. static void DumpFeedbackVert(GLint *i, GLint n)
  277. {
  278.     GLint index;
  279.  
  280.     index = *i;
  281.     if (index+7 > n) {
  282.     *i = n;
  283.     printf("  ???\n");
  284.     return;
  285.     }
  286.     printf("  (%g %g %g), color = (%4.2f %4.2f %4.2f)\n",
  287.        feedBuf[index],
  288.        feedBuf[index+1],
  289.        feedBuf[index+2],
  290.        feedBuf[index+3],
  291.        feedBuf[index+4],
  292.        feedBuf[index+5]);
  293.     index += 7;
  294.     *i = index;
  295. }
  296.  
  297. static void DrawFeedback(GLint n)
  298. {
  299.     GLint i;
  300.     GLint verts;
  301.  
  302.     printf("Feedback results (%d floats):\n", n);
  303.     for (i = 0; i < n; i++) {
  304.     switch ((GLint)feedBuf[i]) {
  305.       case GL_POLYGON_TOKEN:
  306.         printf("Polygon");
  307.         i++;
  308.         if (i < n) {
  309.         verts = (GLint)feedBuf[i];
  310.         i++;
  311.         printf(": %d vertices", verts);
  312.         } else {
  313.         verts = 0;
  314.         }
  315.         printf("\n");
  316.         while (verts) {
  317.         DumpFeedbackVert(&i, n);
  318.         verts--;
  319.         }
  320.         i--;
  321.         break;
  322.       case GL_LINE_TOKEN:
  323.         printf("Line:\n");
  324.         i++;
  325.         DumpFeedbackVert(&i, n);
  326.         DumpFeedbackVert(&i, n);
  327.         i--;
  328.         break;
  329.       case GL_LINE_RESET_TOKEN:
  330.         printf("Line Reset:\n");
  331.         i++;
  332.         DumpFeedbackVert(&i, n);
  333.         DumpFeedbackVert(&i, n);
  334.         i--;
  335.         break;
  336.       default:
  337.         printf("%9.2f\n", feedBuf[i]);
  338.         break;
  339.     }
  340.     }
  341.     if (i == MAXFEED) {
  342.     printf("...\n");
  343.     }
  344.     printf("\n");
  345. }
  346.  
  347. static void DoFeedback(void) 
  348. {
  349.     GLint x;
  350.  
  351.     glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf);
  352.     (void)glRenderMode(GL_FEEDBACK);
  353.  
  354.     glPushMatrix();
  355.  
  356.     glViewport(0, 0, windW, windH);
  357.     glGetIntegerv(GL_VIEWPORT, vp);
  358.  
  359.     glMatrixMode(GL_PROJECTION);
  360.     glLoadIdentity();
  361.     gluOrtho2D(-175, 175, -175, 175);
  362.     glMatrixMode(GL_MODELVIEW);
  363.  
  364.     glClearColor(0.0, 0.0, 0.0, 0.0);
  365.     glClear(GL_COLOR_BUFFER_BIT);
  366.  
  367.     glScalef(zoom, zoom, zoom);
  368.     glRotatef(zRotation, 0, 0, 1);
  369.  
  370.     Render(GL_FEEDBACK);
  371.  
  372.     glPopMatrix();
  373.     
  374.     x = glRenderMode(GL_RENDER); 
  375.     if (x == -1) {
  376.     x = MAXFEED;
  377.     }
  378.  
  379.     DrawFeedback((GLint)x);
  380. }
  381.  
  382. static void Key2(int key, int x, int y)
  383. {
  384.     switch (key) {
  385.       case GLUT_KEY_LEFT:
  386.     zRotation += 0.5;
  387.     break;
  388.       case GLUT_KEY_RIGHT:
  389.     zRotation -= 0.5;
  390.     break;
  391.       default:
  392.     return;
  393.     }
  394.  
  395.     glutPostRedisplay();
  396. }
  397.  
  398. static void Key(unsigned char key, int x, int y)
  399. {
  400.     switch (key) {
  401.       case 27:
  402.     exit(1);
  403.       case 'Z':
  404.     zoom /= 0.75;
  405.     break;
  406.       case 'z':
  407.     zoom *= 0.75;
  408.     break;
  409.       case 'f':
  410.     DoFeedback();
  411.     break;
  412.       case 'd':
  413.     DrawZoom(x, y);
  414.     break;
  415.       case 'l':
  416.     linePoly = !linePoly;
  417.     if (linePoly) {
  418.         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  419.     } else {
  420.         glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  421.     }
  422.     break;
  423.       default:
  424.     return;
  425.     }
  426.  
  427.     glutPostRedisplay();
  428. }
  429.  
  430. int main(int argc, char **argv)
  431. {
  432.     GLenum type;
  433.  
  434.     glutInit(&argc, argv);
  435.  
  436.     windW = 300;
  437.     windH = 300;
  438.     glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
  439.  
  440.     type = GLUT_RGB | GLUT_SINGLE;
  441.     glutInitDisplayMode(type);
  442.  
  443.     if (glutCreateWindow("Select Test") == GL_FALSE) {
  444.     exit(1);
  445.     }
  446.  
  447.     Init();
  448.  
  449.     glutReshapeFunc(Reshape);
  450.     glutKeyboardFunc(Key);
  451.     glutSpecialFunc(Key2);
  452.     glutMouseFunc(Mouse);
  453.     glutDisplayFunc(Draw);
  454.     glutMainLoop();
  455.     return 0;
  456. }
  457.