s/DP4/DP3/
[mesa.git] / progs / demos / arbocclude.c
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 #define GL_GLEXT_PROTOTYPES
33 #include <GL/glut.h>
34
35
36 static GLboolean Anim = GL_TRUE;
37 static GLfloat Xpos = 0;
38 static GLuint OccQuery;
39
40
41
42 static void
43 PrintString(const char *s)
44 {
45 while (*s) {
46 glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
47 s++;
48 }
49 }
50
51
52
53 static void Idle(void)
54 {
55 static int lastTime = 0;
56 static int sign = +1;
57 int time = glutGet(GLUT_ELAPSED_TIME);
58 float step;
59
60 if (lastTime == 0)
61 lastTime = time;
62 else if (time - lastTime < 20) /* 50Hz update */
63 return;
64
65 step = (time - lastTime) / 1000.0 * sign;
66 lastTime = time;
67
68 Xpos += step;
69
70 if (Xpos > 2.5) {
71 Xpos = 2.5;
72 sign = -1;
73 }
74 else if (Xpos < -2.5) {
75 Xpos = -2.5;
76 sign = +1;
77 }
78 glutPostRedisplay();
79 }
80
81
82 static void Display( void )
83 {
84 GLuint passed;
85 GLint ready;
86 char s[100];
87
88 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
89
90 glMatrixMode( GL_PROJECTION );
91 glLoadIdentity();
92 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
93 glMatrixMode( GL_MODELVIEW );
94 glLoadIdentity();
95 glTranslatef( 0.0, 0.0, -15.0 );
96
97 /* draw the occluding polygons */
98 glColor3f(0, 0.6, 0.8);
99 glBegin(GL_QUADS);
100 glVertex2f(-1.6, -1.5);
101 glVertex2f(-0.4, -1.5);
102 glVertex2f(-0.4, 1.5);
103 glVertex2f(-1.6, 1.5);
104
105 glVertex2f( 0.4, -1.5);
106 glVertex2f( 1.6, -1.5);
107 glVertex2f( 1.6, 1.5);
108 glVertex2f( 0.4, 1.5);
109 glEnd();
110
111 /* draw the test polygon with occlusion testing */
112 glPushMatrix();
113 glTranslatef(Xpos, 0, -0.5);
114 glScalef(0.3, 0.3, 1.0);
115 glRotatef(-90.0 * Xpos, 0, 0, 1);
116
117 glBeginQueryARB(GL_SAMPLES_PASSED_ARB, OccQuery);
118
119 glColorMask(0, 0, 0, 0);
120 glDepthMask(GL_FALSE);
121
122 glBegin(GL_POLYGON);
123 glVertex3f(-1, -1, 0);
124 glVertex3f( 1, -1, 0);
125 glVertex3f( 1, 1, 0);
126 glVertex3f(-1, 1, 0);
127 glEnd();
128
129 glEndQueryARB(GL_SAMPLES_PASSED_ARB);
130
131 do {
132 /* do useful work here, if any */
133 glGetQueryObjectivARB(OccQuery, GL_QUERY_RESULT_AVAILABLE_ARB, &ready);
134 } while (!ready);
135 glGetQueryObjectuivARB(OccQuery, GL_QUERY_RESULT_ARB, &passed);
136
137 /* turn off occlusion testing */
138 glColorMask(1, 1, 1, 1);
139 glDepthMask(GL_TRUE);
140
141 /* draw the orange rect, so we can see what's going on */
142 glColor3f(0.8, 0.5, 0);
143 glBegin(GL_POLYGON);
144 glVertex3f(-1, -1, 0);
145 glVertex3f( 1, -1, 0);
146 glVertex3f( 1, 1, 0);
147 glVertex3f(-1, 1, 0);
148 glEnd();
149
150 glPopMatrix();
151
152
153 /* Print result message */
154 glMatrixMode( GL_PROJECTION );
155 glLoadIdentity();
156 glOrtho( -1.0, 1.0, -1.0, 1.0, -1.0, 1.0 );
157 glMatrixMode( GL_MODELVIEW );
158 glLoadIdentity();
159
160 glColor3f(1, 1, 1);
161 sprintf(s, " %4d Fragments Visible", passed);
162 glRasterPos3f(-0.50, -0.7, 0);
163 PrintString(s);
164 if (!passed) {
165 glRasterPos3f(-0.25, -0.8, 0);
166 PrintString("Fully Occluded");
167 }
168
169 glutSwapBuffers();
170 }
171
172
173 static void Reshape( int width, int height )
174 {
175 glViewport( 0, 0, width, height );
176 }
177
178
179 static void Key( unsigned char key, int x, int y )
180 {
181 (void) x;
182 (void) y;
183 switch (key) {
184 case 27:
185 exit(0);
186 break;
187 case ' ':
188 Anim = !Anim;
189 if (Anim)
190 glutIdleFunc(Idle);
191 else
192 glutIdleFunc(NULL);
193 break;
194 }
195 glutPostRedisplay();
196 }
197
198
199 static void SpecialKey( int key, int x, int y )
200 {
201 const GLfloat step = 0.1;
202 (void) x;
203 (void) y;
204 switch (key) {
205 case GLUT_KEY_LEFT:
206 Xpos -= step;
207 break;
208 case GLUT_KEY_RIGHT:
209 Xpos += step;
210 break;
211 }
212 glutPostRedisplay();
213 }
214
215
216 static void Init( void )
217 {
218 const char *ext = (const char *) glGetString(GL_EXTENSIONS);
219 GLint bits;
220
221 if (!strstr(ext, "GL_ARB_occlusion_query")) {
222 printf("Sorry, this demo requires the GL_ARB_occlusion_query extension\n");
223 exit(-1);
224 }
225
226 glGetQueryivARB(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB, &bits);
227 if (!bits) {
228 printf("Hmmm, GL_QUERY_COUNTER_BITS_ARB is zero!\n");
229 exit(-1);
230 }
231
232 glGenQueriesARB(1, &OccQuery);
233 assert( glIsQueryARB(OccQuery) );
234
235 glEnable(GL_DEPTH_TEST);
236 }
237
238
239 int main( int argc, char *argv[] )
240 {
241 glutInit( &argc, argv );
242 glutInitWindowPosition( 0, 0 );
243 glutInitWindowSize( 400, 400 );
244 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
245 glutCreateWindow(argv[0]);
246 glutReshapeFunc( Reshape );
247 glutKeyboardFunc( Key );
248 glutSpecialFunc( SpecialKey );
249 glutIdleFunc( Idle );
250 glutDisplayFunc( Display );
251 Init();
252 glutMainLoop();
253 return 0;
254 }