blob: 9653f998d0fef9a6d6fae196f2230ec61a160360 [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;
162
163 glGenBuffersARB(1, &obj->BufferID);
164 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
165 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000166 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000167
168 /* Make rectangle */
169 v[0] = -1; v[1] = -1; v[2] = 0;
170 v[3] = 1; v[4] = -1; v[5] = 0;
171 v[6] = 1; v[7] = 1; v[8] = 0;
172 v[9] = -1; v[10] = 1; v[11] = 0;
173 c = v + 12;
174 c[0] = 1; c[1] = 0; c[2] = 0;
175 c[3] = 1; c[4] = 0; c[5] = 0;
176 c[6] = 1; c[7] = 0; c[8] = 1;
177 c[9] = 1; c[10] = 0; c[11] = 1;
178 obj->NumVerts = 4;
179 obj->VertexOffset = 0;
180 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000181 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000182
183 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
184}
185
186
187static void MakeObject2(struct object *obj)
188{
189 GLfloat *v, *c;
190
191 glGenBuffersARB(1, &obj->BufferID);
192 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
193 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000194 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000195
196 /* Make triangle */
197 v[0] = -1; v[1] = -1; v[2] = 0;
198 v[3] = 1; v[4] = -1; v[5] = 0;
199 v[6] = 0; v[7] = 1; v[8] = 0;
200 c = v + 9;
201 c[0] = 0; c[1] = 1; c[2] = 0;
202 c[3] = 0; c[4] = 1; c[5] = 0;
203 c[6] = 1; c[7] = 1; c[8] = 0;
204 obj->NumVerts = 3;
205 obj->VertexOffset = 0;
206 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
Brian Paulde8d4102003-09-17 18:15:47 +0000207 obj->NumElements = 0;
Brian Paul6bced012003-09-17 16:27:07 +0000208
209 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
210}
211
212
213static void MakeObject3(struct object *obj)
214{
215 GLfloat *v, *c;
Brian Paulde8d4102003-09-17 18:15:47 +0000216 GLuint *i;
Brian Paul6bced012003-09-17 16:27:07 +0000217
218 glGenBuffersARB(1, &obj->BufferID);
219 glBindBufferARB(GL_ARRAY_BUFFER_ARB, obj->BufferID);
220 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 1000, NULL, GL_STATIC_DRAW_ARB);
Brian Paul1ceeac22003-09-17 18:20:52 +0000221 v = (GLfloat *) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
Brian Paul6bced012003-09-17 16:27:07 +0000222
223 /* Make rectangle */
224 v[0] = -1; v[1] = -0.5; v[2] = 0;
225 v[3] = 1; v[4] = -0.5; v[5] = 0;
226 v[6] = 1; v[7] = 0.5; v[8] = 0;
227 v[9] = -1; v[10] = 0.5; v[11] = 0;
228 c = v + 12;
229 c[0] = 0; c[1] = 0; c[2] = 1;
230 c[3] = 0; c[4] = 0; c[5] = 1;
231 c[6] = 0; c[7] = 1; c[8] = 1;
232 c[9] = 0; c[10] = 1; c[11] = 1;
233 obj->NumVerts = 4;
234 obj->VertexOffset = 0;
235 obj->ColorOffset = 3 * sizeof(GLfloat) * obj->NumVerts;
236
237 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);
Brian Paulde8d4102003-09-17 18:15:47 +0000238
239 /* Setup a buffer of indices to test the ELEMENTS path */
240 glGenBuffersARB(1, &obj->ElementsBufferID);
241 glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, obj->ElementsBufferID);
242 glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 100, NULL, GL_STATIC_DRAW_ARB);
243 i = (GLuint *) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_READ_WRITE_ARB);
244 i[0] = 0;
245 i[1] = 1;
246 i[2] = 2;
247 i[3] = 3;
248 glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB);
249 obj->NumElements = 4;
Brian Paul6bced012003-09-17 16:27:07 +0000250}
251
252
253
254static void Init( void )
255{
256 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
257 printf("GL_ARB_vertex_buffer_object not found!\n");
258 exit(0);
259 }
260 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
261
262 MakeObject1(Objects + 0);
263 MakeObject2(Objects + 1);
264 MakeObject3(Objects + 2);
265 NumObjects = 3;
266}
267
268
269int main( int argc, char *argv[] )
270{
271 glutInit( &argc, argv );
272 glutInitWindowPosition( 0, 0 );
273 glutInitWindowSize( 600, 300 );
274 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
275 glutCreateWindow(argv[0]);
276 glutReshapeFunc( Reshape );
277 glutKeyboardFunc( Key );
278 glutSpecialFunc( SpecialKey );
279 glutDisplayFunc( Display );
280 if (Anim)
281 glutIdleFunc(Idle);
282 Init();
283 glutMainLoop();
284 return 0;
285}