1/* 2 * GL_ARB_occlusion_query demo 3 * 4 * Brian Paul 5 * 12 June 2003 6 * 7 * Copyright (C) 2003 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27#include <assert.h> 28#include <stdio.h> 29#include <stdlib.h> 30#include <string.h> 31#include <math.h> 32#include <GL/glew.h> 33#include "glut_wrap.h" 34 35#define NUM_OCC 10 36 37static GLboolean Anim = GL_TRUE; 38static GLfloat Xpos[NUM_OCC], Ypos[NUM_OCC]; 39static GLfloat Sign[NUM_OCC]; 40static GLuint OccQuery[NUM_OCC]; 41static GLint Win = 0; 42 43 44static void 45PrintString(const char *s) 46{ 47 while (*s) { 48 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 49 s++; 50 } 51} 52 53 54 55static void Idle(void) 56{ 57 static int lastTime = 0; 58 int time = glutGet(GLUT_ELAPSED_TIME); 59 float step; 60 int i; 61 62 if (lastTime == 0) 63 lastTime = time; 64 else if (time - lastTime < 20) /* 50Hz update */ 65 return; 66 67 for (i = 0; i < NUM_OCC; i++) { 68 69 step = (time - lastTime) / 1000.0 * Sign[i]; 70 71 Xpos[i] += step; 72 73 if (Xpos[i] > 2.5) { 74 Xpos[i] = 2.5; 75 Sign[i] = -1; 76 } 77 else if (Xpos[i] < -2.5) { 78 Xpos[i] = -2.5; 79 Sign[i] = +1; 80 } 81 82 } 83 84 lastTime = time; 85 86 glutPostRedisplay(); 87} 88 89 90static void Display( void ) 91{ 92 int i; 93 94 glClearColor(0.25, 0.25, 0.25, 0.0); 95 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 96 97 glMatrixMode( GL_PROJECTION ); 98 glLoadIdentity(); 99 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); 100 glMatrixMode( GL_MODELVIEW ); 101 glLoadIdentity(); 102 glTranslatef( 0.0, 0.0, -15.0 ); 103 104 /* draw the occluding polygons */ 105 glColor3f(0, 0.4, 0.6); 106 glBegin(GL_QUADS); 107 glVertex2f(-1.6, -2.5); 108 glVertex2f(-0.4, -2.5); 109 glVertex2f(-0.4, 2.5); 110 glVertex2f(-1.6, 2.5); 111 glVertex2f( 0.4, -2.5); 112 glVertex2f( 1.6, -2.5); 113 glVertex2f( 1.6, 2.5); 114 glVertex2f( 0.4, 2.5); 115 glEnd(); 116 117 118 glColorMask(0, 0, 0, 0); 119 glDepthMask(GL_FALSE); 120 121 /* draw the test polygons with occlusion testing */ 122 for (i = 0; i < NUM_OCC; i++) { 123 glPushMatrix(); 124 glTranslatef(Xpos[i], Ypos[i], -0.5); 125 glScalef(0.2, 0.2, 1.0); 126 glRotatef(-90.0 * Xpos[i], 0, 0, 1); 127 128 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery[i]); 129 glBegin(GL_POLYGON); 130 glVertex3f(-1, -1, 0); 131 glVertex3f( 1, -1, 0); 132 glVertex3f( 1, 1, 0); 133 glVertex3f(-1, 1, 0); 134 glEnd(); 135 glEndQueryARB(GL_SAMPLES_PASSED_ARB); 136 137 glPopMatrix(); 138 } 139 140 glColorMask(1, 1, 1, 1); 141 glDepthMask(GL_TRUE); 142 143 /* Draw the rectangles now. 144 * Draw orange if result was ready 145 * Draw red if result was not ready. 146 */ 147 for (i = 0; i < NUM_OCC; i++) { 148 GLuint passed; 149 GLint ready; 150 151 glGetQueryObjectivARB(OccQuery[i], GL_QUERY_RESULT_AVAILABLE_ARB, &ready); 152 153 glGetQueryObjectuivARB(OccQuery[i], GL_QUERY_RESULT_ARB, &passed); 154 155 if (!ready) 156 glColor3f(1, 0, 0); 157 else 158 glColor3f(0.8, 0.5, 0); 159 160 if (!ready || passed) { 161 glPushMatrix(); 162 glTranslatef(Xpos[i], Ypos[i], -0.5); 163 glScalef(0.2, 0.2, 1.0); 164 glRotatef(-90.0 * Xpos[i], 0, 0, 1); 165 166 glBegin(GL_POLYGON); 167 glVertex3f(-1, -1, 0); 168 glVertex3f( 1, -1, 0); 169 glVertex3f( 1, 1, 0); 170 glVertex3f(-1, 1, 0); 171 glEnd(); 172 173 glPopMatrix(); 174 } 175 176 { 177 char s[10]; 178 glRasterPos3f(0.45, Ypos[i], 1.0); 179 sprintf(s, "%4d", passed); 180 PrintString(s); 181 } 182 } 183 184 glutSwapBuffers(); 185} 186 187 188static void Reshape( int width, int height ) 189{ 190 glViewport( 0, 0, width, height ); 191} 192 193 194static void Key( unsigned char key, int x, int y ) 195{ 196 (void) x; 197 (void) y; 198 switch (key) { 199 case 27: 200 glutDestroyWindow(Win); 201 exit(0); 202 break; 203 case ' ': 204 Anim = !Anim; 205 if (Anim) 206 glutIdleFunc(Idle); 207 else 208 glutIdleFunc(NULL); 209 break; 210 } 211 glutPostRedisplay(); 212} 213 214 215static void SpecialKey( int key, int x, int y ) 216{ 217 const GLfloat step = 0.1; 218 int i; 219 (void) x; 220 (void) y; 221 switch (key) { 222 case GLUT_KEY_LEFT: 223 for (i = 0; i < NUM_OCC; i++) 224 Xpos[i] -= step; 225 break; 226 case GLUT_KEY_RIGHT: 227 for (i = 0; i < NUM_OCC; i++) 228 Xpos[i] += step; 229 break; 230 } 231 glutPostRedisplay(); 232} 233 234 235static void Init( void ) 236{ 237 const char *ext = (const char *) glGetString(GL_EXTENSIONS); 238 GLint bits; 239 int i; 240 241 if (!strstr(ext, "GL_ARB_occlusion_query")) { 242 printf("Sorry, this demo requires the GL_ARB_occlusion_query extension\n"); 243 exit(-1); 244 } 245 246 glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &bits); 247 if (!bits) { 248 printf("Hmmm, GL_QUERY_COUNTER_BITS_ARB is zero!\n"); 249 exit(-1); 250 } 251 252 glGetIntegerv(GL_DEPTH_BITS, &bits); 253 printf("Depthbits: %d\n", bits); 254 255 glGenQueriesARB(NUM_OCC, OccQuery); 256 257 glEnable(GL_DEPTH_TEST); 258 259 for (i = 0; i < NUM_OCC; i++) { 260 float t = (float) i / (NUM_OCC - 1); 261 Xpos[i] = 2.5 * t; 262 Ypos[i] = 4.0 * (t - 0.5); 263 Sign[i] = 1.0; 264 } 265 266} 267 268 269int main( int argc, char *argv[] ) 270{ 271 glutInitWindowSize( 400, 400 ); 272 glutInit( &argc, argv ); 273 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 274 Win = glutCreateWindow(argv[0]); 275 glewInit(); 276 glutReshapeFunc( Reshape ); 277 glutKeyboardFunc( Key ); 278 glutSpecialFunc( SpecialKey ); 279 if (Anim) 280 glutIdleFunc(Idle); 281 else 282 glutIdleFunc(NULL); 283 glutDisplayFunc( Display ); 284 Init(); 285 glutMainLoop(); 286 return 0; 287} 288