/* * (c) Copyright 1993, Silicon Graphics, Inc. * 1993-1995 Microsoft Corporation * * ALL RIGHTS RESERVED * * Please refer to OpenGL/readme.txt for additional information * */ /* * picksquare.c * Use of multiple names and picking are demonstrated. * A 3x3 grid of squares is drawn. When the left mouse * button is pressed, all squares under the cursor position * have their color changed. */ #include "glos.h" #include #include #include #include void myinit(void); void processHits (GLint hits, GLuint buffer[]); void CALLBACK pickSquares(AUX_EVENTREC *event); void CALLBACK display(void); void CALLBACK myReshape(GLsizei w, GLsizei h); int board[3][3]; /* amount of color for each square */ /* Clear color value for every square on the board */ void myinit(void) { int i, j; for (i = 0; i < 3; i++) for (j = 0; j < 3; j ++) board[i][j] = 0; glClearColor (0.0, 0.0, 0.0, 0.0); } /* The nine squares are drawn. In selection mode, each * square is given two names: one for the row and the * other for the column on the grid. The color of each * square is determined by its position on the grid, and * the value in the board[][] array. */ void drawSquares(GLenum mode) { GLuint i, j; for (i = 0; i < 3; i++) { if (mode == GL_SELECT) glLoadName (i); for (j = 0; j < 3; j ++) { if (mode == GL_SELECT) glPushName (j); glColor3f ((GLfloat) i/3.0, (GLfloat) j/3.0, (GLfloat) board[i][j]/3.0); glRecti (i, j, i+1, j+1); if (mode == GL_SELECT) glPopName (); } } } /* processHits() prints out the contents of the * selection array. */ void processHits (GLint hits, GLuint buffer[]) { int i, j; GLint ii, jj, 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 this hit = %d\n", names); ptr++; //printf (" z1 is %u;", *ptr); ptr++; //printf (" z2 is %u\n", *ptr); ptr++; //printf (" names are "); for (j = 0; j < names; j++) { /* for each name */ //printf ("%d ", *ptr); if (j == 0) /* set row and column */ ii = *ptr; else if (j == 1) jj = *ptr; ptr++; } //printf ("\n"); board[ii][jj] = (board[ii][jj] + 1) % 3; } } /* pickSquares() sets up selection mode, name stack, * and projection matrix for picking. Then the * objects are drawn. */ #define BUFSIZE 512 void CALLBACK pickSquares(AUX_EVENTREC *event) { GLuint selectBuf[BUFSIZE]; GLint hits; GLint viewport[4]; int x, y; x = event->data[AUX_MOUSEX]; y = event->data[AUX_MOUSEY]; glGetIntegerv (GL_VIEWPORT, viewport); glSelectBuffer (BUFSIZE, selectBuf); (void) glRenderMode (GL_SELECT); glInitNames(); glPushName((unsigned)-1); glMatrixMode (GL_PROJECTION); glPushMatrix (); glLoadIdentity (); /* create 5x5 pixel picking region near cursor location */ gluPickMatrix ((GLdouble) x, (GLdouble) (viewport[3] - y), 5.0, 5.0, viewport); gluOrtho2D (0.0, 3.0, 0.0, 3.0); drawSquares (GL_SELECT); glMatrixMode (GL_PROJECTION); glPopMatrix (); glFlush (); hits = glRenderMode (GL_RENDER); processHits (hits, selectBuf); } void CALLBACK display(void) { glClear(GL_COLOR_BUFFER_BIT); drawSquares (GL_RENDER); glFlush(); } void CALLBACK myReshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D (0.0, 3.0, 0.0, 3.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. */ int main(int argc, char** argv) { auxInitDisplayMode (AUX_SINGLE | AUX_RGB); auxInitPosition (0, 0, 100, 100); auxInitWindow ("Picking Squares"); myinit (); auxMouseFunc (AUX_LEFTBUTTON, AUX_MOUSEDOWN, pickSquares); auxReshapeFunc (myReshape); auxMainLoop(display); return(0); }