OpenGL学习笔记之 uniform blocks

  构建Uniform blocks, 将此结构数据存入 buffer object, 性能会有很大的提高。 

这篇对uniform buffer object 的std140规则, uniform block赋值讲解的非常详细

https://learnopengl.com/#!Advanced-OpenGL/Advanced-GLSL

记录下书中的例子。以下是vertextShader:
#version 440 core

in vec4 position;

out VS_OUT
{
    vec4 color;
} vs_out;

// default block uniform 
uniform mat4 mv_matrix;

// uniform block 
//推荐的memory layout qualifier是 std140
//binding point 连接uniform block 与 buffer object
layout(std140, binding = 0) uniform TransformBlock
{
    mat4 proj_matrix;
}; 

void main()
{
    // mvp 变换
    gl_Position = proj_matrix * mv_matrix * position;
    vs_out.color = position * 2.0 + vec4(0.5, 0.5, 0.5, 0.0);
}

以下是Start()内:

// cube
    static const GLfloat vertex_positions[] =
    {
        -0.5f, -0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        0.5f,  0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
        -0.5f,  0.5f, -0.5f,

        -0.5f, -0.5f,  0.5f,
        0.5f, -0.5f,  0.5f,
        0.5f,  0.5f,  0.5f,
        0.5f,  0.5f,  0.5f,
        -0.5f,  0.5f,  0.5f,
        -0.5f, -0.5f,  0.5f,

        -0.5f,  0.5f,  0.5f,
        -0.5f,  0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
        -0.5f, -0.5f,  0.5f,
        -0.5f,  0.5f,  0.5f,

        0.5f,  0.5f,  0.5f,
        0.5f, -0.5f, -0.5f,
        0.5f,  0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        0.5f,  0.5f,  0.5f,
        0.5f, -0.5f,  0.5f,

        -0.5f, -0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        0.5f, -0.5f,  0.5f,
        0.5f, -0.5f,  0.5f,
        -0.5f, -0.5f,  0.5f,
        -0.5f, -0.5f, -0.5f,

        -0.5f,  0.5f, -0.5f,
        0.5f,  0.5f,  0.5f,
        0.5f,  0.5f, -0.5f,
        0.5f,  0.5f,  0.5f,
        -0.5f,  0.5f, -0.5f,
        -0.5f,  0.5f,  0.5f



    };

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    // vertex attribute
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);

    program = getProgram("vertexshader.glsl", "fragmentshader.glsl");

    // projection matrix
    proj_matrix = glm::perspective(50.0f, ((float)screenWidth ) / (screenHeight), 0.1f, 1000.0f);

    GLuint uboBuffer;
    glGenBuffers(1, &uboBuffer);
    glBindBuffer(GL_UNIFORM_BUFFER, uboBuffer);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), glm::value_ptr(proj_matrix), GL_STATIC_DRAW);

    //将buffer object 绑定到 索引缓冲区目标,即顶点着色器内binding的值
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, uboBuffer);

    glBindVertexArray(0);

以下是Render()内:

        GLfloat currentTime = glfwGetTime();
    deltaTime = currentTime - lastFrame;
    lastFrame = currentTime;

    GLfloat colors[] = {.3, 0.3, .3, 1.0};
    glClearBufferfv(GL_COLOR, 0, colors);
    glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);

    glBindVertexArray(vao);

    for (size_t i = 0; i < 24; i++)
    {
        glUseProgram(program);

        float f = (float)i + currentTime * 0.3f;

        // viewMatrix * rotate * translate
        mv_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -30.0f)) *
                    glm::rotate(glm::mat4(1.0f), 45.0f, glm::vec3(0.0f, 1.0f, 0.0f)) *
            glm::translate( glm::mat4(1.0f), glm::vec3(sinf(2.1f * f) * 2.0f,cosf(1.7f * f) * 2.0f,sinf(1.3f * f) * cosf(1.5f * f) * 2.0f)) *
                    camera.GetViewMatrix();

        // default block uniform 获取 location 后直接赋值
        glUniformMatrix4fv(glGetUniformLocation(program, "mv_matrix"), 1, GL_FALSE, glm::value_ptr(mv_matrix));

        glDrawArrays(GL_TRIANGLES, 0, 36);

        // 线框型cube
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }

    glBindVertexArray(0);

    //glViewport(0, 0, screenWidth / 2.0f, screenHeight / 2.0f);

编译后截图:
OpenGL学习笔记之 uniform blocks_第1张图片

你可能感兴趣的:(OpenGL)