2 * Test GL_ARB_vertex_buffer_object
9 #define GL_GLEXT_PROTOTYPES
16 #define NUM_OBJECTS 10
21 GLuint ElementsBufferID
;
28 static struct object Objects
[NUM_OBJECTS
];
29 static GLuint NumObjects
;
33 static GLfloat Xrot
= 0, Yrot
= 0, Zrot
= 0;
34 static GLboolean Anim
= GL_TRUE
;
37 static void CheckError(int line
)
39 GLenum err
= glGetError();
41 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
46 static void DrawObject( const struct object
*obj
)
48 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
49 glVertexPointer(3, GL_FLOAT
, 0, (void *) obj
->VertexOffset
);
50 glEnable(GL_VERTEX_ARRAY
);
52 /* test push/pop attrib */
53 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
57 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
58 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
59 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 999999);
63 glColorPointer(3, GL_FLOAT
, 0, (void *) obj
->ColorOffset
);
64 glEnable(GL_COLOR_ARRAY
);
66 if (obj
->NumElements
> 0) {
68 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
69 glDrawElements(GL_LINE_LOOP
, obj
->NumElements
, GL_UNSIGNED_INT
, NULL
);
72 /* non-indexed arrays */
73 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 0);
74 glDrawArrays(GL_LINE_LOOP
, 0, obj
->NumVerts
);
79 static void Idle( void )
81 Zrot
= 0.05 * glutGet(GLUT_ELAPSED_TIME
);
86 static void Display( void )
90 glClear( GL_COLOR_BUFFER_BIT
);
92 for (i
= 0; i
< NumObjects
; i
++) {
93 float x
= 5.0 * ((float) i
/ (NumObjects
-1) - 0.5);
95 glTranslatef(x
, 0, 0);
96 glRotatef(Xrot
, 1, 0, 0);
97 glRotatef(Yrot
, 0, 1, 0);
98 glRotatef(Zrot
, 0, 0, 1);
100 DrawObject(Objects
+ i
);
105 CheckError(__LINE__
);
110 static void Reshape( int width
, int height
)
112 float ar
= (float) width
/ (float) height
;
113 glViewport( 0, 0, width
, height
);
114 glMatrixMode( GL_PROJECTION
);
116 glFrustum( -ar
, ar
, -1.0, 1.0, 5.0, 25.0 );
117 glMatrixMode( GL_MODELVIEW
);
119 glTranslatef( 0.0, 0.0, -15.0 );
123 static void FreeBuffers(void)
126 for (i
= 0; i
< NUM_OBJECTS
; i
++)
127 glDeleteBuffersARB(1, &Objects
[i
].BufferID
);
131 static void Key( unsigned char key
, int x
, int y
)
133 const GLfloat step
= 3.0;
152 glutDestroyWindow(Win
);
160 static void SpecialKey( int key
, int x
, int y
)
162 const GLfloat step
= 3.0;
184 static void MakeObject1(struct object
*obj
)
191 for (i
= 0; i
< 500; i
++)
192 buffer
[i
] = i
& 0xff;
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
);
200 for (i
= 0; i
< 500; i
++)
203 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0, 500, buffer
);
205 for (i
= 0; i
< 500; i
++)
206 assert(buffer
[i
] == (i
& 0xff));
208 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
211 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
213 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
215 /* do some sanity tests */
216 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
219 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_SIZE_ARB
, &i
);
222 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
223 assert(i
== GL_STATIC_DRAW_ARB
);
225 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_ACCESS_ARB
, &i
);
226 assert(i
== GL_WRITE_ONLY_ARB
);
228 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
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;
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;
242 obj
->VertexOffset
= 0;
243 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
244 obj
->NumElements
= 0;
246 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
248 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
251 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
256 static void MakeObject2(struct object
*obj
)
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
);
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;
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;
274 obj
->VertexOffset
= 0;
275 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
276 obj
->NumElements
= 0;
278 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
282 static void MakeObject3(struct object
*obj
)
284 GLfloat vertexData
[1000];
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;
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;
301 obj
->VertexOffset
= 0;
302 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
304 bytes
= obj
->NumVerts
* (3 + 3) * sizeof(GLfloat
);
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
);
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
);
320 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
);
321 obj
->NumElements
= 4;
326 static void Init( void )
328 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
329 printf("GL_ARB_vertex_buffer_object not found!\n");
332 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
334 /* Test buffer object deletion */
336 static GLubyte data
[1000];
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
));
348 MakeObject1(Objects
+ 0);
349 MakeObject2(Objects
+ 1);
350 MakeObject3(Objects
+ 2);
355 int main( int argc
, char *argv
[] )
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
);