VBO: 显卡存储空间里的一块缓存区(Buffer),用于记录顶点的信息,包括法线,问路坐标等,这个Buffer有它的名字(VBO的ID),OpenGL在GPU的某处记录着这个ID和对应的显存地址(或者地址偏移,类似内存)。
VAO:是一个对象,其中包含一个或者更多的Vertex Buffer Objects,用于记录渲染对象的完整信息。
使用步骤如下:
1.生成VAO
void glGenVertexArrays( GLsizei n,GLuint *arrays);
2.绑定VAO
void glBindVertexArray(GLuint array);
3.产生VBOs
void glGenBuffers( GLsizei n,GLuint * buffers);
4.绑定VBOS
void glBindBuffer( GLenum target, GLuint buffer);
5.给VBO分配数据
void glBufferData( GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage);
6.给对应的顶点属性数组指定数据
void glVertexAttribPointer( GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * pointer);
7.设置Attribute变量,传递给shader
void glBindAttribLocation( GLuint program,GLuint index,const GLchar *name);
例:
绑定glsl中的变量到opengl程序中有两种方法:
1 xxx.vert
#version 130
in vec2 in_position;
in vec3 in_color;
若在glsl中直接定义变量,不指定索引,则需要在绑定程序后,用如下语句指定索引号:
glBindAttribLocation(progamHandle, 0, "in_position"); 指定变量in_position为0
glBindAttribLocation(progamHandle, 1, "in_color"); 指定变量in_color为1
方法1与方法2的写法效果相同
2. xxx.vert(在glsl130版本不生效,在glsl140版本才引入layout)
#version 130
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec3 in_color;
案例:
GLuint progamHandle;
GLuint vShader;
GLuint fShader;
vShader = glCreateShader(GL_VERTEX_SHADER);
fShader = glCreateShader(GL_FRAGMENT_SHADER);
if(0 == vShader || 0==fShader){
cout<<"vshader or fshader fail"<<endl;
return;
}
GLchar *vShaderCode = read_file("basic.vert");
GLchar *fShaderCode = read_file("basic.frag");
const GLchar *vCodeArray[1] = {vShaderCode};
const GLchar *fCodeArray[1] = {fShaderCode};
glShaderSource(vShader, 1, vCodeArray, NULL);
glShaderSource(fShader, 1, fCodeArray, NULL);
glCompileShader(vShader);
glCompileShader(fShader);
free(vShaderCode);
free(fShaderCode);
GLint logLen;
glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &logLen);
if(logLen > 0){
char *log = new char[logLen];
GLsizei written;
glGetShaderInfoLog(vShader, logLen, &written, log);
cout<<"shader compile error log: "<<log<<endl;
delete [] log;
}
progamHandle = glCreateProgram();
if(0 == progamHandle){
cout<<"error creating program"<<endl;
return;
}
glAttachShader(progamHandle, vShader);
glAttachShader(progamHandle, fShader);
glBindAttribLocation(progamHandle, 0, "in_position");
glBindAttribLocation(progamHandle, 1, "in_color");
glLinkProgram(progamHandle);
const GLfloat diamond[4][2] = {
{ 0.0, 1.0 },
{ 1.0, 0.0 },
{ 0.0, -1.0 },
{ -1.0, 0.0 }
};
const GLfloat colors[4][3] = {
{ 1.0, 0.0, 0.0 }, /* Red */
{ 0.0, 1.0, 0.0 }, /* Green */
{ 0.0, 0.0, 1.0 }, /* Blue */
{ 1.0, 1.0, 1.0 }
}; /* White */
GLuint vao, vbo[2];
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenVertexArrays(2, vbo);
glBindBuffer(GL_ARRAY_BUFFER ,vbo[0]);
glBufferData(GL_ARRAY_BUFFER, 8*sizeof(GLfloat), diamond, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, 12*sizeof(GLfloat), colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE ,3 * sizeof(GLfloat) ,0);
glEnableVertexAttribArray(1);
//glBindVertexArray(0); 解绑vao,保存之前的数据,网上例程添加此句,但130版本会导致无法显示出图片,其他版本不确定