132001f49Smrg/* 232001f49Smrg * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc. 332001f49Smrg * 432001f49Smrg * Permission to use, copy, modify, distribute, and sell this software and 532001f49Smrg * its documentation for any purpose is hereby granted without fee, provided 632001f49Smrg * that (i) the above copyright notices and this permission notice appear in 732001f49Smrg * all copies of the software and related documentation, and (ii) the name of 832001f49Smrg * Silicon Graphics may not be used in any advertising or 932001f49Smrg * publicity relating to the software without the specific, prior written 1032001f49Smrg * permission of Silicon Graphics. 1132001f49Smrg * 1232001f49Smrg * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF 1332001f49Smrg * ANY KIND, 1432001f49Smrg * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 1532001f49Smrg * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 1632001f49Smrg * 1732001f49Smrg * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR 1832001f49Smrg * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 1932001f49Smrg * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 2032001f49Smrg * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 2132001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 2232001f49Smrg * OF THIS SOFTWARE. 2332001f49Smrg */ 2432001f49Smrg 2532001f49Smrg#include <stdio.h> 2632001f49Smrg#include <stdlib.h> 2732001f49Smrg#include <math.h> 2832001f49Smrg#include <string.h> 2932001f49Smrg#include <time.h> 3032001f49Smrg#include "glut_wrap.h" 3132001f49Smrg 3232001f49Smrg 3332001f49Smrg#define MAXOBJS 10000 3432001f49Smrg#define MAXSELECT 100 3532001f49Smrg#define MAXFEED 300 3632001f49Smrg#define SOLID 1 3732001f49Smrg#define LINE 2 3832001f49Smrg#define POINT 3 3932001f49Smrg 4032001f49Smrg 4132001f49SmrgGLint windW, windH; 4232001f49Smrg 4332001f49SmrgGLuint selectBuf[MAXSELECT]; 4432001f49SmrgGLfloat feedBuf[MAXFEED]; 4532001f49SmrgGLint vp[4]; 4632001f49Smrgfloat zRotation = 90.0; 4732001f49Smrgfloat zoom = 1.0; 4832001f49SmrgGLint objectCount; 4932001f49SmrgGLint numObjects; 5032001f49Smrgstruct object { 5132001f49Smrg float v1[2]; 5232001f49Smrg float v2[2]; 5332001f49Smrg float v3[2]; 5432001f49Smrg float color[3]; 5532001f49Smrg} objects[MAXOBJS]; 5632001f49SmrgGLenum linePoly = GL_FALSE; 5732001f49Smrg 5832001f49Smrg 5932001f49Smrgstatic void InitObjects(GLint num) 6032001f49Smrg{ 6132001f49Smrg GLint i; 6232001f49Smrg float x, y; 6332001f49Smrg 6432001f49Smrg if (num > MAXOBJS) { 6532001f49Smrg num = MAXOBJS; 6632001f49Smrg } 6732001f49Smrg if (num < 1) { 6832001f49Smrg num = 1; 6932001f49Smrg } 7032001f49Smrg objectCount = num; 7132001f49Smrg 7232001f49Smrg srand((unsigned int)time(NULL)); 7332001f49Smrg for (i = 0; i < num; i++) { 7432001f49Smrg x = (rand() % 300) - 150; 7532001f49Smrg y = (rand() % 300) - 150; 7632001f49Smrg 7732001f49Smrg objects[i].v1[0] = x + (rand() % 50) - 25; 7832001f49Smrg objects[i].v2[0] = x + (rand() % 50) - 25; 7932001f49Smrg objects[i].v3[0] = x + (rand() % 50) - 25; 8032001f49Smrg objects[i].v1[1] = y + (rand() % 50) - 25; 8132001f49Smrg objects[i].v2[1] = y + (rand() % 50) - 25; 8232001f49Smrg objects[i].v3[1] = y + (rand() % 50) - 25; 8332001f49Smrg objects[i].color[0] = ((rand() % 100) + 50) / 150.0; 8432001f49Smrg objects[i].color[1] = ((rand() % 100) + 50) / 150.0; 8532001f49Smrg objects[i].color[2] = ((rand() % 100) + 50) / 150.0; 8632001f49Smrg } 8732001f49Smrg} 8832001f49Smrg 8932001f49Smrgstatic void Init(void) 9032001f49Smrg{ 9132001f49Smrg 9232001f49Smrg numObjects = 10; 9332001f49Smrg InitObjects(numObjects); 9432001f49Smrg glGetIntegerv(GL_VIEWPORT, vp); 9532001f49Smrg 9632001f49Smrg#if 0 /* debug - test culling */ 9732001f49Smrg glCullFace(GL_BACK); 9832001f49Smrg glFrontFace(GL_CW); 9932001f49Smrg glEnable(GL_CULL_FACE); 10032001f49Smrg#endif 10132001f49Smrg} 10232001f49Smrg 10332001f49Smrgstatic void Reshape(int width, int height) 10432001f49Smrg{ 10532001f49Smrg 10632001f49Smrg windW = (GLint)width; 10732001f49Smrg windH = (GLint)height; 10832001f49Smrg} 10932001f49Smrg 11032001f49Smrgstatic void Render(GLenum mode) 11132001f49Smrg{ 11232001f49Smrg GLint i; 11332001f49Smrg 11432001f49Smrg for (i = 0; i < objectCount; i++) { 11532001f49Smrg if (mode == GL_SELECT) { 11632001f49Smrg glLoadName(i); 11732001f49Smrg } 11832001f49Smrg glColor3fv(objects[i].color); 11932001f49Smrg glBegin(GL_POLYGON); 12032001f49Smrg glVertex2fv(objects[i].v1); 12132001f49Smrg glVertex2fv(objects[i].v2); 12232001f49Smrg glVertex2fv(objects[i].v3); 12332001f49Smrg glEnd(); 12432001f49Smrg } 12532001f49Smrg} 12632001f49Smrg 12732001f49Smrgstatic GLint DoSelect(GLint x, GLint y) 12832001f49Smrg{ 12932001f49Smrg GLint hits; 13032001f49Smrg 13132001f49Smrg glSelectBuffer(MAXSELECT, selectBuf); 13232001f49Smrg (void)glRenderMode(GL_SELECT); 13332001f49Smrg glInitNames(); 13432001f49Smrg glPushName(~0); 13532001f49Smrg 13632001f49Smrg glPushMatrix(); 13732001f49Smrg 13832001f49Smrg glViewport(0, 0, windW, windH); 13932001f49Smrg glGetIntegerv(GL_VIEWPORT, vp); 14032001f49Smrg 14132001f49Smrg glMatrixMode(GL_PROJECTION); 14232001f49Smrg glLoadIdentity(); 14332001f49Smrg gluPickMatrix(x, windH-y, 4, 4, vp); 14432001f49Smrg gluOrtho2D(-175, 175, -175, 175); 14532001f49Smrg glMatrixMode(GL_MODELVIEW); 14632001f49Smrg 14732001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 14832001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 14932001f49Smrg 15032001f49Smrg glScalef(zoom, zoom, zoom); 15132001f49Smrg glRotatef(zRotation, 0, 0, 1); 15232001f49Smrg 15332001f49Smrg Render(GL_SELECT); 15432001f49Smrg 15532001f49Smrg glPopMatrix(); 15632001f49Smrg 15732001f49Smrg hits = glRenderMode(GL_RENDER); 15832001f49Smrg if (hits <= 0) { 15932001f49Smrg return -1; 16032001f49Smrg } 16132001f49Smrg 16232001f49Smrg return selectBuf[(hits-1)*4+3]; 16332001f49Smrg} 16432001f49Smrg 16532001f49Smrgstatic void RecolorTri(GLint h) 16632001f49Smrg{ 16732001f49Smrg 16832001f49Smrg objects[h].color[0] = ((rand() % 100) + 50) / 150.0; 16932001f49Smrg objects[h].color[1] = ((rand() % 100) + 50) / 150.0; 17032001f49Smrg objects[h].color[2] = ((rand() % 100) + 50) / 150.0; 17132001f49Smrg} 17232001f49Smrg 17332001f49Smrgstatic void DeleteTri(GLint h) 17432001f49Smrg{ 17532001f49Smrg 17632001f49Smrg objects[h] = objects[objectCount-1]; 17732001f49Smrg objectCount--; 17832001f49Smrg} 17932001f49Smrg 18032001f49Smrgstatic void GrowTri(GLint h) 18132001f49Smrg{ 18232001f49Smrg float v[2]; 18332001f49Smrg float *oldV = NULL; 18432001f49Smrg GLint i; 18532001f49Smrg 18632001f49Smrg v[0] = objects[h].v1[0] + objects[h].v2[0] + objects[h].v3[0]; 18732001f49Smrg v[1] = objects[h].v1[1] + objects[h].v2[1] + objects[h].v3[1]; 18832001f49Smrg v[0] /= 3; 18932001f49Smrg v[1] /= 3; 19032001f49Smrg 19132001f49Smrg for (i = 0; i < 3; i++) { 19232001f49Smrg switch (i) { 19332001f49Smrg case 0: 19432001f49Smrg oldV = objects[h].v1; 19532001f49Smrg break; 19632001f49Smrg case 1: 19732001f49Smrg oldV = objects[h].v2; 19832001f49Smrg break; 19932001f49Smrg case 2: 20032001f49Smrg oldV = objects[h].v3; 20132001f49Smrg break; 20232001f49Smrg } 20332001f49Smrg oldV[0] = 1.5 * (oldV[0] - v[0]) + v[0]; 20432001f49Smrg oldV[1] = 1.5 * (oldV[1] - v[1]) + v[1]; 20532001f49Smrg } 20632001f49Smrg} 20732001f49Smrg 20832001f49Smrgstatic void Mouse(int button, int state, int mouseX, int mouseY) 20932001f49Smrg{ 21032001f49Smrg GLint hit; 21132001f49Smrg 21232001f49Smrg if (state != GLUT_DOWN) 21332001f49Smrg return; 21432001f49Smrg 21532001f49Smrg hit = DoSelect((GLint)mouseX, (GLint)mouseY); 21632001f49Smrg if (hit != -1) { 21732001f49Smrg if (button == GLUT_LEFT_BUTTON) { 21832001f49Smrg RecolorTri(hit); 21932001f49Smrg } 22032001f49Smrg if (button == GLUT_MIDDLE_BUTTON) { 22132001f49Smrg GrowTri(hit); 22232001f49Smrg } 22332001f49Smrg if (button == GLUT_RIGHT_BUTTON) { 22432001f49Smrg DeleteTri(hit); 22532001f49Smrg } 22632001f49Smrg } 22732001f49Smrg 22832001f49Smrg glutPostRedisplay(); 22932001f49Smrg} 23032001f49Smrg 23132001f49Smrgstatic void Draw(void) 23232001f49Smrg{ 23332001f49Smrg 23432001f49Smrg glPushMatrix(); 23532001f49Smrg 23632001f49Smrg glViewport(0, 0, windW, windH); 23732001f49Smrg glGetIntegerv(GL_VIEWPORT, vp); 23832001f49Smrg 23932001f49Smrg glMatrixMode(GL_PROJECTION); 24032001f49Smrg glLoadIdentity(); 24132001f49Smrg gluOrtho2D(-175, 175, -175, 175); 24232001f49Smrg glMatrixMode(GL_MODELVIEW); 24332001f49Smrg 24432001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 24532001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 24632001f49Smrg 24732001f49Smrg glScalef(zoom, zoom, zoom); 24832001f49Smrg glRotatef(zRotation, 0, 0, 1); 24932001f49Smrg 25032001f49Smrg Render(GL_RENDER); 25132001f49Smrg 25232001f49Smrg glPopMatrix(); 25332001f49Smrg 25432001f49Smrg glFlush(); 25532001f49Smrg} 25632001f49Smrg 25732001f49Smrgstatic void DrawZoom(GLint x, GLint y) 25832001f49Smrg{ 25932001f49Smrg 26032001f49Smrg glPushMatrix(); 26132001f49Smrg 26232001f49Smrg glViewport(0, 0, windW, windH); 26332001f49Smrg glGetIntegerv(GL_VIEWPORT, vp); 26432001f49Smrg 26532001f49Smrg glMatrixMode(GL_PROJECTION); 26632001f49Smrg glLoadIdentity(); 26732001f49Smrg gluPickMatrix(x, windH-y, 4, 4, vp); 26832001f49Smrg gluOrtho2D(-175, 175, -175, 175); 26932001f49Smrg glMatrixMode(GL_MODELVIEW); 27032001f49Smrg 27132001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 27232001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 27332001f49Smrg 27432001f49Smrg glScalef(zoom, zoom, zoom); 27532001f49Smrg glRotatef(zRotation, 0, 0, 1); 27632001f49Smrg 27732001f49Smrg Render(GL_RENDER); 27832001f49Smrg 27932001f49Smrg glPopMatrix(); 28032001f49Smrg} 28132001f49Smrg 28232001f49Smrgstatic void DumpFeedbackVert(GLint *i, GLint n) 28332001f49Smrg{ 28432001f49Smrg GLint index; 28532001f49Smrg 28632001f49Smrg index = *i; 28732001f49Smrg if (index+7 > n) { 28832001f49Smrg *i = n; 28932001f49Smrg printf(" ???\n"); 29032001f49Smrg return; 29132001f49Smrg } 29232001f49Smrg printf(" (%g %g %g), color = (%4.2f %4.2f %4.2f)\n", 29332001f49Smrg feedBuf[index], 29432001f49Smrg feedBuf[index+1], 29532001f49Smrg feedBuf[index+2], 29632001f49Smrg feedBuf[index+3], 29732001f49Smrg feedBuf[index+4], 29832001f49Smrg feedBuf[index+5]); 29932001f49Smrg index += 7; 30032001f49Smrg *i = index; 30132001f49Smrg} 30232001f49Smrg 30332001f49Smrgstatic void DrawFeedback(GLint n) 30432001f49Smrg{ 30532001f49Smrg GLint i; 30632001f49Smrg GLint verts; 30732001f49Smrg 30832001f49Smrg printf("Feedback results (%d floats):\n", n); 30932001f49Smrg for (i = 0; i < n; i++) { 31032001f49Smrg switch ((GLint)feedBuf[i]) { 31132001f49Smrg case GL_POLYGON_TOKEN: 31232001f49Smrg printf("Polygon"); 31332001f49Smrg i++; 31432001f49Smrg if (i < n) { 31532001f49Smrg verts = (GLint)feedBuf[i]; 31632001f49Smrg i++; 31732001f49Smrg printf(": %d vertices", verts); 31832001f49Smrg } else { 31932001f49Smrg verts = 0; 32032001f49Smrg } 32132001f49Smrg printf("\n"); 32232001f49Smrg while (verts) { 32332001f49Smrg DumpFeedbackVert(&i, n); 32432001f49Smrg verts--; 32532001f49Smrg } 32632001f49Smrg i--; 32732001f49Smrg break; 32832001f49Smrg case GL_LINE_TOKEN: 32932001f49Smrg printf("Line:\n"); 33032001f49Smrg i++; 33132001f49Smrg DumpFeedbackVert(&i, n); 33232001f49Smrg DumpFeedbackVert(&i, n); 33332001f49Smrg i--; 33432001f49Smrg break; 33532001f49Smrg case GL_LINE_RESET_TOKEN: 33632001f49Smrg printf("Line Reset:\n"); 33732001f49Smrg i++; 33832001f49Smrg DumpFeedbackVert(&i, n); 33932001f49Smrg DumpFeedbackVert(&i, n); 34032001f49Smrg i--; 34132001f49Smrg break; 34232001f49Smrg default: 34332001f49Smrg printf("%9.2f\n", feedBuf[i]); 34432001f49Smrg break; 34532001f49Smrg } 34632001f49Smrg } 34732001f49Smrg if (i == MAXFEED) { 34832001f49Smrg printf("...\n"); 34932001f49Smrg } 35032001f49Smrg printf("\n"); 35132001f49Smrg} 35232001f49Smrg 35332001f49Smrgstatic void DoFeedback(void) 35432001f49Smrg{ 35532001f49Smrg GLint x; 35632001f49Smrg 35732001f49Smrg glFeedbackBuffer(MAXFEED, GL_3D_COLOR, feedBuf); 35832001f49Smrg (void)glRenderMode(GL_FEEDBACK); 35932001f49Smrg 36032001f49Smrg glPushMatrix(); 36132001f49Smrg 36232001f49Smrg glViewport(0, 0, windW, windH); 36332001f49Smrg glGetIntegerv(GL_VIEWPORT, vp); 36432001f49Smrg 36532001f49Smrg glMatrixMode(GL_PROJECTION); 36632001f49Smrg glLoadIdentity(); 36732001f49Smrg gluOrtho2D(-175, 175, -175, 175); 36832001f49Smrg glMatrixMode(GL_MODELVIEW); 36932001f49Smrg 37032001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 37132001f49Smrg glClear(GL_COLOR_BUFFER_BIT); 37232001f49Smrg 37332001f49Smrg glScalef(zoom, zoom, zoom); 37432001f49Smrg glRotatef(zRotation, 0, 0, 1); 37532001f49Smrg 37632001f49Smrg Render(GL_FEEDBACK); 37732001f49Smrg 37832001f49Smrg glPopMatrix(); 37932001f49Smrg 38032001f49Smrg x = glRenderMode(GL_RENDER); 38132001f49Smrg if (x == -1) { 38232001f49Smrg x = MAXFEED; 38332001f49Smrg } 38432001f49Smrg 38532001f49Smrg DrawFeedback((GLint)x); 38632001f49Smrg} 38732001f49Smrg 38832001f49Smrgstatic void Key2(int key, int x, int y) 38932001f49Smrg{ 39032001f49Smrg switch (key) { 39132001f49Smrg case GLUT_KEY_LEFT: 39232001f49Smrg zRotation += 0.5; 39332001f49Smrg break; 39432001f49Smrg case GLUT_KEY_RIGHT: 39532001f49Smrg zRotation -= 0.5; 39632001f49Smrg break; 39732001f49Smrg default: 39832001f49Smrg return; 39932001f49Smrg } 40032001f49Smrg 40132001f49Smrg glutPostRedisplay(); 40232001f49Smrg} 40332001f49Smrg 40432001f49Smrgstatic void Key(unsigned char key, int x, int y) 40532001f49Smrg{ 40632001f49Smrg switch (key) { 40732001f49Smrg case 27: 40832001f49Smrg exit(1); 40932001f49Smrg case 'Z': 41032001f49Smrg zoom /= 0.75; 41132001f49Smrg break; 41232001f49Smrg case 'z': 41332001f49Smrg zoom *= 0.75; 41432001f49Smrg break; 41532001f49Smrg case 'f': 41632001f49Smrg DoFeedback(); 41732001f49Smrg break; 41832001f49Smrg case 'd': 41932001f49Smrg DrawZoom(x, y); 42032001f49Smrg break; 42132001f49Smrg case 'l': 42232001f49Smrg linePoly = !linePoly; 42332001f49Smrg if (linePoly) { 42432001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 42532001f49Smrg } else { 42632001f49Smrg glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 42732001f49Smrg } 42832001f49Smrg break; 42932001f49Smrg default: 43032001f49Smrg return; 43132001f49Smrg } 43232001f49Smrg 43332001f49Smrg glutPostRedisplay(); 43432001f49Smrg} 43532001f49Smrg 43632001f49Smrgint main(int argc, char **argv) 43732001f49Smrg{ 43832001f49Smrg GLenum type; 43932001f49Smrg 44032001f49Smrg glutInit(&argc, argv); 44132001f49Smrg 44232001f49Smrg windW = 300; 44332001f49Smrg windH = 300; 44432001f49Smrg glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH); 44532001f49Smrg 44632001f49Smrg type = GLUT_RGB | GLUT_SINGLE; 44732001f49Smrg glutInitDisplayMode(type); 44832001f49Smrg 44932001f49Smrg if (glutCreateWindow("Select Test") == GL_FALSE) { 45032001f49Smrg exit(1); 45132001f49Smrg } 45232001f49Smrg 45332001f49Smrg Init(); 45432001f49Smrg 45532001f49Smrg glutReshapeFunc(Reshape); 45632001f49Smrg glutKeyboardFunc(Key); 45732001f49Smrg glutSpecialFunc(Key2); 45832001f49Smrg glutMouseFunc(Mouse); 45932001f49Smrg glutDisplayFunc(Draw); 46032001f49Smrg glutMainLoop(); 46132001f49Smrg return 0; 46232001f49Smrg} 463