1/* 2 * GL_ARB_occlusion_query(2) 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 * Enhanced by Dave Airlie to add ARB_occlusion_query2 27 */ 28 29#include <assert.h> 30#include <stdio.h> 31#include <stdlib.h> 32#include <string.h> 33#include <math.h> 34#include <GL/glew.h> 35#include "glut_wrap.h" 36 37static GLboolean Anim = GL_TRUE; 38static GLfloat Xpos = 0; 39static GLuint OccQuery1; 40#if defined(GL_ARB_occlusion_query2) 41static GLuint OccQuery2; 42#endif 43static GLint Win = 0; 44static GLboolean has_oq2 = GL_FALSE; 45 46 47static void 48PrintString(const char *s) 49{ 50 while (*s) { 51 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); 52 s++; 53 } 54} 55 56 57 58static void Idle(void) 59{ 60 static int lastTime = 0; 61 static int sign = +1; 62 int time = glutGet(GLUT_ELAPSED_TIME); 63 float step; 64 65 if (lastTime == 0) 66 lastTime = time; 67 else if (time - lastTime < 20) /* 50Hz update */ 68 return; 69 70 step = (time - lastTime) / 1000.0 * sign; 71 lastTime = time; 72 73 Xpos += step; 74 75 if (Xpos > 2.5) { 76 Xpos = 2.5; 77 sign = -1; 78 } 79 else if (Xpos < -2.5) { 80 Xpos = -2.5; 81 sign = +1; 82 } 83 glutPostRedisplay(); 84} 85 86 87static void Display( void ) 88{ 89 GLuint passed1; 90#if defined(GL_ARB_occlusion_query2) 91 GLuint passed2_boolean; 92#endif 93 GLint ready; 94 char s[100]; 95 96 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 97 98 glMatrixMode( GL_PROJECTION ); 99 glLoadIdentity(); 100 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 ); 101 glMatrixMode( GL_MODELVIEW ); 102 glLoadIdentity(); 103 glTranslatef( 0.0, 0.0, -15.0 ); 104 105 /* draw the occluding polygons */ 106 glColor3f(0, 0.6, 0.8); 107 glBegin(GL_QUADS); 108 glVertex2f(-1.6, -1.5); 109 glVertex2f(-0.4, -1.5); 110 glVertex2f(-0.4, 1.5); 111 glVertex2f(-1.6, 1.5); 112 113 glVertex2f( 0.4, -1.5); 114 glVertex2f( 1.6, -1.5); 115 glVertex2f( 1.6, 1.5); 116 glVertex2f( 0.4, 1.5); 117 glEnd(); 118 119#if defined(GL_ARB_occlusion_query) 120 /* disable all buffer updates */ 121 glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); 122 glDepthMask(GL_FALSE); 123 124 /* draw the first polygon with occlusion testing */ 125 glPushMatrix(); 126 glTranslatef(Xpos, 0.4, -0.5); 127 glScalef(0.3, 0.3, 1.0); 128 glRotatef(-90.0 * Xpos, 0, 0, 1); 129 130 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery1); 131 132 glBegin(GL_POLYGON); 133 glVertex3f(-1, -1, 0); 134 glVertex3f( 1, -1, 0); 135 glVertex3f( 1, 1, 0); 136 glVertex3f(-1, 1, 0); 137 glEnd(); 138 139 glEndQueryARB(GL_SAMPLES_PASSED_ARB); 140 glPopMatrix(); 141#endif 142 143 /* draw the second polygon with occlusion testing */ 144 glPushMatrix(); 145 glTranslatef(Xpos, -0.4, -0.5); 146 glScalef(0.3, 0.3, 1.0); 147#if defined(GL_ARB_occlusion_query2) 148 if (has_oq2) { 149 glBeginQueryARB(GL_ANY_SAMPLES_PASSED, OccQuery2); 150 151 glBegin(GL_POLYGON); 152 glVertex3f(-1, -1, 0); 153 glVertex3f( 1, -1, 0); 154 glVertex3f( 1, 1, 0); 155 glVertex3f(-1, 1, 0); 156 glEnd(); 157 158 glEndQueryARB(GL_ANY_SAMPLES_PASSED); 159 } 160#endif 161 162 /* re-enable buffer updates */ 163 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); 164 glDepthMask(GL_TRUE); 165 166#if defined(GL_ARB_occlusion_query) 167 do { 168 /* do useful work here, if any */ 169 glGetQueryObjectivARB(OccQuery1, GL_QUERY_RESULT_AVAILABLE_ARB, &ready); 170 } while (!ready); 171 glGetQueryObjectuivARB(OccQuery1, GL_QUERY_RESULT_ARB, &passed1); 172#endif 173#if defined(GL_ARB_occlusion_query2) 174 if (has_oq2) { 175 do { 176 /* do useful work here, if any */ 177 glGetQueryObjectivARB(OccQuery2, GL_QUERY_RESULT_AVAILABLE_ARB, &ready); 178 } while (!ready); 179 glGetQueryObjectuivARB(OccQuery2, GL_QUERY_RESULT_ARB, &passed2_boolean); 180 } 181#endif /* GL_ARB_occlusion_query2 */ 182 183 /* draw the second rect, so we can see what's going on */ 184 glColor3f(0.8, 0.5, 0); 185 if (has_oq2) { 186 glBegin(GL_POLYGON); 187 glVertex3f(-1, -1, 0); 188 glVertex3f( 1, -1, 0); 189 glVertex3f( 1, 1, 0); 190 glVertex3f(-1, 1, 0); 191 glEnd(); 192 } 193 glPopMatrix(); 194 195 glPushMatrix(); 196 glTranslatef(Xpos, 0.4, -0.5); 197 glScalef(0.3, 0.3, 1.0); 198 glRotatef(-90.0 * Xpos, 0, 0, 1); 199 200 /* draw the first rect, so we can see what's going on */ 201 glBegin(GL_POLYGON); 202 glVertex3f(-1, -1, 0); 203 glVertex3f( 1, -1, 0); 204 glVertex3f( 1, 1, 0); 205 glVertex3f(-1, 1, 0); 206 glEnd(); 207 glPopMatrix(); 208 209 /* Print result message */ 210 glMatrixMode( GL_PROJECTION ); 211 glLoadIdentity(); 212 glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 ); 213 glMatrixMode( GL_MODELVIEW ); 214 glLoadIdentity(); 215 216 glColor3f(1, 1, 1); 217#if defined(GL_ARB_occlusion_query) 218 sprintf(s, " %4d Fragments Visible", passed1); 219 glRasterPos3f(-0.50, -0.6, 0); 220 PrintString(s); 221 if (!passed1) { 222 glRasterPos3f(-0.25, -0.7, 0); 223 PrintString("Fully Occluded"); 224 } 225#if defined(GL_ARB_occlusion_query2) 226 if (has_oq2) { 227 glRasterPos3f(-0.25, -0.9, 0); 228 if (!passed2_boolean) { 229 PrintString("Fully Occluded"); 230 } else { 231 PrintString("Partly Visible"); 232 } 233 } 234#endif 235#else 236 glRasterPos3f(-0.25, -0.8, 0); 237 PrintString("GL_ARB_occlusion_query not available at compile time"); 238#endif /* GL_ARB_occlusion_query */ 239 240 glutSwapBuffers(); 241} 242 243 244static void Reshape( int width, int height ) 245{ 246 glViewport( 0, 0, width, height ); 247} 248 249 250static void Key( unsigned char key, int x, int y ) 251{ 252 (void) x; 253 (void) y; 254 switch (key) { 255 case 27: 256 glutDestroyWindow(Win); 257 exit(0); 258 break; 259 case ' ': 260 Anim = !Anim; 261 if (Anim) 262 glutIdleFunc(Idle); 263 else 264 glutIdleFunc(NULL); 265 break; 266 } 267 glutPostRedisplay(); 268} 269 270 271static void SpecialKey( int key, int x, int y ) 272{ 273 const GLfloat step = 0.1; 274 (void) x; 275 (void) y; 276 switch (key) { 277 case GLUT_KEY_LEFT: 278 Xpos -= step; 279 break; 280 case GLUT_KEY_RIGHT: 281 Xpos += step; 282 break; 283 } 284 glutPostRedisplay(); 285} 286 287 288static void Init( void ) 289{ 290 const char *ext = (const char *) glGetString(GL_EXTENSIONS); 291 GLint bits; 292 293 if (!strstr(ext, "GL_ARB_occlusion_query")) { 294 printf("Sorry, this demo requires the GL_ARB_occlusion_query extension\n"); 295 exit(-1); 296 } 297 298 if (strstr(ext, "GL_ARB_occlusion_query2")) { 299 has_oq2 = GL_TRUE; 300 printf("OQ2 supported\n"); 301 } 302#if defined(GL_ARB_occlusion_query) 303 glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &bits); 304 if (!bits) { 305 printf("Hmmm, GL_QUERY_COUNTER_BITS_ARB is zero!\n"); 306 exit(-1); 307 } 308#endif /* GL_ARB_occlusion_query */ 309 310 glGetIntegerv(GL_DEPTH_BITS, &bits); 311 printf("Depthbits: %d\n", bits); 312 313#if defined(GL_ARB_occlusion_query) 314 glGenQueriesARB(1, &OccQuery1); 315 assert(OccQuery1 > 0); 316#if defined(GL_ARB_occlusion_query2) 317 if (has_oq2) { 318 glGenQueriesARB(1, &OccQuery2); 319 assert(OccQuery2 > 0); 320 } 321#endif 322#endif /* GL_ARB_occlusion_query */ 323 324 glEnable(GL_DEPTH_TEST); 325} 326 327 328int main( int argc, char *argv[] ) 329{ 330 glutInitWindowSize( 400, 400 ); 331 glutInit( &argc, argv ); 332 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 333 Win = glutCreateWindow(argv[0]); 334 glewInit(); 335 glutReshapeFunc( Reshape ); 336 glutKeyboardFunc( Key ); 337 glutSpecialFunc( SpecialKey ); 338 glutIdleFunc( Idle ); 339 glutDisplayFunc( Display ); 340 Init(); 341 glutMainLoop(); 342 return 0; 343} 344