/* * (c) Copyright 1993, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(TM) is a trademark of Silicon Graphics, Inc. */ #include #include #include #include #include #include "tk.h" #define MAXOBJS 10000 #define MAXSELECT 100 #define MAXFEED 300 #define SOLID 1 #define LINE 2 #define POINT 3 GLenum directRender; GLint windW, windH; GLuint selectBuf[MAXSELECT]; GLfloat feedBuf[MAXFEED]; GLint vp[4]; float zRotation = 90.0; float zoom = 1.0; GLint objectCount; GLint numObjects; struct object { float v1[2]; float v2[2]; float v3[2]; float color[3]; } objects[MAXOBJS]; GLenum linePoly = GL_FALSE; static void InitObjects(GLint num) { GLint i; float x, y; if (num > MAXOBJS) { num = MAXOBJS; } if (num < 1) { num = 1; } objectCount = num; srand((unsigned int)time(NULL)); for (i = 0; i < num; i++) { x = (rand() % 300) - 150; y = (rand() % 300) - 150; objects[i].v1[0] = x + (rand() % 50) - 25; objects[i].v2[0] = x + (rand() % 50) - 25; objects[i].v3[0] = x + (rand() % 50) - 25; objects[i].v1[1] = y + (rand() % 50) - 25; objects[i].v2[1] = y + (rand() % 50) - 25; objects[i].v3[1] = y + (rand() % 50) - 25; objects[i].color[0] = ((rand() % 100) + 50) / 150.0; objects[i].color[1] = ((rand() % 100) + 50) / 150.0; objects[i].color[2] = ((rand() % 100) + 50) / 150.0; } } static void Init(void) { numObjects = 10; InitObjects(numObjects); glGetIntegerv(GL_VIEWPORT, vp); } static void Reshape(int width, int height) { windW = (GLint)width; windH = (GLint)height; } static void Render(GLenum mode) { GLint i; for (i = 0; i < objectCount; i++) { if (mode == GL_SELECT) { glLoadName(i); } glColor3fv(objects[i].color); glBegin(GL_POLYGON); glVertex2fv(objects[i].v1); glVertex2fv(objects[i].v2); glVertex2fv(objects[i].v3); glEnd(); } } static GLint DoSelect(GLint x, GLint y) { GLint hits; glSelectBuffer(MAXSELECT, selectBuf); (void)glRenderMode(GL_SELECT); glInitNames(); glPushName(~0); glPushMatrix(); glViewport(0, 0, windW, windH); glGetIntegerv(GL_VIEWPORT, vp); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPickMatrix(x, windH-y, 4, 4, vp); gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glScalef(zoom, zoom, zoom); glRotatef(zRotation, 0, 0, 1); Render(GL_SELECT); glPopMatrix(); hits = glRenderMode(GL_RENDER); if (hits <= 0) { return -1; } return selectBuf[(hits-1)*4+3]; } static void RecolorTri(GLint h) { objects[h].color[0] = ((rand() % 100) + 50) / 150.0; objects[h].color[1] = ((rand() % 100) + 50) / 150.0; objects[h].color[2] = ((rand() % 100) + 50) / 150.0; } static void DeleteTri(GLint h) { objects[h] = objects[objectCount-1]; objectCount--; } static void GrowTri(GLint h) { float v[2]; float *oldV; GLint i; v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0]; v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1]; v[0] /= 3; v[1] /= 3; for (i = 0; i < 3; i++) { switch (i) { case 0: oldV = objects[h].v1; break; case 1: oldV = objects[h].v2; break; case 2: oldV = objects[h].v3; break; } oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0]; oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1]; } } static GLenum Mouse(int mouseX, int mouseY, GLenum button) { GLint hit; hit = DoSelect((GLint)mouseX, (GLint)mouseY); if (hit != -1) { if (button & TK_LEFTBUTTON) { RecolorTri(hit); } if (button & TK_MIDDLEBUTTON) { GrowTri(hit); } if (button & TK_RIGHTBUTTON) { DeleteTri(hit); } return GL_TRUE; } return GL_FALSE; } static void Draw(void) { glPushMatrix(); glViewport(0, 0, windW, windH); glGetIntegerv(GL_VIEWPORT, vp); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glScalef(zoom, zoom, zoom); glRotatef(zRotation, 0, 0, 1); Render(GL_RENDER); glPopMatrix(); glFlush(); } static void DrawZoom(GLint x, GLint y) { glPushMatrix(); glViewport(0, 0, windW, windH); glGetIntegerv(GL_VIEWPORT, vp); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPickMatrix(x, windH-y, 4, 4, vp); gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glScalef(zoom, zoom, zoom); glRotatef(zRotation, 0, 0, 1); Render(GL_RENDER); glPopMatrix(); } static void DumpFeedbackVert(GLint *i, GLint n) { GLint index; index = *i; if (index+7 > n) { *i = n; printf(" ???\n"); return; } printf(" (%g %g %g), color = (%4.2f %4.2f %4.2f)\n", feedBuf[index], feedBuf[index+1], feedBuf[index+2], feedBuf[index+3], feedBuf[index+4], feedBuf[index+5]); index += 7; *i = index; } static void DrawFeedback(GLint n) { GLint i; GLint verts; printf("Feedback results (%d floats):\n", n); for (i = 0; i < n; i++) { switch ((GLint)feedBuf[i]) { case GL_POLYGON_TOKEN: printf("Polygon"); i++; if (i < n) { verts = (GLint)feedBuf[i]; i++; printf(": %d vertices", verts); } else { verts = 0; } printf("\n"); while (verts) { DumpFeedbackVert(&i, n); verts--; } i--; break; case GL_LINE_TOKEN: printf("Line:\n"); i++; DumpFeedbackVert(&i, n); DumpFeedbackVert(&i, n); i--; break; case GL_LINE_RESET_TOKEN: printf("Line Reset:\n"); i++; DumpFeedbackVert(&i, n); DumpFeedbackVert(&i, n); i--; break; default: printf("%9.2f\n", feedBuf[i]); break; } } if (i == MAXFEED) { printf("...\n"); } printf("\n"); } static void DoFeedback(void) { GLint x; glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf); (void)glRenderMode(GL_FEEDBACK); glPushMatrix(); glViewport(0, 0, windW, windH); glGetIntegerv(GL_VIEWPORT, vp); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-175, 175, -175, 175); glMatrixMode(GL_MODELVIEW); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glScalef(zoom, zoom, zoom); glRotatef(zRotation, 0, 0, 1); Render(GL_FEEDBACK); glPopMatrix(); x = glRenderMode(GL_RENDER); if (x == -1) { x = MAXFEED; } DrawFeedback((GLint)x); } static GLenum Key(int key, GLenum mask) { int mouseX, mouseY; switch (key) { case TK_ESCAPE: tkQuit(); case TK_LEFT: zRotation += 0.5; break; case TK_RIGHT: zRotation -= 0.5; break; case TK_Z: zoom /= 0.75; break; case TK_z: zoom *= 0.75; break; case TK_f: DoFeedback(); break; case TK_d: tkGetMouseLoc(&mouseX, &mouseY); DrawZoom((GLint)mouseX, (GLint)mouseY); break; case TK_l: linePoly = !linePoly; if (linePoly) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } break; default: return GL_FALSE; } return GL_TRUE; } static GLenum Args(int argc, char **argv) { GLint i; directRender = GL_FALSE; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-dr") == 0) { directRender = GL_TRUE; } else if (strcmp(argv[i], "-ir") == 0) { directRender = GL_FALSE; } else { printf("%s (Bad option).\n", argv[i]); return GL_FALSE; } } return GL_TRUE; } void main(int argc, char **argv) { GLenum type; if (Args(argc, argv) == GL_FALSE) { tkQuit(); } windW = 300; windH = 300; tkInitPosition(0, 0, windW, windH); type = TK_RGB | TK_SINGLE; type |= (directRender) ? TK_DIRECT : TK_INDIRECT; tkInitDisplayMode(type); if (tkInitWindow("Select Test") == GL_FALSE) { tkQuit(); } Init(); tkExposeFunc(Reshape); tkReshapeFunc(Reshape); tkKeyDownFunc(Key); tkMouseDownFunc(Mouse); tkDisplayFunc(Draw); tkExec(); }