1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
|
/*
* CS 453 - Final project : An OpenGL version of the pegboard game IQ
* Due : June 5, 1997
* Author : Kiri Wagstaff
*
* File : pick.c
* Description : Routines for picking ability. MANY thanks to Nate
* Robins since all of this code is his. I couldn't
* have done it without him. :)
*
*/
#include <stdarg.h>
#include "gliq.h"
int picked=0; /* Which piece has been selected? */
GLuint select_buffer[SELECT_BUFFER];
GLboolean selection = GL_FALSE;
GLuint pick(int x, int y);
void passive(int x, int y);
void text(GLuint x, GLuint y, GLfloat scale, char *format, ...);
GLuint pick(int x, int y)
{
GLuint i, hits, num_names, picked;
GLuint* p;
GLboolean save;
GLuint depth = (GLuint)-1;
GLint viewport[4];
int height = glutGet(GLUT_WINDOW_HEIGHT);
int width = glutGet(GLUT_WINDOW_WIDTH);
/* fill in the current viewport parameters */
viewport[0] = 0;
viewport[1] = 0;
viewport[2] = width;
viewport[3] = height;
/* set the render mode to selection */
glRenderMode(GL_SELECT);
selection = GL_TRUE;
glInitNames();
glPushName(0);
/* setup a picking matrix and render into selection buffer */
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(x, viewport[3] - y, 5.0, 5.0, viewport);
gluPerspective(60.0, (GLfloat)viewport[3]/(GLfloat)viewport[2], 1.0, 128.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, -2.0, -15.0);
switch(curstate)
{
case SELBOARD:
/* Draw the quit button */
drawquit(7.0, 9.0, 0.4, 1.0);
displaybuttons();
break;
case PLAY:
/* Draw the quit button */
drawquit(7.0, 9.0, 0.4, 1.0);
glPushMatrix();
glRotatef(45.0, 1.0, 0.0, 0.0);
tbMatrix();
drawpegs();
glPopMatrix();
break;
case HIGHSC:
break;
case VIEWSCORES:
break;
default:
printf("Unknown state %d, exiting.\n", curstate);
exit(1);
}
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
hits = glRenderMode(GL_RENDER);
selection = GL_FALSE;
p = select_buffer;
picked = 0;
for (i = 0; i < hits; i++) {
save = GL_FALSE;
num_names = *p; /* number of names in this hit */
p++;
if (*p <= depth) { /* check the 1st depth value */
depth = *p;
save = GL_TRUE;
}
p++;
if (*p <= depth) { /* check the 2nd depth value */
depth = *p;
save = GL_TRUE;
}
p++;
if (save)
picked = *p;
p += num_names; /* skip over the rest of the names */
}
return picked;
}
void passive(int x, int y)
{
picked = pick(x,y);
glutPostRedisplay();
}
/* text: general purpose text routine. draws a string according to
* format in a stroke font at x, y after scaling it by the scale
* specified (scale is in window-space (lower-left origin) pixels).
*
* x - position in x (in window-space)
* y - position in y (in window-space)
* scale - scale in pixels
* format - as in printf()
*/
void
text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
{
va_list args;
char buffer[255], *p;
GLfloat font_scale = 119.05 + 33.33;
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glTranslatef(x, y, 0.0);
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
for(p = buffer; *p; p++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
glPopAttrib();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
|