#include "stdlib.h" #include <OpenGL/glext.h> #include <GLUT/GLUT.h> #define BUFFER_OFFSET(bytes) ((GLubyte*) NULL + (bytes)) #define VERTICES 0 #define INDICES 1 #define NUM_BUFFERS 6 GLuint buffers[NUM_BUFFERS]; GLfloat vertices[][3] = { {-1.0f,-1.0f,-1.0f}, {1.0f,-1.0f,-1.0f}, {1.0f,1.0f,-1.0f}, {-1.0f,1.0f,-1.0f}, {-1.0f,-1.0f,1.0f}, {1.0f,-1.0f,1.0f}, {1.0f,1.0f,1.0f}, {-1.0f,1.0f,1.0f} }; GLubyte indices[][4] = { {0,1,2,3}, {4,7,6,5}, {0,4,5,1}, {3,2,6,7}, {0,3,7,4}, {1,5,6,2} }; GLfloat* bdata; void changeSize(int w, int h) { glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,(double)w/(double)h,0.01,30); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyDown(unsigned char key, int x, int y) { switch (key) { case'b': bdata = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER,GL_READ_WRITE); for (int i =0; i <24; i ++) { *(bdata + i) *=1.1f; } glUnmapBuffer(GL_ARRAY_BUFFER); glutPostRedisplay(); break; } } void mouse(int button, int state, int x, int y) { } void display(void) { glLoadIdentity(); glTranslatef(0.0f,0.0f,-5.0f); glRotatef(30.0f,1.0f,1.0f,0.0f); // 6. 绘制, 这个地方注意的是最后一个参数,这个与普通的非VBO最大的不同就在这里 glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,BUFFER_OFFSET(0)); //glDrawArrays(GL_TRIANGLE_FAN, 0, 8); glutSwapBuffers(); } void init(void) { glClearColor(0.0f,0.0f,0.0f,0.0f); glShadeModel(GL_FLAT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //1. 创建缓冲区对象,系统会自动创建缓动区标示符放入到buffers中,可以使用glIsBuffer()函数,判断一个标示符是否被使用 glGenBuffers(NUM_BUFFERS ,buffers); //2. 激活缓冲区对象,绑定缓冲区对象表示未来选择的操作将影响哪个缓冲区。 如果要金融缓冲区对象,可以用0来作为缓冲区对象的标示符, 第一个参数target可以为GL_ARRAY_BUFFER,GL_ELEMENT_ARRAY_FUFFER glBindBuffer(GL_ARRAY_BUFFER,buffers[VERTICES]); //3. 用数据分配和初始化缓冲区对象 glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_DYNAMIC_DRAW); //4. 指定相对于缓冲区起始位置的偏移量 glVertexPointer(3,GL_FLOAT,0,BUFFER_OFFSET(0)); //5.一定不要忘记启动 glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[INDICES]); glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW); } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GL_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(512, 512); glutCreateWindow("Buffer Demo"); init(); glutReshapeFunc(changeSize); glutMouseFunc(mouse); glutKeyboardFunc(keyDown); glutDisplayFunc(display); glutMainLoop(); return 0; }