2 * Test GL_ARB_vertex_buffer_object
9 #define GL_GLEXT_PROTOTYPES
16 #define NUM_OBJECTS 10
21 GLuint ElementsBufferID
;
30 static struct object Objects
[NUM_OBJECTS
];
31 static GLuint NumObjects
;
35 static GLfloat Xrot
= 0, Yrot
= 0, Zrot
= 0;
36 static GLboolean Anim
= GL_TRUE
;
39 static void CheckError(int line
)
41 GLenum err
= glGetError();
43 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
48 static void DrawObject( const struct object
*obj
)
50 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
51 glVertexPointer(3, GL_FLOAT
, obj
->VertexStride
, (void *) obj
->VertexOffset
);
52 glEnable(GL_VERTEX_ARRAY
);
54 /* test push/pop attrib */
55 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
59 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
60 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
61 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 999999);
65 glColorPointer(3, GL_FLOAT
, obj
->ColorStride
, (void *) obj
->ColorOffset
);
66 glEnable(GL_COLOR_ARRAY
);
68 if (obj
->NumElements
> 0) {
70 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
71 glDrawElements(GL_LINE_LOOP
, obj
->NumElements
, GL_UNSIGNED_INT
, NULL
);
74 /* non-indexed arrays */
75 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 0);
76 glDrawArrays(GL_LINE_LOOP
, 0, obj
->NumVerts
);
81 static void Idle( void )
83 Zrot
= 0.05 * glutGet(GLUT_ELAPSED_TIME
);
88 static void Display( void )
92 glClear( GL_COLOR_BUFFER_BIT
);
94 for (i
= 0; i
< NumObjects
; i
++) {
95 float x
= 5.0 * ((float) i
/ (NumObjects
-1) - 0.5);
97 glTranslatef(x
, 0, 0);
98 glRotatef(Xrot
, 1, 0, 0);
99 glRotatef(Yrot
, 0, 1, 0);
100 glRotatef(Zrot
, 0, 0, 1);
102 DrawObject(Objects
+ i
);
107 CheckError(__LINE__
);
112 static void Reshape( int width
, int height
)
114 float ar
= (float) width
/ (float) height
;
115 glViewport( 0, 0, width
, height
);
116 glMatrixMode( GL_PROJECTION
);
118 glFrustum( -ar
, ar
, -1.0, 1.0, 5.0, 25.0 );
119 glMatrixMode( GL_MODELVIEW
);
121 glTranslatef( 0.0, 0.0, -15.0 );
125 static void FreeBuffers(void)
128 for (i
= 0; i
< NUM_OBJECTS
; i
++)
129 glDeleteBuffersARB(1, &Objects
[i
].BufferID
);
133 static void Key( unsigned char key
, int x
, int y
)
135 const GLfloat step
= 3.0;
154 glutDestroyWindow(Win
);
162 static void SpecialKey( int key
, int x
, int y
)
164 const GLfloat step
= 3.0;
186 static void MakeObject1(struct object
*obj
)
193 for (i
= 0; i
< 500; i
++)
194 buffer
[i
] = i
& 0xff;
197 glGenBuffersARB(1, &obj
->BufferID
);
198 assert(obj
->BufferID
!= 0);
199 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
200 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 500, buffer
, GL_STATIC_DRAW_ARB
);
202 for (i
= 0; i
< 500; i
++)
205 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0, 500, buffer
);
207 for (i
= 0; i
< 500; i
++)
208 assert(buffer
[i
] == (i
& 0xff));
210 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
213 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
215 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
217 /* do some sanity tests */
218 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
221 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_SIZE_ARB
, &i
);
224 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
225 assert(i
== GL_STATIC_DRAW_ARB
);
227 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_ACCESS_ARB
, &i
);
228 assert(i
== GL_WRITE_ONLY_ARB
);
230 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
234 v
[0] = -1; v
[1] = -1; v
[2] = 0;
235 v
[3] = 1; v
[4] = -1; v
[5] = 0;
236 v
[6] = 1; v
[7] = 1; v
[8] = 0;
237 v
[9] = -1; v
[10] = 1; v
[11] = 0;
239 c
[0] = 1; c
[1] = 0; c
[2] = 0;
240 c
[3] = 1; c
[4] = 0; c
[5] = 0;
241 c
[6] = 1; c
[7] = 0; c
[8] = 1;
242 c
[9] = 1; c
[10] = 0; c
[11] = 1;
244 obj
->VertexOffset
= 0;
245 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
246 obj
->VertexStride
= 0;
247 obj
->ColorStride
= 0;
248 obj
->NumElements
= 0;
250 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
252 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
255 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
260 static void MakeObject2(struct object
*obj
)
263 int start
= 40; /* bytes, to test non-zero array offsets */
265 glGenBuffersARB(1, &obj
->BufferID
);
266 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
267 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 1000, NULL
, GL_STATIC_DRAW_ARB
);
268 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
270 v
+= start
/ sizeof(GLfloat
);
272 /* Make triangle: interleaved colors, then positions */
274 v
[0] = 0; v
[1] = 1; v
[2] = 0; v
[3] = -1; v
[4] = -1; v
[5] = 0;
275 v
[6] = 0; v
[7] = 1; v
[8] = 0; v
[9] = 1; v
[10] = -1; v
[11] = 0;
276 v
[12] = 1; v
[13] = 1; v
[14] = 0; v
[15] = 0; v
[16] = 1; v
[17] = 0;
279 obj
->VertexOffset
= start
+ 3 * sizeof(GLfloat
);
280 obj
->ColorOffset
= start
;
281 obj
->VertexStride
= 6 * sizeof(GLfloat
);
282 obj
->ColorStride
= 6 * sizeof(GLfloat
);
284 obj
->NumElements
= 0;
286 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
290 static void MakeObject3(struct object
*obj
)
292 GLfloat vertexData
[1000];
299 v
[0] = -1; v
[1] = -0.5; v
[2] = 0;
300 v
[3] = 1; v
[4] = -0.5; v
[5] = 0;
301 v
[6] = 1; v
[7] = 0.5; v
[8] = 0;
302 v
[9] = -1; v
[10] = 0.5; v
[11] = 0;
304 c
[0] = 0; c
[1] = 0; c
[2] = 1;
305 c
[3] = 0; c
[4] = 0; c
[5] = 1;
306 c
[6] = 0; c
[7] = 1; c
[8] = 1;
307 c
[9] = 0; c
[10] = 1; c
[11] = 1;
309 obj
->VertexOffset
= 0;
310 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
311 obj
->VertexStride
= 0;
312 obj
->ColorStride
= 0;
314 bytes
= obj
->NumVerts
* (3 + 3) * sizeof(GLfloat
);
316 /* Don't use glMap/UnmapBuffer for this object */
317 glGenBuffersARB(1, &obj
->BufferID
);
318 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
319 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, bytes
, vertexData
, GL_STATIC_DRAW_ARB
);
321 /* Setup a buffer of indices to test the ELEMENTS path */
322 glGenBuffersARB(1, &obj
->ElementsBufferID
);
323 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
324 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 100, NULL
, GL_STATIC_DRAW_ARB
);
325 i
= (GLuint
*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, GL_READ_WRITE_ARB
);
330 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
);
331 obj
->NumElements
= 4;
336 static void Init( void )
338 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
339 printf("GL_ARB_vertex_buffer_object not found!\n");
342 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
344 /* Test buffer object deletion */
346 static GLubyte data
[1000];
348 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, id
);
349 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, 1000, data
, GL_STATIC_DRAW_ARB
);
350 glVertexPointer(3, GL_FLOAT
, 0, (void *) 0);
351 glDeleteBuffersARB(1, &id
);
352 assert(!glIsBufferARB(id
));
353 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 0);
354 glVertexPointer(3, GL_FLOAT
, 0, (void *) 0);
355 assert(!glIsBufferARB(id
));
358 MakeObject1(Objects
+ 0);
359 MakeObject2(Objects
+ 1);
360 MakeObject3(Objects
+ 2);
365 int main( int argc
, char *argv
[] )
367 glutInit( &argc
, argv
);
368 glutInitWindowPosition( 0, 0 );
369 glutInitWindowSize( 600, 300 );
370 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
);
371 Win
= glutCreateWindow(argv
[0]);
372 glutReshapeFunc( Reshape
);
373 glutKeyboardFunc( Key
);
374 glutSpecialFunc( SpecialKey
);
375 glutDisplayFunc( Display
);