blob: 93e3f8b82093ffc676238789b3fa4167f9c90cd1 [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
31static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
32static GLboolean Anim = GL_TRUE;
33
34
35static void CheckError(int line)
36{
37 GLenum err = glGetError();
38 if (err) {
Brian Paul47a67492004-08-10 15:34:51 +000039 printf("GL Error 0x%x at line %d\n", (int) err, line);
Brian Paul6bced012003-09-17 16:27:07 +000040 }
41}
42
43
44static void DrawObject( const struct object *obj )
45{
46 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
47 glVertexPointer(3, GL_FLOAT, 0, (void *) obj->VertexOffset);
48 glEnable(GL_VERTEX_ARRAY);
Brian Paulb87c5d02004-03-22 16:28:02 +000049
50 /* test push/pop attrib */
51 /* XXX this leads to a segfault with NVIDIA's 53.36 driver */
52#if 0
53 if (1)
54 {
55 glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
56 /*glVertexPointer(3, GL_FLOAT, 0, (void *) (obj->VertexOffset + 10000));*/
57 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 999999);
58 glPopClientAttrib();
59 }
60#endif
Brian Paul6bced012003-09-17 16:27:07 +000061 glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset);
62 glEnable(GL_COLOR_ARRAY);
Brian Paulb87c5d02004-03-22 16:28:02 +000063
Brian Paulde8d4102003-09-17 18:15:47 +000064 if (obj->NumElements > 0) {
65 /* indexed arrays */
66 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
67 glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL);
68 }
69 else {
70 /* non-indexed arrays */
71 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
72 glDrawArrays(GL_LINE_LOOP, 0, obj->NumVerts);
73 }
Brian Paul6bced012003-09-17 16:27:07 +000074}
75
76
77static void Idle( void )
78{
79 Zrot = 0.05 * glutGet(GLUT_ELAPSED_TIME);
80 glutPostRedisplay();
81}
82
83
84static void Display( void )
85{
86 int i;
87
88 glClear( GL_COLOR_BUFFER_BIT );
89
90 for (i = 0; i < NumObjects; i++) {
91 float x = 5.0 * ((float) i / (NumObjects-1) - 0.5);
92 glPushMatrix();
93 glTranslatef(x, 0, 0);
94 glRotatef(Xrot, 1, 0, 0);
95 glRotatef(Yrot, 0, 1, 0);
96 glRotatef(Zrot, 0, 0, 1);
97
98 DrawObject(Objects + i);
99
100 glPopMatrix();
101 }
102
103 CheckError(__LINE__);
104 glutSwapBuffers();
105}
106
107
108static void Reshape( int width, int height )
109{
110 float ar = (float) width / (float) height;
111 glViewport( 0, 0, width, height );
112 glMatrixMode( GL_PROJECTION );
113 glLoadIdentity();
114 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
115 glMatrixMode( GL_MODELVIEW );
116 glLoadIdentity();
117 glTranslatef( 0.0, 0.0, -15.0 );
118}
119
120
121static void Key( unsigned char key, int x, int y )
122{
123 const GLfloat step = 3.0;
124 (void) x;
125 (void) y;
126 switch (key) {
127 case 'a':
128 Anim = !Anim;
129 if (Anim)
130 glutIdleFunc(Idle);
131 else
132 glutIdleFunc(NULL);
133 break;
134 case 'z':
135 Zrot -= step;
136 break;
137 case 'Z':
138 Zrot += step;
139 break;
140 case 27:
141 exit(0);
142 break;
143 }
144 glutPostRedisplay();
145}
146
147
148static void SpecialKey( int key, int x, int y )
149{
150 const GLfloat step = 3.0;
151 (void) x;
152 (void) y;
153 switch (key) {
154 case GLUT_KEY_UP:
155 Xrot -= step;
156 break;
157 case GLUT_KEY_DOWN:
158 Xrot += step;
159 break;
160 case GLUT_KEY_LEFT:
161 Yrot -= step;
162 break;
163 case GLUT_KEY_RIGHT:
164 Yrot += step;
165 break;
166 }
167 glutPostRedisplay();
168}
169
170
171
172static void MakeObject1(struct object *obj)
173{
174 GLfloat *v, *c;
Brian Paul45242742003-10-14 15:49:12 +0000175 void *p;
176 int i;
Brian Paul35b52c72003-10-21 14:56:53 +0000177 GLubyte buffer[500];
178
179 for (i = 0; i < 500; i++)
180 buffer[i] = i & 0xff;
Brian Paul6bced012003-09-17 16:27:07 +0000181
Brian Paul47a67492004-08-10 15:34:51 +0000182 obj->BufferID = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000183 glGenBuffersARB(1, &obj->BufferID);
Brian Paul47a67492004-08-10 15:34:51 +0000184 assert(obj->BufferID != 0);
Brian Paul6bced012003-09-17 16:27:07 +0000185 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
Brian Paul35b52c72003-10-21 14:56:53 +0000186 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 500, buffer, GL_STATIC_DRAW_ARB);
187
188 for (i = 0; i < 500; i++)
189 buffer[i] = 0;
190
191 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 500, buffer);
192
193 for (i = 0; i < 500; i++)
194 assert(buffer[i] == (i & 0xff));
195
196 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
197 assert(!i);
198
199 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
200
Brian Paul1ceeac22003-09-17 18:20:52 +0000201 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000202
Brian Paul45242742003-10-14 15:49:12 +0000203 /* do some sanity tests */
204 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
205 assert(p == v);
206
207 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
Brian Paul35b52c72003-10-21 14:56:53 +0000208 assert(i == 500);
Brian Paul45242742003-10-14 15:49:12 +0000209
210 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
211 assert(i == GL_STATIC_DRAW_ARB);
212
Brian Paul35b52c72003-10-21 14:56:53 +0000213 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
214 assert(i == GL_WRITE_ONLY_ARB);
215
Brian Paul45242742003-10-14 15:49:12 +0000216 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
217 assert(i);
218
Brian Paul6bced012003-09-17 16:27:07 +0000219 /* Make rectangle */
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;
224 c = v + 12;
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;
229 obj->NumVerts = 4;
230 obj->VertexOffset = 0;
231 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000232 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000233
234 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paul45242742003-10-14 15:49:12 +0000235
236 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
237 assert(!p);
238
239 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
240 assert(!i);
Brian Paul6bced012003-09-17 16:27:07 +0000241}
242
243
244static void MakeObject2(struct object *obj)
245{
246 GLfloat *v, *c;
247
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);
Brian Paul1ceeac22003-09-17 18:20:52 +0000251 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000252
253 /* Make triangle */
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;
257 c = v + 9;
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;
261 obj->NumVerts = 3;
262 obj->VertexOffset = 0;
263 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000264 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000265
266 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
267}
268
269
270static void MakeObject3(struct object *obj)
271{
Brian Paul45242742003-10-14 15:49:12 +0000272 GLfloat vertexData[1000];
Brian Paul6bced012003-09-17 16:27:07 +0000273 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000274 GLuint *i;
Brian Paul45242742003-10-14 15:49:12 +0000275 int bytes;
Brian Paul6bced012003-09-17 16:27:07 +0000276
277 /* Make rectangle */
Brian Paul45242742003-10-14 15:49:12 +0000278 v = vertexData;
Brian Paul6bced012003-09-17 16:27:07 +0000279 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;
Brian Paul45242742003-10-14 15:49:12 +0000283 c = vertexData + 12;
Brian Paul6bced012003-09-17 16:27:07 +0000284 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;
288 obj->NumVerts = 4;
289 obj->VertexOffset = 0;
290 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
291
Brian Paul45242742003-10-14 15:49:12 +0000292 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
293
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);
Brian Paulde8d4102003-09-17 18:15:47 +0000298
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);
304 i[0] = 0;
305 i[1] = 1;
306 i[2] = 2;
307 i[3] = 3;
308 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
309 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000310}
311
312
313
314static void Init( void )
315{
316 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
317 printf("GL_ARB_vertex_buffer_object not found!\n");
318 exit(0);
319 }
320 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
321
Brian Paulb87c5d02004-03-22 16:28:02 +0000322 /* Test buffer object deletion */
323 if (1) {
324 static GLubyte data[1000];
325 GLuint id = 999;
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));*/
334 }
335
Brian Paul6bced012003-09-17 16:27:07 +0000336 MakeObject1(Objects + 0);
337 MakeObject2(Objects + 1);
338 MakeObject3(Objects + 2);
339 NumObjects = 3;
340}
341
342
343int main( int argc, char *argv[] )
344{
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 );
354 if (Anim)
355 glutIdleFunc(Idle);
356 Init();
357 glutMainLoop();
358 return 0;
359}