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