blob: bbfa38a1d84d219bf38a18891bad824a32309431 [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) {
39 printf("GL Error %d at line %d\n", (int) err, line);
40 }
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
182 glGenBuffersARB(1, &obj->BufferID);
183 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
Brian Paul35b52c72003-10-21 14:56:53 +0000184 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 500, buffer, GL_STATIC_DRAW_ARB);
185
186 for (i = 0; i < 500; i++)
187 buffer[i] = 0;
188
189 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 500, buffer);
190
191 for (i = 0; i < 500; i++)
192 assert(buffer[i] == (i & 0xff));
193
194 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
195 assert(!i);
196
197 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
198
Brian Paul1ceeac22003-09-17 18:20:52 +0000199 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000200
Brian Paul45242742003-10-14 15:49:12 +0000201 /* do some sanity tests */
202 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
203 assert(p == v);
204
205 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
Brian Paul35b52c72003-10-21 14:56:53 +0000206 assert(i == 500);
Brian Paul45242742003-10-14 15:49:12 +0000207
208 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
209 assert(i == GL_STATIC_DRAW_ARB);
210
Brian Paul35b52c72003-10-21 14:56:53 +0000211 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
212 assert(i == GL_WRITE_ONLY_ARB);
213
Brian Paul45242742003-10-14 15:49:12 +0000214 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
215 assert(i);
216
Brian Paul6bced012003-09-17 16:27:07 +0000217 /* Make rectangle */
218 v[0] = -1; v[1] = -1; v[2] = 0;
219 v[3] = 1; v[4] = -1; v[5] = 0;
220 v[6] = 1; v[7] = 1; v[8] = 0;
221 v[9] = -1; v[10] = 1; v[11] = 0;
222 c = v + 12;
223 c[0] = 1; c[1] = 0; c[2] = 0;
224 c[3] = 1; c[4] = 0; c[5] = 0;
225 c[6] = 1; c[7] = 0; c[8] = 1;
226 c[9] = 1; c[10] = 0; c[11] = 1;
227 obj->NumVerts = 4;
228 obj->VertexOffset = 0;
229 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000230 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000231
232 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paul45242742003-10-14 15:49:12 +0000233
234 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
235 assert(!p);
236
237 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
238 assert(!i);
Brian Paul6bced012003-09-17 16:27:07 +0000239}
240
241
242static void MakeObject2(struct object *obj)
243{
244 GLfloat *v, *c;
245
246 glGenBuffersARB(1, &obj->BufferID);
247 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
248 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000249 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000250
251 /* Make triangle */
252 v[0] = -1; v[1] = -1; v[2] = 0;
253 v[3] = 1; v[4] = -1; v[5] = 0;
254 v[6] = 0; v[7] = 1; v[8] = 0;
255 c = v + 9;
256 c[0] = 0; c[1] = 1; c[2] = 0;
257 c[3] = 0; c[4] = 1; c[5] = 0;
258 c[6] = 1; c[7] = 1; c[8] = 0;
259 obj->NumVerts = 3;
260 obj->VertexOffset = 0;
261 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000262 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000263
264 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
265}
266
267
268static void MakeObject3(struct object *obj)
269{
Brian Paul45242742003-10-14 15:49:12 +0000270 GLfloat vertexData[1000];
Brian Paul6bced012003-09-17 16:27:07 +0000271 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000272 GLuint *i;
Brian Paul45242742003-10-14 15:49:12 +0000273 int bytes;
Brian Paul6bced012003-09-17 16:27:07 +0000274
275 /* Make rectangle */
Brian Paul45242742003-10-14 15:49:12 +0000276 v = vertexData;
Brian Paul6bced012003-09-17 16:27:07 +0000277 v[0] = -1; v[1] = -0.5; v[2] = 0;
278 v[3] = 1; v[4] = -0.5; v[5] = 0;
279 v[6] = 1; v[7] = 0.5; v[8] = 0;
280 v[9] = -1; v[10] = 0.5; v[11] = 0;
Brian Paul45242742003-10-14 15:49:12 +0000281 c = vertexData + 12;
Brian Paul6bced012003-09-17 16:27:07 +0000282 c[0] = 0; c[1] = 0; c[2] = 1;
283 c[3] = 0; c[4] = 0; c[5] = 1;
284 c[6] = 0; c[7] = 1; c[8] = 1;
285 c[9] = 0; c[10] = 1; c[11] = 1;
286 obj->NumVerts = 4;
287 obj->VertexOffset = 0;
288 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
289
Brian Paul45242742003-10-14 15:49:12 +0000290 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
291
292 /* Don't use glMap/UnmapBuffer for this object */
293 glGenBuffersARB(1, &obj->BufferID);
294 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
295 glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, vertexData, GL_STATIC_DRAW_ARB);
Brian Paulde8d4102003-09-17 18:15:47 +0000296
297 /* Setup a buffer of indices to test the ELEMENTS path */
298 glGenBuffersARB(1, &obj->ElementsBufferID);
299 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
300 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 100, NULL, GL_STATIC_DRAW_ARB);
301 i = (GLuint *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
302 i[0] = 0;
303 i[1] = 1;
304 i[2] = 2;
305 i[3] = 3;
306 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
307 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000308}
309
310
311
312static void Init( void )
313{
314 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
315 printf("GL_ARB_vertex_buffer_object not found!\n");
316 exit(0);
317 }
318 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
319
Brian Paulb87c5d02004-03-22 16:28:02 +0000320 /* Test buffer object deletion */
321 if (1) {
322 static GLubyte data[1000];
323 GLuint id = 999;
324 glBindBufferARB(GL_ARRAY_BUFFER_ARB, id);
325 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, data, GL_STATIC_DRAW_ARB);
326 glVertexPointer(3, GL_FLOAT, 0, (void *) 0);
327 glDeleteBuffersARB(1, &id);
328 /*assert(!glIsBufferARB(id));*/
329 glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
330 glVertexPointer(3, GL_FLOAT, 0, (void *) 0);
331 /*assert(!glIsBufferARB(id));*/
332 }
333
Brian Paul6bced012003-09-17 16:27:07 +0000334 MakeObject1(Objects + 0);
335 MakeObject2(Objects + 1);
336 MakeObject3(Objects + 2);
337 NumObjects = 3;
338}
339
340
341int main( int argc, char *argv[] )
342{
343 glutInit( &argc, argv );
344 glutInitWindowPosition( 0, 0 );
345 glutInitWindowSize( 600, 300 );
346 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
347 glutCreateWindow(argv[0]);
348 glutReshapeFunc( Reshape );
349 glutKeyboardFunc( Key );
350 glutSpecialFunc( SpecialKey );
351 glutDisplayFunc( Display );
352 if (Anim)
353 glutIdleFunc(Idle);
354 Init();
355 glutMainLoop();
356 return 0;
357}