2 * Test GL_ARB_vertex_buffer_object
9 #define GL_GLEXT_PROTOTYPES
16 #define NUM_OBJECTS 10
20 GLuint VertexBufferID
;
22 GLuint ElementsBufferID
;
31 static struct object Objects
[NUM_OBJECTS
];
32 static GLuint NumObjects
;
36 static GLfloat Xrot
= 0, Yrot
= 0, Zrot
= 0;
37 static GLboolean Anim
= GL_TRUE
;
40 static void CheckError(int line
)
42 GLenum err
= glGetError();
44 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
49 static void DrawObject( const struct object
*obj
)
51 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->VertexBufferID
);
52 glVertexPointer(3, GL_FLOAT
, obj
->VertexStride
, (void *) obj
->VertexOffset
);
53 glEnable(GL_VERTEX_ARRAY
);
55 /* test push/pop attrib */
56 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
60 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
61 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
62 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 999999);
66 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->ColorBufferID
);
67 glColorPointer(3, GL_FLOAT
, obj
->ColorStride
, (void *) obj
->ColorOffset
);
68 glEnable(GL_COLOR_ARRAY
);
70 if (obj
->NumElements
> 0) {
72 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
73 glDrawElements(GL_LINE_LOOP
, obj
->NumElements
, GL_UNSIGNED_INT
, NULL
);
76 /* non-indexed arrays */
77 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 0);
78 glDrawArrays(GL_LINE_LOOP
, 0, obj
->NumVerts
);
83 static void Idle( void )
85 Zrot
= 0.05 * glutGet(GLUT_ELAPSED_TIME
);
90 static void Display( void )
94 glClear( GL_COLOR_BUFFER_BIT
);
96 for (i
= 0; i
< NumObjects
; i
++) {
97 float x
= 7.0 * ((float) i
/ (NumObjects
-1) - 0.5);
99 glTranslatef(x
, 0, 0);
100 glRotatef(Xrot
, 1, 0, 0);
101 glRotatef(Yrot
, 0, 1, 0);
102 glRotatef(Zrot
, 0, 0, 1);
104 DrawObject(Objects
+ i
);
109 CheckError(__LINE__
);
114 static void Reshape( int width
, int height
)
116 float ar
= (float) width
/ (float) height
;
117 glViewport( 0, 0, width
, height
);
118 glMatrixMode( GL_PROJECTION
);
120 glFrustum( -ar
, ar
, -1.0, 1.0, 5.0, 25.0 );
121 glMatrixMode( GL_MODELVIEW
);
123 glTranslatef( 0.0, 0.0, -15.0 );
127 static void FreeBuffers(void)
130 for (i
= 0; i
< NUM_OBJECTS
; i
++) {
131 glDeleteBuffersARB(1, &Objects
[i
].VertexBufferID
);
132 glDeleteBuffersARB(1, &Objects
[i
].ColorBufferID
);
133 glDeleteBuffersARB(1, &Objects
[i
].ElementsBufferID
);
138 static void Key( unsigned char key
, int x
, int y
)
140 const GLfloat step
= 3.0;
159 glutDestroyWindow(Win
);
167 static void SpecialKey( int key
, int x
, int y
)
169 const GLfloat step
= 3.0;
191 * Non-interleaved position/color data.
193 static void MakeObject1(struct object
*obj
)
200 for (i
= 0; i
< 500; i
++)
201 buffer
[i
] = i
& 0xff;
203 obj
->VertexBufferID
= 0;
204 glGenBuffersARB(1, &obj
->VertexBufferID
);
205 obj
->ColorBufferID
= obj
->VertexBufferID
;
206 assert(obj
->VertexBufferID
!= 0);
207 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->VertexBufferID
);
208 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 500, buffer
, GL_STATIC_DRAW_ARB
);
210 for (i
= 0; i
< 500; i
++)
213 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0, 500, buffer
);
215 for (i
= 0; i
< 500; i
++)
216 assert(buffer
[i
] == (i
& 0xff));
218 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
221 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
223 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
225 /* do some sanity tests */
226 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
229 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_SIZE_ARB
, &i
);
232 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
233 assert(i
== GL_STATIC_DRAW_ARB
);
235 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_ACCESS_ARB
, &i
);
236 assert(i
== GL_WRITE_ONLY_ARB
);
238 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
242 v
[0] = -1; v
[1] = -1; v
[2] = 0;
243 v
[3] = 1; v
[4] = -1; v
[5] = 0;
244 v
[6] = 1; v
[7] = 1; v
[8] = 0;
245 v
[9] = -1; v
[10] = 1; v
[11] = 0;
247 c
[0] = 1; c
[1] = 0; c
[2] = 0;
248 c
[3] = 1; c
[4] = 0; c
[5] = 0;
249 c
[6] = 1; c
[7] = 0; c
[8] = 1;
250 c
[9] = 1; c
[10] = 0; c
[11] = 1;
252 obj
->VertexOffset
= 0;
253 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
254 obj
->VertexStride
= 0;
255 obj
->ColorStride
= 0;
256 obj
->NumElements
= 0;
258 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
260 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
263 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
269 * Interleaved position/color data.
271 static void MakeObject2(struct object
*obj
)
274 int start
= 40; /* bytes, to test non-zero array offsets */
276 glGenBuffersARB(1, &obj
->VertexBufferID
);
277 obj
->ColorBufferID
= obj
->VertexBufferID
;
279 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->VertexBufferID
);
280 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 1000, NULL
, GL_STATIC_DRAW_ARB
);
281 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
283 v
+= start
/ sizeof(GLfloat
);
285 /* Make triangle: interleaved colors, then positions */
287 v
[0] = 0; v
[1] = 1; v
[2] = 0; v
[3] = -1; v
[4] = -1; v
[5] = 0;
288 v
[6] = 0; v
[7] = 1; v
[8] = 0; v
[9] = 1; v
[10] = -1; v
[11] = 0;
289 v
[12] = 1; v
[13] = 1; v
[14] = 0; v
[15] = 0; v
[16] = 1; v
[17] = 0;
292 obj
->VertexOffset
= start
+ 3 * sizeof(GLfloat
);
293 obj
->ColorOffset
= start
;
294 obj
->VertexStride
= 6 * sizeof(GLfloat
);
295 obj
->ColorStride
= 6 * sizeof(GLfloat
);
297 obj
->NumElements
= 0;
299 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
304 * Use an index buffer and glDrawElements().
306 static void MakeObject3(struct object
*obj
)
308 GLfloat vertexData
[1000];
315 v
[0] = -1; v
[1] = -0.5; v
[2] = 0;
316 v
[3] = 1; v
[4] = -0.5; v
[5] = 0;
317 v
[6] = 1; v
[7] = 0.5; v
[8] = 0;
318 v
[9] = -1; v
[10] = 0.5; v
[11] = 0;
320 c
[0] = 0; c
[1] = 0; c
[2] = 1;
321 c
[3] = 0; c
[4] = 0; c
[5] = 1;
322 c
[6] = 0; c
[7] = 1; c
[8] = 1;
323 c
[9] = 0; c
[10] = 1; c
[11] = 1;
325 obj
->VertexOffset
= 0;
326 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
327 obj
->VertexStride
= 0;
328 obj
->ColorStride
= 0;
330 bytes
= obj
->NumVerts
* (3 + 3) * sizeof(GLfloat
);
332 /* Don't use glMap/UnmapBuffer for this object */
333 glGenBuffersARB(1, &obj
->VertexBufferID
);
334 obj
->ColorBufferID
= obj
->VertexBufferID
;
336 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->VertexBufferID
);
337 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, bytes
, vertexData
, GL_STATIC_DRAW_ARB
);
339 /* Setup a buffer of indices to test the ELEMENTS path */
340 glGenBuffersARB(1, &obj
->ElementsBufferID
);
341 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
342 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 100, NULL
, GL_STATIC_DRAW_ARB
);
343 i
= (GLuint
*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, GL_READ_WRITE_ARB
);
348 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
);
349 obj
->NumElements
= 4;
354 * Vertex and color data in different buffers.
356 static void MakeObject4(struct object
*obj
)
358 static const GLfloat vertexData
[] = {
364 static const GLfloat colorData
[] = {
371 obj
->VertexOffset
= 0;
372 obj
->VertexStride
= 0;
373 obj
->ColorOffset
= 0;
374 obj
->ColorStride
= 0;
377 glGenBuffersARB(1, &obj
->VertexBufferID
);
378 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->VertexBufferID
);
379 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, sizeof(vertexData
), vertexData
,
382 glGenBuffersARB(1, &obj
->ColorBufferID
);
383 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->ColorBufferID
);
384 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, sizeof(colorData
), colorData
,
387 /* Setup a buffer of indices to test the ELEMENTS path */
388 obj
->ElementsBufferID
= 0;
389 obj
->NumElements
= 0;
394 static void Init( void )
396 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
397 printf("GL_ARB_vertex_buffer_object not found!\n");
400 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
402 /* Test buffer object deletion */
404 static GLubyte data
[1000];
406 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, id
);
407 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 1000, data
, GL_STATIC_DRAW_ARB
);
408 glVertexPointer(3, GL_FLOAT
, 0, (void *) 0);
409 glDeleteBuffersARB(1, &id
);
410 assert(!glIsBufferARB(id
));
411 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 0);
412 glVertexPointer(3, GL_FLOAT
, 0, (void *) 0);
413 assert(!glIsBufferARB(id
));
416 MakeObject1(Objects
+ 0);
417 MakeObject2(Objects
+ 1);
418 MakeObject3(Objects
+ 2);
419 MakeObject4(Objects
+ 3);
424 int main( int argc
, char *argv
[] )
426 glutInit( &argc
, argv
);
427 glutInitWindowPosition( 0, 0 );
428 glutInitWindowSize( 600, 300 );
429 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
430 Win
= glutCreateWindow(argv
[0]);
431 glutReshapeFunc( Reshape
);
432 glutKeyboardFunc( Key
);
433 glutSpecialFunc( SpecialKey
);
434 glutDisplayFunc( Display
);