blob: cd73737640ad091daf031f4f1202b5ebb1a81049 [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);
49 glColorPointer(3, GL_FLOAT, 0, (void *) obj->ColorOffset);
50 glEnable(GL_COLOR_ARRAY);
Brian Paulde8d4102003-09-17 18:15:47 +000051 if (obj->NumElements > 0) {
52 /* indexed arrays */
53 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
54 glDrawElements(GL_LINE_LOOP, obj->NumElements, GL_UNSIGNED_INT, NULL);
55 }
56 else {
57 /* non-indexed arrays */
58 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
59 glDrawArrays(GL_LINE_LOOP, 0, obj->NumVerts);
60 }
Brian Paul6bced012003-09-17 16:27:07 +000061}
62
63
64static void Idle( void )
65{
66 Zrot = 0.05 * glutGet(GLUT_ELAPSED_TIME);
67 glutPostRedisplay();
68}
69
70
71static void Display( void )
72{
73 int i;
74
75 glClear( GL_COLOR_BUFFER_BIT );
76
77 for (i = 0; i < NumObjects; i++) {
78 float x = 5.0 * ((float) i / (NumObjects-1) - 0.5);
79 glPushMatrix();
80 glTranslatef(x, 0, 0);
81 glRotatef(Xrot, 1, 0, 0);
82 glRotatef(Yrot, 0, 1, 0);
83 glRotatef(Zrot, 0, 0, 1);
84
85 DrawObject(Objects + i);
86
87 glPopMatrix();
88 }
89
90 CheckError(__LINE__);
91 glutSwapBuffers();
92}
93
94
95static void Reshape( int width, int height )
96{
97 float ar = (float) width / (float) height;
98 glViewport( 0, 0, width, height );
99 glMatrixMode( GL_PROJECTION );
100 glLoadIdentity();
101 glFrustum( -ar, ar, -1.0, 1.0, 5.0, 25.0 );
102 glMatrixMode( GL_MODELVIEW );
103 glLoadIdentity();
104 glTranslatef( 0.0, 0.0, -15.0 );
105}
106
107
108static void Key( unsigned char key, int x, int y )
109{
110 const GLfloat step = 3.0;
111 (void) x;
112 (void) y;
113 switch (key) {
114 case 'a':
115 Anim = !Anim;
116 if (Anim)
117 glutIdleFunc(Idle);
118 else
119 glutIdleFunc(NULL);
120 break;
121 case 'z':
122 Zrot -= step;
123 break;
124 case 'Z':
125 Zrot += step;
126 break;
127 case 27:
128 exit(0);
129 break;
130 }
131 glutPostRedisplay();
132}
133
134
135static void SpecialKey( int key, int x, int y )
136{
137 const GLfloat step = 3.0;
138 (void) x;
139 (void) y;
140 switch (key) {
141 case GLUT_KEY_UP:
142 Xrot -= step;
143 break;
144 case GLUT_KEY_DOWN:
145 Xrot += step;
146 break;
147 case GLUT_KEY_LEFT:
148 Yrot -= step;
149 break;
150 case GLUT_KEY_RIGHT:
151 Yrot += step;
152 break;
153 }
154 glutPostRedisplay();
155}
156
157
158
159static void MakeObject1(struct object *obj)
160{
161 GLfloat *v, *c;
Brian Paul45242742003-10-14 15:49:12 +0000162 void *p;
163 int i;
Brian Paul35b52c72003-10-21 14:56:53 +0000164 GLubyte buffer[500];
165
166 for (i = 0; i < 500; i++)
167 buffer[i] = i & 0xff;
Brian Paul6bced012003-09-17 16:27:07 +0000168
169 glGenBuffersARB(1, &obj->BufferID);
170 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
Brian Paul35b52c72003-10-21 14:56:53 +0000171 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 500, buffer, GL_STATIC_DRAW_ARB);
172
173 for (i = 0; i < 500; i++)
174 buffer[i] = 0;
175
176 glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, 500, buffer);
177
178 for (i = 0; i < 500; i++)
179 assert(buffer[i] == (i & 0xff));
180
181 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
182 assert(!i);
183
184 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
185
Brian Paul1ceeac22003-09-17 18:20:52 +0000186 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000187
Brian Paul45242742003-10-14 15:49:12 +0000188 /* do some sanity tests */
189 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
190 assert(p == v);
191
192 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
Brian Paul35b52c72003-10-21 14:56:53 +0000193 assert(i == 500);
Brian Paul45242742003-10-14 15:49:12 +0000194
195 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
196 assert(i == GL_STATIC_DRAW_ARB);
197
Brian Paul35b52c72003-10-21 14:56:53 +0000198 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
199 assert(i == GL_WRITE_ONLY_ARB);
200
Brian Paul45242742003-10-14 15:49:12 +0000201 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
202 assert(i);
203
Brian Paul6bced012003-09-17 16:27:07 +0000204 /* Make rectangle */
205 v[0] = -1; v[1] = -1; v[2] = 0;
206 v[3] = 1; v[4] = -1; v[5] = 0;
207 v[6] = 1; v[7] = 1; v[8] = 0;
208 v[9] = -1; v[10] = 1; v[11] = 0;
209 c = v + 12;
210 c[0] = 1; c[1] = 0; c[2] = 0;
211 c[3] = 1; c[4] = 0; c[5] = 0;
212 c[6] = 1; c[7] = 0; c[8] = 1;
213 c[9] = 1; c[10] = 0; c[11] = 1;
214 obj->NumVerts = 4;
215 obj->VertexOffset = 0;
216 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000217 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000218
219 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paul45242742003-10-14 15:49:12 +0000220
221 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
222 assert(!p);
223
224 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
225 assert(!i);
Brian Paul6bced012003-09-17 16:27:07 +0000226}
227
228
229static void MakeObject2(struct object *obj)
230{
231 GLfloat *v, *c;
232
233 glGenBuffersARB(1, &obj->BufferID);
234 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
235 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000236 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000237
238 /* Make triangle */
239 v[0] = -1; v[1] = -1; v[2] = 0;
240 v[3] = 1; v[4] = -1; v[5] = 0;
241 v[6] = 0; v[7] = 1; v[8] = 0;
242 c = v + 9;
243 c[0] = 0; c[1] = 1; c[2] = 0;
244 c[3] = 0; c[4] = 1; c[5] = 0;
245 c[6] = 1; c[7] = 1; c[8] = 0;
246 obj->NumVerts = 3;
247 obj->VertexOffset = 0;
248 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000249 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000250
251 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
252}
253
254
255static void MakeObject3(struct object *obj)
256{
Brian Paul45242742003-10-14 15:49:12 +0000257 GLfloat vertexData[1000];
Brian Paul6bced012003-09-17 16:27:07 +0000258 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000259 GLuint *i;
Brian Paul45242742003-10-14 15:49:12 +0000260 int bytes;
Brian Paul6bced012003-09-17 16:27:07 +0000261
262 /* Make rectangle */
Brian Paul45242742003-10-14 15:49:12 +0000263 v = vertexData;
Brian Paul6bced012003-09-17 16:27:07 +0000264 v[0] = -1; v[1] = -0.5; v[2] = 0;
265 v[3] = 1; v[4] = -0.5; v[5] = 0;
266 v[6] = 1; v[7] = 0.5; v[8] = 0;
267 v[9] = -1; v[10] = 0.5; v[11] = 0;
Brian Paul45242742003-10-14 15:49:12 +0000268 c = vertexData + 12;
Brian Paul6bced012003-09-17 16:27:07 +0000269 c[0] = 0; c[1] = 0; c[2] = 1;
270 c[3] = 0; c[4] = 0; c[5] = 1;
271 c[6] = 0; c[7] = 1; c[8] = 1;
272 c[9] = 0; c[10] = 1; c[11] = 1;
273 obj->NumVerts = 4;
274 obj->VertexOffset = 0;
275 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
276
Brian Paul45242742003-10-14 15:49:12 +0000277 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
278
279 /* Don't use glMap/UnmapBuffer for this object */
280 glGenBuffersARB(1, &obj->BufferID);
281 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
282 glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, vertexData, GL_STATIC_DRAW_ARB);
Brian Paulde8d4102003-09-17 18:15:47 +0000283
284 /* Setup a buffer of indices to test the ELEMENTS path */
285 glGenBuffersARB(1, &obj->ElementsBufferID);
286 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
287 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 100, NULL, GL_STATIC_DRAW_ARB);
288 i = (GLuint *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
289 i[0] = 0;
290 i[1] = 1;
291 i[2] = 2;
292 i[3] = 3;
293 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
294 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000295}
296
297
298
299static void Init( void )
300{
301 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
302 printf("GL_ARB_vertex_buffer_object not found!\n");
303 exit(0);
304 }
305 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
306
307 MakeObject1(Objects + 0);
308 MakeObject2(Objects + 1);
309 MakeObject3(Objects + 2);
310 NumObjects = 3;
311}
312
313
314int main( int argc, char *argv[] )
315{
316 glutInit( &argc, argv );
317 glutInitWindowPosition( 0, 0 );
318 glutInitWindowSize( 600, 300 );
319 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
320 glutCreateWindow(argv[0]);
321 glutReshapeFunc( Reshape );
322 glutKeyboardFunc( Key );
323 glutSpecialFunc( SpecialKey );
324 glutDisplayFunc( Display );
325 if (Anim)
326 glutIdleFunc(Idle);
327 Init();
328 glutMainLoop();
329 return 0;
330}