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