OpenGL学习八:缓冲区对象

来源:互联网 发布:sql字符串拼接赋值 编辑:程序博客网 时间:2024/05/01 21:39
产生原因
OpenGL是按照CS结构设计的,当OPENGL需要数据的时候,必须从客户机内存传递到服务器,如果客户机和服务器属于不同的计算机,这样的数据效率缓慢,并且有时是冗余的做法
1.创建缓冲区对象
glGenBuffers(NUM_BUFFER,buffers);
2.激活缓冲区对象
glBindBuffer(target,buffer);
GL_ARRAY_BUFFER //坐标,颜色 等
GL_ELEMENT_ARRAY_BUFFER //索引坐标
GL_TEXTURE_BUFFER//纹理缓冲
……
3.用数据分配和初始化缓冲区对象
glBufferData(target,size,data,usage)

usage:
#define GL_STREAM_DRAW 0x88E0
#define GL_STREAM_READ 0x88E1
#define GL_STREAM_COPY 0x88E2
#define GL_STATIC_DRAW 0x88E4
#define GL_STATIC_READ 0x88E5
#define GL_STATIC_COPY 0x88E6
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_DYNAMIC_READ 0x88E9
DRAW: 客户机指定了用于渲染的数据
READ:从OPENGL缓冲区读取数据值,并且在应用程序中用于各种鱼渲染不直接相关的计算过程
COPY:从OPENGL缓冲区读取数据值,作为用于渲染的数据

STREAM:缓冲区对象中数据需要经常更新,但是作为绘图或其他操作使用较少
STATIC:缓冲区数据只指定1次,但是这些数据使用频率非常高
DYNAMIC:缓冲区数据常常更新,并且使用频率也很高
4.激活顶点数组
5.为顶点数组指定数据,这里指定的数据在服务器存储的内存地址


glGenBuffers(NUM_BUFFER,buffers);
glBindBuffer(GL_ARRAY_BUFFER,buffers[VERTICES]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glVertexPointer(3,GL_FLOAT,0,0);
glEnableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER,buffers[COLOR]);
glBufferData(GL_ARRAY_BUFFER,sizeof(colors),colors,GL_STATIC_DRAW);
glColorPointer(3,GL_FLOAT,0,0);
glEnableClientState(GL_COLOR_ARRAY);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,buffers[INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);缓冲区数据更改

方法1:
glBufferSubData(Glenum target,GLintptr offset,Glsizeiptr size,const Glvoid* data)
用data指向数据更新target相关联的当前绑定缓冲区的对象中offset开始的size个字节数据

方法2:
使用glMapBuffer返回一个指向缓冲区对象的指针,可以在这个缓冲区写入新值。在完成了对缓冲区对象的数据更新之后,可以调用glUnmapBuffer(target)取消都这个缓冲区的映射。
数据在缓冲区对象向之间复制
void glCopyBufferSubData(GLenum readbuffer,GLenum writebuffer,GLinrptr readoffset,GLinrptr writeoffset,Glsizeiptr size)
Glvoid* glMapBuffer(target,access)
target:当前绑定缓冲区对象的数据存储
accrss: GL_READ_ONLY
        GL_WRITE_ONLY
        GL_WRITE_READ_ONLY

glIsBuffer 查看缓冲区是否已被绑定
glDeleteBuffers 清空缓冲区对象
glUnmapBuffer(target) 对数据存储访问之后,调用取消对这个缓冲区的映射

 

#include "header.h"#define VERTICES 0#define COLOR 1#define INDICES 2#define NUM_BUFFER 3GLuint buffers[NUM_BUFFER];float quard=0; GLfloat vertices[][3]={{0,0,50},//0{100,0,50},//1{100,100,50},//2{0,100,50},//3{0,0,-50},//4{100,0,-50},//5{100,100,-50},//6{0,100,-50}//7}; GLfloat colors[][3]={{1.0,0.2,0.2}, {0.2,0.2,1.0}, {0.8,1.0,0.2}, {0.75,0.75,0.75}, {0.35,0.35,0.35}, {0.5,0.5,0.5}, {0.3,0.4,0.5}, {0.5,0.6,0.7}};GLubyte indices[][4]={{3,2,1,0},{7,6,5,4},{7,4,0,3},{6,5,1,2},{7,3,2,6},{0,4,5,1}};void display(void){glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glRotatef(quard,1,1,0);glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,0);glFlush();glutSwapBuffers();}void rotate(){quard+=0.1;glutPostRedisplay();}void mouse(int button,int state,int x,int y){switch(button){case GLUT_LEFT_BUTTON:if(GLUT_DOWN==state){glutIdleFunc(rotate);}else{//glutIdleFunc(0);}}}void init(){glClearColor(0.0,1.0,0.0,0.0);glClearDepth(1.0);glViewport(0,0,600,480);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LEQUAL);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-300,300,-100,380,-100,100);glMatrixMode(GL_MODELVIEW);glewInit();glGenBuffers(NUM_BUFFER,buffers);glBindBuffer(GL_ARRAY_BUFFER,buffers[VERTICES]);glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);glVertexPointer(3,GL_FLOAT,0,0);glEnableClientState(GL_VERTEX_ARRAY);glBindBuffer(GL_ARRAY_BUFFER,buffers[COLOR]);glBufferData(GL_ARRAY_BUFFER,sizeof(colors),colors,GL_STATIC_DRAW);glColorPointer(3,GL_FLOAT,0,0);glEnableClientState(GL_COLOR_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(GLUT_DOUBLE|GLUT_RGB);glutInitWindowSize(600,480);glutInitWindowPosition(100,100);glutCreateWindow("缓冲区对象");init();glutDisplayFunc(display);glutMouseFunc(mouse);glutMainLoop();return 0;}


 

0 0