2 * Test glMapBuffer() and glMapBufferRange()
4 * Fill a VBO with vertex data to draw several colored quads.
5 * On each redraw, update the geometry for just one rect in the VBO.
19 #include "glut_wrap.h"
22 static const GLuint NumRects
= 10;
23 static GLuint BufferID
;
24 static GLboolean Anim
= GL_TRUE
;
25 static GLboolean UseBufferRange
= GL_FALSE
;
29 static const float RectData
[] = {
30 /* vertex */ /* color */
39 * The buffer contains vertex positions (float[3]) and colors (float[3])
40 * for 'NumRects' quads.
41 * This function updates/rotates one quad in the buffer.
44 UpdateRect(int r
, float angle
)
51 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, BufferID
);
53 GLintptr offset
= r
* sizeof(RectData
);
54 GLsizeiptr length
= sizeof(RectData
);
55 GLbitfield access
= GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_RANGE_BIT
;
56 float *buf
= (float *) glMapBufferRange(GL_ARRAY_BUFFER_ARB
,
57 offset
, length
, access
);
61 /* map whole buffer */
62 float *buf
= (float *)
63 glMapBufferARB(GL_ARRAY_BUFFER_ARB
, GL_WRITE_ONLY_ARB
);
67 /* set rect verts/colors */
68 memcpy(rect
, RectData
, sizeof(RectData
));
70 /* loop over four verts, updating vertices */
71 for (i
= 0; i
< 4; i
++) {
72 float x
= 0.2 * RectData
[i
*6+0];
73 float y
= 0.2 * RectData
[i
*6+1];
74 float xpos
= -2.5 + 0.5 * r
;
77 /* translate and rotate vert */
78 rect
[i
* 6 + 0] = xpos
+ x
* cos(angle
) + y
* sin(angle
);
79 rect
[i
* 6 + 1] = ypos
+ x
* sin(angle
) - y
* cos(angle
);
82 glUnmapBufferARB(GL_ARRAY_BUFFER_ARB
);
90 float angle
= glutGet(GLUT_ELAPSED_TIME
) * 0.001;
91 UpdateRect(frame
% NumRects
, angle
);
99 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, BufferID
);
100 glVertexPointer(3, GL_FLOAT
, 24, 0);
101 glEnableClientState(GL_VERTEX_ARRAY
);
103 glColorPointer(3, GL_FLOAT
, 24, (void*) 12);
104 glEnableClientState(GL_COLOR_ARRAY
);
106 glDrawArrays(GL_QUADS
, 0, NumRects
* 4);
116 glClear(GL_COLOR_BUFFER_BIT
);
123 Reshape(int width
, int height
)
125 glViewport(0, 0, width
, height
);
126 glMatrixMode(GL_PROJECTION
);
128 glOrtho(-3.0, 3.0, -1.0, 1.0, -1.0, 1.0);
129 glMatrixMode(GL_MODELVIEW
);
143 Key(unsigned char key
, int x
, int y
)
149 glutIdleFunc(Anim
? Idle
: NULL
);
151 else if (key
== 's') {
154 else if (key
== 27) {
155 glutDestroyWindow(Win
);
165 GLuint BufferSize
= NumRects
* sizeof(RectData
);
168 if (!glutExtensionSupported("GL_ARB_vertex_buffer_object")) {
169 printf("GL_ARB_vertex_buffer_object not found!\n");
173 UseBufferRange
= glutExtensionSupported("GL_ARB_map_buffer_range");
174 printf("Use GL_ARB_map_buffer_range: %c\n", "NY"[UseBufferRange
]);
176 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
178 /* initially load buffer with zeros */
179 buf
= (float *) calloc(1, BufferSize
);
181 glGenBuffersARB(1, &BufferID
);
182 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, BufferID
);
183 glBufferDataARB(GL_ARRAY_BUFFER_ARB
, BufferSize
, buf
, GL_DYNAMIC_DRAW_ARB
);
190 main(int argc
, char *argv
[])
192 glutInit(&argc
, argv
);
193 glutInitWindowSize(800, 200);
194 glutInitDisplayMode(GLUT_RGB
| GLUT_DOUBLE
);
195 Win
= glutCreateWindow(argv
[0]);
198 glutReshapeFunc(Reshape
);
199 glutKeyboardFunc(Key
);
200 glutDisplayFunc(Display
);
201 glutIdleFunc(Anim
? Idle
: NULL
);