Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / progs / tests / bufferobj.c
1 /*
2 * Test GL_ARB_vertex_buffer_object
3 *
4 * Brian Paul
5 * 16 Sep 2003
6 */
7
8
9 #define GL_GLEXT_PROTOTYPES
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <GL/glut.h>
15
16 #define NUM_OBJECTS 10
17
18 struct object
19 {
20 GLuint BufferID;
21 GLuint ElementsBufferID;
22 GLuint NumVerts;
23 GLuint VertexOffset;
24 GLuint ColorOffset;
25 GLuint NumElements;
26 };
27
28 static struct object Objects[NUM_OBJECTS];
29 static GLuint NumObjects;
30
31 static GLuint Win;
32
33 static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
34 static GLboolean Anim = GL_TRUE;
35
36
37 static void CheckError(int line)
38 {
39 GLenum err = glGetError();
40 if (err) {
41 printf("GL Error 0x%x at line %d\n", (int) err, line);
42 }
43 }
44
45
46 static void DrawObject( const struct object *obj )
47 {
48 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
49 glVertexPointer(3, GL_FLOAT, 0, (void *) obj->VertexOffset);
50 glEnable(GL_VERTEX_ARRAY);
51
52 /* test push/pop attrib */
53 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
54 #if 0
55 if (1)
56 {
57 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
58 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
59 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 999999);
60 glPopClientAttrib();
61 }
62 #endif
63 glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset);
64 glEnable(GL_COLOR_ARRAY);
65
66 if (obj->NumElements > 0) {
67 /* indexed arrays */
68 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
69 glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL);
70 }
71 else {
72 /* non-indexed arrays */
73 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
74 glDrawArrays(GL_LINE_LOOP, 0, obj->NumVerts);
75 }
76 }
77
78
79 static void Idle( void )
80 {
81 Zrot = 0.05 * glutGet(GLUT_ELAPSED_TIME);
82 glutPostRedisplay();
83 }
84
85
86 static void Display( void )
87 {
88 int i;
89
90 glClear( GL_COLOR_BUFFER_BIT );
91
92 for (i = 0; i < NumObjects; i++) {
93 float x = 5.0 * ((float) i / (NumObjects-1) - 0.5);
94 glPushMatrix();
95 glTranslatef(x, 0, 0);
96 glRotatef(Xrot, 1, 0, 0);
97 glRotatef(Yrot, 0, 1, 0);
98 glRotatef(Zrot, 0, 0, 1);
99
100 DrawObject(Objects + i);
101
102 glPopMatrix();
103 }
104
105 CheckError(__LINE__);
106 glutSwapBuffers();
107 }
108
109
110 static void Reshape( int width, int height )
111 {
112 float ar = (float) width / (float) height;
113 glViewport( 0, 0, width, height );
114 glMatrixMode( GL_PROJECTION );
115 glLoadIdentity();
116 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
117 glMatrixMode( GL_MODELVIEW );
118 glLoadIdentity();
119 glTranslatef( 0.0, 0.0, -15.0 );
120 }
121
122
123 static void FreeBuffers(void)
124 {
125 int i;
126 for (i = 0; i < NUM_OBJECTS; i++)
127 glDeleteBuffersARB(1, &Objects[i].BufferID);
128 }
129
130
131 static void Key( unsigned char key, int x, int y )
132 {
133 const GLfloat step = 3.0;
134 (void) x;
135 (void) y;
136 switch (key) {
137 case 'a':
138 Anim = !Anim;
139 if (Anim)
140 glutIdleFunc(Idle);
141 else
142 glutIdleFunc(NULL);
143 break;
144 case 'z':
145 Zrot -= step;
146 break;
147 case 'Z':
148 Zrot += step;
149 break;
150 case 27:
151 FreeBuffers();
152 glutDestroyWindow(Win);
153 exit(0);
154 break;
155 }
156 glutPostRedisplay();
157 }
158
159
160 static void SpecialKey( int key, int x, int y )
161 {
162 const GLfloat step = 3.0;
163 (void) x;
164 (void) y;
165 switch (key) {
166 case GLUT_KEY_UP:
167 Xrot -= step;
168 break;
169 case GLUT_KEY_DOWN:
170 Xrot += step;
171 break;
172 case GLUT_KEY_LEFT:
173 Yrot -= step;
174 break;
175 case GLUT_KEY_RIGHT:
176 Yrot += step;
177 break;
178 }
179 glutPostRedisplay();
180 }
181
182
183
184 static void MakeObject1(struct object *obj)
185 {
186 GLfloat *v, *c;
187 void *p;
188 int i;
189 GLubyte buffer[500];
190
191 for (i = 0; i < 500; i++)
192 buffer[i] = i & 0xff;
193
194 obj->BufferID = 0;
195 glGenBuffersARB(1, &obj->BufferID);
196 assert(obj->BufferID != 0);
197 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
198 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 500, buffer, GL_STATIC_DRAW_ARB);
199
200 for (i = 0; i < 500; i++)
201 buffer[i] = 0;
202
203 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 500, buffer);
204
205 for (i = 0; i < 500; i++)
206 assert(buffer[i] == (i & 0xff));
207
208 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
209 assert(!i);
210
211 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
212
213 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
214
215 /* do some sanity tests */
216 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
217 assert(p == v);
218
219 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
220 assert(i == 500);
221
222 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
223 assert(i == GL_STATIC_DRAW_ARB);
224
225 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
226 assert(i == GL_WRITE_ONLY_ARB);
227
228 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
229 assert(i);
230
231 /* Make rectangle */
232 v[0] = -1; v[1] = -1; v[2] = 0;
233 v[3] = 1; v[4] = -1; v[5] = 0;
234 v[6] = 1; v[7] = 1; v[8] = 0;
235 v[9] = -1; v[10] = 1; v[11] = 0;
236 c = v + 12;
237 c[0] = 1; c[1] = 0; c[2] = 0;
238 c[3] = 1; c[4] = 0; c[5] = 0;
239 c[6] = 1; c[7] = 0; c[8] = 1;
240 c[9] = 1; c[10] = 0; c[11] = 1;
241 obj->NumVerts = 4;
242 obj->VertexOffset = 0;
243 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
244 obj->NumElements = 0;
245
246 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
247
248 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
249 assert(!p);
250
251 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
252 assert(!i);
253 }
254
255
256 static void MakeObject2(struct object *obj)
257 {
258 GLfloat *v, *c;
259
260 glGenBuffersARB(1, &obj->BufferID);
261 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
262 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
263 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
264
265 /* Make triangle */
266 v[0] = -1; v[1] = -1; v[2] = 0;
267 v[3] = 1; v[4] = -1; v[5] = 0;
268 v[6] = 0; v[7] = 1; v[8] = 0;
269 c = v + 9;
270 c[0] = 0; c[1] = 1; c[2] = 0;
271 c[3] = 0; c[4] = 1; c[5] = 0;
272 c[6] = 1; c[7] = 1; c[8] = 0;
273 obj->NumVerts = 3;
274 obj->VertexOffset = 0;
275 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
276 obj->NumElements = 0;
277
278 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
279 }
280
281
282 static void MakeObject3(struct object *obj)
283 {
284 GLfloat vertexData[1000];
285 GLfloat *v, *c;
286 GLuint *i;
287 int bytes;
288
289 /* Make rectangle */
290 v = vertexData;
291 v[0] = -1; v[1] = -0.5; v[2] = 0;
292 v[3] = 1; v[4] = -0.5; v[5] = 0;
293 v[6] = 1; v[7] = 0.5; v[8] = 0;
294 v[9] = -1; v[10] = 0.5; v[11] = 0;
295 c = vertexData + 12;
296 c[0] = 0; c[1] = 0; c[2] = 1;
297 c[3] = 0; c[4] = 0; c[5] = 1;
298 c[6] = 0; c[7] = 1; c[8] = 1;
299 c[9] = 0; c[10] = 1; c[11] = 1;
300 obj->NumVerts = 4;
301 obj->VertexOffset = 0;
302 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
303
304 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
305
306 /* Don't use glMap/UnmapBuffer for this object */
307 glGenBuffersARB(1, &obj->BufferID);
308 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
309 glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, vertexData, GL_STATIC_DRAW_ARB);
310
311 /* Setup a buffer of indices to test the ELEMENTS path */
312 glGenBuffersARB(1, &obj->ElementsBufferID);
313 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
314 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 100, NULL, GL_STATIC_DRAW_ARB);
315 i = (GLuint *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
316 i[0] = 0;
317 i[1] = 1;
318 i[2] = 2;
319 i[3] = 3;
320 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
321 obj->NumElements = 4;
322 }
323
324
325
326 static void Init( void )
327 {
328 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
329 printf("GL_ARB_vertex_buffer_object not found!\n");
330 exit(0);
331 }
332 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
333
334 /* Test buffer object deletion */
335 if (1) {
336 static GLubyte data[1000];
337 GLuint id = 999;
338 glBindBufferARB(GL_ARRAY_BUFFER_ARB, id);
339 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, data, GL_STATIC_DRAW_ARB);
340 glVertexPointer(3, GL_FLOAT, 0, (void *) 0);
341 glDeleteBuffersARB(1, &id);
342 assert(!glIsBufferARB(id));
343 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
344 glVertexPointer(3, GL_FLOAT, 0, (void *) 0);
345 assert(!glIsBufferARB(id));
346 }
347
348 MakeObject1(Objects + 0);
349 MakeObject2(Objects + 1);
350 MakeObject3(Objects + 2);
351 NumObjects = 3;
352 }
353
354
355 int main( int argc, char *argv[] )
356 {
357 glutInit( &argc, argv );
358 glutInitWindowPosition( 0, 0 );
359 glutInitWindowSize( 600, 300 );
360 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
361 Win = glutCreateWindow(argv[0]);
362 glutReshapeFunc( Reshape );
363 glutKeyboardFunc( Key );
364 glutSpecialFunc( SpecialKey );
365 glutDisplayFunc( Display );
366 if (Anim)
367 glutIdleFunc(Idle);
368 Init();
369 glutMainLoop();
370 return 0;
371 }