opengl3.x之glsl数据传递VAO,VBO

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版本会导致无法显示出图片,其他版本不确定

猜你喜欢

转载自blog.csdn.net/zhouchao_0321/article/details/82695364