| /* |
| * Copyright (c) 1993-1997, 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(R) is a registered trademark of Silicon Graphics, Inc. |
| */ |
| |
| /* |
| * select.c |
| * This is an illustration of the selection mode and |
| * name stack, which detects whether objects which collide |
| * with a viewing volume. First, four triangles and a |
| * rectangular box representing a viewing volume are drawn |
| * (drawScene routine). The green triangle and yellow |
| * triangles appear to lie within the viewing volume, but |
| * the red triangle appears to lie outside it. Then the |
| * selection mode is entered (selectObjects routine). |
| * Drawing to the screen ceases. To see if any collisions |
| * occur, the four triangles are called. In this example, |
| * the green triangle causes one hit with the name 1, and |
| * the yellow triangles cause one hit with the name 3. |
| */ |
| #include <GL/glut.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| /* draw a triangle with vertices at (x1, y1), (x2, y2) |
| * and (x3, y3) at z units away from the origin. |
| */ |
| static void drawTriangle (GLfloat x1, GLfloat y1, GLfloat x2, |
| GLfloat y2, GLfloat x3, GLfloat y3, GLfloat z) |
| { |
| glBegin (GL_TRIANGLES); |
| glVertex3f (x1, y1, z); |
| glVertex3f (x2, y2, z); |
| glVertex3f (x3, y3, z); |
| glEnd (); |
| } |
| |
| /* draw a rectangular box with these outer x, y, and z values */ |
| static void drawViewVolume (GLfloat x1, GLfloat x2, GLfloat y1, |
| GLfloat y2, GLfloat z1, GLfloat z2) |
| { |
| glColor3f (1.0, 1.0, 1.0); |
| glBegin (GL_LINE_LOOP); |
| glVertex3f (x1, y1, -z1); |
| glVertex3f (x2, y1, -z1); |
| glVertex3f (x2, y2, -z1); |
| glVertex3f (x1, y2, -z1); |
| glEnd (); |
| |
| glBegin (GL_LINE_LOOP); |
| glVertex3f (x1, y1, -z2); |
| glVertex3f (x2, y1, -z2); |
| glVertex3f (x2, y2, -z2); |
| glVertex3f (x1, y2, -z2); |
| glEnd (); |
| |
| glBegin (GL_LINES); /* 4 lines */ |
| glVertex3f (x1, y1, -z1); |
| glVertex3f (x1, y1, -z2); |
| glVertex3f (x1, y2, -z1); |
| glVertex3f (x1, y2, -z2); |
| glVertex3f (x2, y1, -z1); |
| glVertex3f (x2, y1, -z2); |
| glVertex3f (x2, y2, -z1); |
| glVertex3f (x2, y2, -z2); |
| glEnd (); |
| } |
| |
| /* drawScene draws 4 triangles and a wire frame |
| * which represents the viewing volume. |
| */ |
| static void drawScene (void) |
| { |
| glMatrixMode (GL_PROJECTION); |
| glLoadIdentity (); |
| gluPerspective (40.0, 4.0/3.0, 1.0, 100.0); |
| |
| glMatrixMode (GL_MODELVIEW); |
| glLoadIdentity (); |
| gluLookAt (7.5, 7.5, 12.5, 2.5, 2.5, -5.0, 0.0, 1.0, 0.0); |
| glColor3f (0.0, 1.0, 0.0); /* green triangle */ |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0); |
| glColor3f (1.0, 0.0, 0.0); /* red triangle */ |
| drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0); |
| glColor3f (1.0, 1.0, 0.0); /* yellow triangles */ |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0); |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0); |
| drawViewVolume (0.0, 5.0, 0.0, 5.0, 0.0, 10.0); |
| } |
| |
| /* processHits prints out the contents of the selection array |
| */ |
| static void processHits (GLint hits, GLuint buffer[]) |
| { |
| GLint i; |
| GLuint j, names, *ptr; |
| |
| printf ("hits = %d\n", hits); |
| ptr = (GLuint *) buffer; |
| for (i = 0; i < hits; i++) { /* for each hit */ |
| names = *ptr; |
| printf (" number of names for hit = %d\n", names); ptr++; |
| printf(" z1 is %g;", (float) *ptr/0x7fffffff); ptr++; |
| printf(" z2 is %g\n", (float) *ptr/0x7fffffff); ptr++; |
| printf (" the name is "); |
| for (j = 0; j < names; j++) { /* for each name */ |
| printf ("%d ", *ptr); ptr++; |
| } |
| printf ("\n"); |
| } |
| } |
| |
| /* selectObjects "draws" the triangles in selection mode, |
| * assigning names for the triangles. Note that the third |
| * and fourth triangles share one name, so that if either |
| * or both triangles intersects the viewing/clipping volume, |
| * only one hit will be registered. |
| */ |
| #define BUFSIZE 512 |
| |
| static void selectObjects(void) |
| { |
| GLuint selectBuf[BUFSIZE]; |
| GLint hits; |
| |
| glSelectBuffer (BUFSIZE, selectBuf); |
| (void) glRenderMode (GL_SELECT); |
| |
| glInitNames(); |
| glPushName(0); |
| |
| glPushMatrix (); |
| glMatrixMode (GL_PROJECTION); |
| glLoadIdentity (); |
| glOrtho (0.0, 5.0, 0.0, 5.0, 0.0, 10.0); |
| glMatrixMode (GL_MODELVIEW); |
| glLoadIdentity (); |
| glLoadName(1); |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -5.0); |
| glLoadName(2); |
| drawTriangle (2.0, 7.0, 3.0, 7.0, 2.5, 8.0, -5.0); |
| glLoadName(3); |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, 0.0); |
| drawTriangle (2.0, 2.0, 3.0, 2.0, 2.5, 3.0, -10.0); |
| glPopMatrix (); |
| glFlush (); |
| |
| hits = glRenderMode (GL_RENDER); |
| processHits (hits, selectBuf); |
| } |
| |
| static void init (void) |
| { |
| glEnable(GL_DEPTH_TEST); |
| glShadeModel(GL_FLAT); |
| } |
| |
| static void display(void) |
| { |
| glClearColor (0.0, 0.0, 0.0, 0.0); |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
| drawScene (); |
| selectObjects (); |
| glFlush(); |
| } |
| |
| /* ARGSUSED1 */ |
| static void keyboard(unsigned char key, int x, int y) |
| { |
| switch (key) { |
| case 27: |
| exit(0); |
| break; |
| } |
| } |
| |
| /* Main Loop */ |
| int main(int argc, char** argv) |
| { |
| glutInit(&argc, argv); |
| glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); |
| glutInitWindowSize (200, 200); |
| glutInitWindowPosition (100, 100); |
| glutCreateWindow (argv[0]); |
| init(); |
| glutDisplayFunc(display); |
| glutKeyboardFunc(keyboard); |
| glutMainLoop(); |
| return 0; |
| } |