blob: df7d57f8e0a380bf0bc8f3bb9412102ed3db5140 [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 Paul6bced012003-09-17 16:27:07 +0000164
165 glGenBuffersARB(1, &obj->BufferID);
166 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
167 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000168 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000169
Brian Paul45242742003-10-14 15:49:12 +0000170 /* do some sanity tests */
171 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
172 assert(p == v);
173
174 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &i);
175 assert(i == 1000);
176
177 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_ACCESS_ARB, &i);
178 assert(i == GL_WRITE_ONLY_ARB);
179
180 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_USAGE_ARB, &i);
181 assert(i == GL_STATIC_DRAW_ARB);
182
183 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
184 assert(i);
185
Brian Paul6bced012003-09-17 16:27:07 +0000186 /* Make rectangle */
187 v[0] = -1; v[1] = -1; v[2] = 0;
188 v[3] = 1; v[4] = -1; v[5] = 0;
189 v[6] = 1; v[7] = 1; v[8] = 0;
190 v[9] = -1; v[10] = 1; v[11] = 0;
191 c = v + 12;
192 c[0] = 1; c[1] = 0; c[2] = 0;
193 c[3] = 1; c[4] = 0; c[5] = 0;
194 c[6] = 1; c[7] = 0; c[8] = 1;
195 c[9] = 1; c[10] = 0; c[11] = 1;
196 obj->NumVerts = 4;
197 obj->VertexOffset = 0;
198 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000199 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000200
201 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paul45242742003-10-14 15:49:12 +0000202
203 glGetBufferPointervARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAP_POINTER_ARB, &p);
204 assert(!p);
205
206 glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB, &i);
207 assert(!i);
Brian Paul6bced012003-09-17 16:27:07 +0000208}
209
210
211static void MakeObject2(struct object *obj)
212{
213 GLfloat *v, *c;
214
215 glGenBuffersARB(1, &obj->BufferID);
216 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
217 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000218 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000219
220 /* Make triangle */
221 v[0] = -1; v[1] = -1; v[2] = 0;
222 v[3] = 1; v[4] = -1; v[5] = 0;
223 v[6] = 0; v[7] = 1; v[8] = 0;
224 c = v + 9;
225 c[0] = 0; c[1] = 1; c[2] = 0;
226 c[3] = 0; c[4] = 1; c[5] = 0;
227 c[6] = 1; c[7] = 1; c[8] = 0;
228 obj->NumVerts = 3;
229 obj->VertexOffset = 0;
230 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000231 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000232
233 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
234}
235
236
237static void MakeObject3(struct object *obj)
238{
Brian Paul45242742003-10-14 15:49:12 +0000239 GLfloat vertexData[1000];
Brian Paul6bced012003-09-17 16:27:07 +0000240 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000241 GLuint *i;
Brian Paul45242742003-10-14 15:49:12 +0000242 int bytes;
Brian Paul6bced012003-09-17 16:27:07 +0000243
244 /* Make rectangle */
Brian Paul45242742003-10-14 15:49:12 +0000245 v = vertexData;
Brian Paul6bced012003-09-17 16:27:07 +0000246 v[0] = -1; v[1] = -0.5; v[2] = 0;
247 v[3] = 1; v[4] = -0.5; v[5] = 0;
248 v[6] = 1; v[7] = 0.5; v[8] = 0;
249 v[9] = -1; v[10] = 0.5; v[11] = 0;
Brian Paul45242742003-10-14 15:49:12 +0000250 c = vertexData + 12;
Brian Paul6bced012003-09-17 16:27:07 +0000251 c[0] = 0; c[1] = 0; c[2] = 1;
252 c[3] = 0; c[4] = 0; c[5] = 1;
253 c[6] = 0; c[7] = 1; c[8] = 1;
254 c[9] = 0; c[10] = 1; c[11] = 1;
255 obj->NumVerts = 4;
256 obj->VertexOffset = 0;
257 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
258
Brian Paul45242742003-10-14 15:49:12 +0000259 bytes = obj->NumVerts * (3 + 3) * sizeof(GLfloat);
260
261 /* Don't use glMap/UnmapBuffer for this object */
262 glGenBuffersARB(1, &obj->BufferID);
263 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
264 glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, vertexData, GL_STATIC_DRAW_ARB);
Brian Paulde8d4102003-09-17 18:15:47 +0000265
266 /* Setup a buffer of indices to test the ELEMENTS path */
267 glGenBuffersARB(1, &obj->ElementsBufferID);
268 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
269 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 100, NULL, GL_STATIC_DRAW_ARB);
270 i = (GLuint *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
271 i[0] = 0;
272 i[1] = 1;
273 i[2] = 2;
274 i[3] = 3;
275 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
276 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000277}
278
279
280
281static void Init( void )
282{
283 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
284 printf("GL_ARB_vertex_buffer_object not found!\n");
285 exit(0);
286 }
287 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
288
289 MakeObject1(Objects + 0);
290 MakeObject2(Objects + 1);
291 MakeObject3(Objects + 2);
292 NumObjects = 3;
293}
294
295
296int main( int argc, char *argv[] )
297{
298 glutInit( &argc, argv );
299 glutInitWindowPosition( 0, 0 );
300 glutInitWindowSize( 600, 300 );
301 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
302 glutCreateWindow(argv[0]);
303 glutReshapeFunc( Reshape );
304 glutKeyboardFunc( Key );
305 glutSpecialFunc( SpecialKey );
306 glutDisplayFunc( Display );
307 if (Anim)
308 glutIdleFunc(Idle);
309 Init();
310 glutMainLoop();
311 return 0;
312}