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
;
31 static GLfloat Xrot
= 0, Yrot
= 0, Zrot
= 0;
32 static GLboolean Anim
= GL_TRUE
;
35 static void CheckError(int line
)
37 GLenum err
= glGetError();
39 printf("GL Error 0x%x at line %d\n", (int) err
, line
);
44 static void DrawObject( const struct object
*obj
)
46 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, obj
->BufferID
);
47 glVertexPointer(3, GL_FLOAT
, 0, (void *) obj
->VertexOffset
);
48 glEnable(GL_VERTEX_ARRAY
);
50 /* test push/pop attrib */
51 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
55 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT
);
56 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
57 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, 999999);
61 glColorPointer(3, GL_FLOAT
, 0, (void *) obj
->ColorOffset
);
62 glEnable(GL_COLOR_ARRAY
);
64 if (obj
->NumElements
> 0) {
66 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, obj
->ElementsBufferID
);
67 glDrawElements(GL_LINE_LOOP
, obj
->NumElements
, GL_UNSIGNED_INT
, NULL
);
70 /* non-indexed arrays */
71 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
, 0);
72 glDrawArrays(GL_LINE_LOOP
, 0, obj
->NumVerts
);
77 static void Idle( void )
79 Zrot
= 0.05 * glutGet(GLUT_ELAPSED_TIME
);
84 static void Display( void )
88 glClear( GL_COLOR_BUFFER_BIT
);
90 for (i
= 0; i
< NumObjects
; i
++) {
91 float x
= 5.0 * ((float) i
/ (NumObjects
-1) - 0.5);
93 glTranslatef(x
, 0, 0);
94 glRotatef(Xrot
, 1, 0, 0);
95 glRotatef(Yrot
, 0, 1, 0);
96 glRotatef(Zrot
, 0, 0, 1);
98 DrawObject(Objects
+ i
);
103 CheckError(__LINE__
);
108 static void Reshape( int width
, int height
)
110 float ar
= (float) width
/ (float) height
;
111 glViewport( 0, 0, width
, height
);
112 glMatrixMode( GL_PROJECTION
);
114 glFrustum( -ar
, ar
, -1.0, 1.0, 5.0, 25.0 );
115 glMatrixMode( GL_MODELVIEW
);
117 glTranslatef( 0.0, 0.0, -15.0 );
121 static void Key( unsigned char key
, int x
, int y
)
123 const GLfloat step
= 3.0;
148 static void SpecialKey( int key
, int x
, int y
)
150 const GLfloat step
= 3.0;
172 static void MakeObject1(struct object
*obj
)
179 for (i
= 0; i
< 500; i
++)
180 buffer
[i
] = i
& 0xff;
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
);
188 for (i
= 0; i
< 500; i
++)
191 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB
, 0, 500, buffer
);
193 for (i
= 0; i
< 500; i
++)
194 assert(buffer
[i
] == (i
& 0xff));
196 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
199 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
201 v
= (GLfloat
*) glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
203 /* do some sanity tests */
204 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
207 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_SIZE_ARB
, &i
);
210 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_USAGE_ARB
, &i
);
211 assert(i
== GL_STATIC_DRAW_ARB
);
213 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_ACCESS_ARB
, &i
);
214 assert(i
== GL_WRITE_ONLY_ARB
);
216 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
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;
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;
230 obj
->VertexOffset
= 0;
231 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
232 obj
->NumElements
= 0;
234 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
236 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAP_POINTER_ARB
, &p
);
239 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB
, GL_BUFFER_MAPPED_ARB
, &i
);
244 static void MakeObject2(struct object
*obj
)
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
);
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;
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;
262 obj
->VertexOffset
= 0;
263 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
264 obj
->NumElements
= 0;
266 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
270 static void MakeObject3(struct object
*obj
)
272 GLfloat vertexData
[1000];
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;
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;
289 obj
->VertexOffset
= 0;
290 obj
->ColorOffset
= 3 * sizeof(GLfloat
) * obj
->NumVerts
;
292 bytes
= obj
->NumVerts
* (3 + 3) * sizeof(GLfloat
);
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
);
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
);
308 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB
);
309 obj
->NumElements
= 4;
314 static void Init( void )
316 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
317 printf("GL_ARB_vertex_buffer_object not found!\n");
320 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
322 /* Test buffer object deletion */
324 static GLubyte data
[1000];
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));*/
336 MakeObject1(Objects
+ 0);
337 MakeObject2(Objects
+ 1);
338 MakeObject3(Objects
+ 2);
343 int main( int argc
, char *argv
[] )
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
);