blob: 50ab5cdfa89ffd827a1cba10a6ea59d80010ccf4 [file] [log] [blame]
Brian Paul6bced012003-09-17 16:27:07 +00001/*
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
18struct object
19{
20 GLuint BufferID;
Brian Paulde8d4102003-09-17 18:15:47 +000021 GLuint ElementsBufferID;
Brian Paul6bced012003-09-17 16:27:07 +000022 GLuint NumVerts;
23 GLuint VertexOffset;
24 GLuint ColorOffset;
Brian Paulde8d4102003-09-17 18:15:47 +000025 GLuint NumElements;
Brian Paul6bced012003-09-17 16:27:07 +000026};
27
28static struct object Objects[NUM_OBJECTS];
29static GLuint NumObjects;
30
Brian Paul0c46a122006-08-25 22:13:08 +000031static GLuint Win;
32
Brian Paul6bced012003-09-17 16:27:07 +000033static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
34static GLboolean Anim = GL_TRUE;
35
36
37static void CheckError(int line)
38{
39 GLenum err = glGetError();
40 if (err) {
Brian Paul47a67492004-08-10 15:34:51 +000041 printf("GL Error 0x%x at line %d\n", (int) err, line);
Brian Paul6bced012003-09-17 16:27:07 +000042 }
43}
44
45
46static void DrawObject( const struct object *obj )
47{
48 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
49 glVertexPointer(3, GL_FLOAT, 0, (void *) obj->VertexOffset);
50 glEnable(GL_VERTEX_ARRAY);
Brian Paulb87c5d02004-03-22 16:28:02 +000051
52 /* test push/pop attrib */
53 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
54#if 0
55 if (1)
56 {
57 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
58 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
59 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 999999);
60 glPopClientAttrib();
61 }
62#endif
Brian Paul6bced012003-09-17 16:27:07 +000063 glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset);
64 glEnable(GL_COLOR_ARRAY);
Brian Paulb87c5d02004-03-22 16:28:02 +000065
Brian Paulde8d4102003-09-17 18:15:47 +000066 if (obj->NumElements > 0) {
67 /* indexed arrays */
68 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
69 glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL);
70 }
71 else {
72 /* non-indexed arrays */
73 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
74 glDrawArrays(GL_LINE_LOOP, 0, obj->NumVerts);
75 }
Brian Paul6bced012003-09-17 16:27:07 +000076}
77
78
79static void Idle( void )
80{
81 Zrot = 0.05 * glutGet(GLUT_ELAPSED_TIME);
82 glutPostRedisplay();
83}
84
85
86static void Display( void )
87{
88 int i;
89
90 glClear( GL_COLOR_BUFFER_BIT );
91
92 for (i = 0; i < NumObjects; i++) {
93 float x = 5.0 * ((float) i / (NumObjects-1) - 0.5);
94 glPushMatrix();
95 glTranslatef(x, 0, 0);
96 glRotatef(Xrot, 1, 0, 0);
97 glRotatef(Yrot, 0, 1, 0);
98 glRotatef(Zrot, 0, 0, 1);
99
100 DrawObject(Objects + i);
101
102 glPopMatrix();
103 }
104
105 CheckError(__LINE__);
106 glutSwapBuffers();
107}
108
109
110static void Reshape( int width, int height )
111{
112 float ar = (float) width / (float) height;
113 glViewport( 0, 0, width, height );
114 glMatrixMode( GL_PROJECTION );
115 glLoadIdentity();
116 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
117 glMatrixMode( GL_MODELVIEW );
118 glLoadIdentity();
119 glTranslatef( 0.0, 0.0, -15.0 );
120}
121
122
Brian Paul0c46a122006-08-25 22:13:08 +0000123static void FreeBuffers(void)
124{
125 int i;
126 for (i = 0; i < NUM_OBJECTS; i++)
127 glDeleteBuffersARB(1, &Objects[i].BufferID);
128}
129
130
Brian Paul6bced012003-09-17 16:27:07 +0000131static void Key( unsigned char key, int x, int y )
132{
133 const GLfloat step = 3.0;
134 (void) x;
135 (void) y;
136 switch (key) {
137 case 'a':
138 Anim = !Anim;
139 if (Anim)
140 glutIdleFunc(Idle);
141 else
142 glutIdleFunc(NULL);
143 break;
144 case 'z':
145 Zrot -= step;
146 break;
147 case 'Z':
148 Zrot += step;
149 break;
150 case 27:
Brian Paul0c46a122006-08-25 22:13:08 +0000151 FreeBuffers();
152 glutDestroyWindow(Win);
Brian Paul6bced012003-09-17 16:27:07 +0000153 exit(0);
154 break;
155 }
156 glutPostRedisplay();
157}
158
159
160static void SpecialKey( int key, int x, int y )
161{
162 const GLfloat step = 3.0;
163 (void) x;
164 (void) y;
165 switch (key) {
166 case GLUT_KEY_UP:
167 Xrot -= step;
168 break;
169 case GLUT_KEY_DOWN:
170 Xrot += step;
171 break;
172 case GLUT_KEY_LEFT:
173 Yrot -= step;
174 break;
175 case GLUT_KEY_RIGHT:
176 Yrot += step;
177 break;
178 }
179 glutPostRedisplay();
180}
181
182
183
184static void MakeObject1(struct object *obj)
185{
186 GLfloat *v, *c;
Brian Paul45242742003-10-14 15:49:12 +0000187 void *p;
188 int i;
Brian Paul35b52c72003-10-21 14:56:53 +0000189 GLubyte buffer[500];
190
191 for (i = 0; i < 500; i++)
192 buffer[i] = i & 0xff;
Brian Paul6bced012003-09-17 16:27:07 +0000193
Brian Paul47a67492004-08-10 15:34:51 +0000194 obj->BufferID = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000195 glGenBuffersARB(1, &obj->BufferID);
Brian Paul47a67492004-08-10 15:34:51 +0000196 assert(obj->BufferID != 0);
Brian Paul6bced012003-09-17 16:27:07 +0000197 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
Brian Paul35b52c72003-10-21 14:56:53 +0000198 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 500, buffer, GL_STATIC_DRAW_ARB);
199
200 for (i = 0; i < 500; i++)
201 buffer[i] = 0;
202
203 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 500, buffer);
204
205 for (i = 0; i < 500; i++)
206 assert(buffer[i] == (i & 0xff));
207
208 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
209 assert(!i);
210
211 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
212
Brian Paul1ceeac22003-09-17 18:20:52 +0000213 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000214
Brian Paul45242742003-10-14 15:49:12 +0000215 /* do some sanity tests */
216 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
217 assert(p == v);
218
219 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
Brian Paul35b52c72003-10-21 14:56:53 +0000220 assert(i == 500);
Brian Paul45242742003-10-14 15:49:12 +0000221
222 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
223 assert(i == GL_STATIC_DRAW_ARB);
224
Brian Paul35b52c72003-10-21 14:56:53 +0000225 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
226 assert(i == GL_WRITE_ONLY_ARB);
227
Brian Paul45242742003-10-14 15:49:12 +0000228 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
229 assert(i);
230
Brian Paul6bced012003-09-17 16:27:07 +0000231 /* Make rectangle */
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;
236 c = v + 12;
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;
241 obj->NumVerts = 4;
242 obj->VertexOffset = 0;
243 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000244 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000245
246 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paul45242742003-10-14 15:49:12 +0000247
248 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
249 assert(!p);
250
251 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
252 assert(!i);
Brian Paul6bced012003-09-17 16:27:07 +0000253}
254
255
256static void MakeObject2(struct object *obj)
257{
258 GLfloat *v, *c;
259
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);
Brian Paul1ceeac22003-09-17 18:20:52 +0000263 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000264
265 /* Make triangle */
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;
269 c = v + 9;
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;
273 obj->NumVerts = 3;
274 obj->VertexOffset = 0;
275 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000276 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000277
278 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
279}
280
281
282static void MakeObject3(struct object *obj)
283{
Brian Paul45242742003-10-14 15:49:12 +0000284 GLfloat vertexData[1000];
Brian Paul6bced012003-09-17 16:27:07 +0000285 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000286 GLuint *i;
Brian Paul45242742003-10-14 15:49:12 +0000287 int bytes;
Brian Paul6bced012003-09-17 16:27:07 +0000288
289 /* Make rectangle */
Brian Paul45242742003-10-14 15:49:12 +0000290 v = vertexData;
Brian Paul6bced012003-09-17 16:27:07 +0000291 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;
Brian Paul45242742003-10-14 15:49:12 +0000295 c = vertexData + 12;
Brian Paul6bced012003-09-17 16:27:07 +0000296 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;
300 obj->NumVerts = 4;
301 obj->VertexOffset = 0;
302 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
303
Brian Paul45242742003-10-14 15:49:12 +0000304 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
305
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);
Brian Paulde8d4102003-09-17 18:15:47 +0000310
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);
316 i[0] = 0;
317 i[1] = 1;
318 i[2] = 2;
319 i[3] = 3;
320 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
321 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000322}
323
324
325
326static void Init( void )
327{
328 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
329 printf("GL_ARB_vertex_buffer_object not found!\n");
330 exit(0);
331 }
332 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
333
Brian Paulb87c5d02004-03-22 16:28:02 +0000334 /* Test buffer object deletion */
335 if (1) {
336 static GLubyte data[1000];
337 GLuint id = 999;
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);
Brian Paul5c6b3912005-01-24 15:41:08 +0000342 assert(!glIsBufferARB(id));
Brian Paulb87c5d02004-03-22 16:28:02 +0000343 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
344 glVertexPointer(3, GL_FLOAT, 0, (void *) 0);
Brian Paul5c6b3912005-01-24 15:41:08 +0000345 assert(!glIsBufferARB(id));
Brian Paulb87c5d02004-03-22 16:28:02 +0000346 }
347
Brian Paul6bced012003-09-17 16:27:07 +0000348 MakeObject1(Objects + 0);
349 MakeObject2(Objects + 1);
350 MakeObject3(Objects + 2);
351 NumObjects = 3;
352}
353
354
355int main( int argc, char *argv[] )
356{
357 glutInit( &argc, argv );
358 glutInitWindowPosition( 0, 0 );
359 glutInitWindowSize( 600, 300 );
360 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
Brian Paul0c46a122006-08-25 22:13:08 +0000361 Win = glutCreateWindow(argv[0]);
Brian Paul6bced012003-09-17 16:27:07 +0000362 glutReshapeFunc( Reshape );
363 glutKeyboardFunc( Key );
364 glutSpecialFunc( SpecialKey );
365 glutDisplayFunc( Display );
366 if (Anim)
367 glutIdleFunc(Idle);
368 Init();
369 glutMainLoop();
370 return 0;
371}