天天看点

opengl 独立着色器对象的使用

独立着色器对象,可以对管线的各个阶段进行动态组合,使得对某一个管线阶段的代码进行复用。

注意的问题:

获取uniform变量和设置uniform变量。设置的是某个程序对象的uniform而不是管线对象的。

例子代码:

创建

createShaderPipelineProgram(GLuint target, const char * src)
{
    GLuint object;
    GLint status;

    const char * shaderPrefix = "#version 440\n";
    const GLchar * fullSrc[] = {
        shaderPrefix,src
    };
    object = glCreateShaderProgramv(target, , (const GLchar **)fullSrc);
    glGetProgramiv(object, GL_LINK_STATUS, &status);

    if (!status)
    {
        GLint charsWritten, infoLogLength;
        glGetProgramiv(object, GL_INFO_LOG_LENGTH, &infoLogLength);
        char * infoLog = new char[infoLogLength];
        glGetProgramInfoLog(object, infoLogLength, &charsWritten, infoLog);
        LOGI("Error compiling %s:\n", GetShaderStageName(target));
        LOGI("Log: %s", infoLog);
        delete[] infoLog;

        glDeleteProgram(object);
        object = ;
    }
    return object;
}
           

渲染初始化

initRendering(void)
{
    //全局初始化
    glGenProgramPipelines(, &_tessPipeline);
    glBindProgramPipeline(_tessPipeline);
    CHECK_GL_ERROR();

    std::string tess_vertex = loadShaderSourceWithIncludeTag("",
        "shaders/tess_vertex.glsl");

    std::string tess_control = loadShaderSourceWithIncludeTag("",
        "shaders/tess_control.glsl");

    std::string terrain_tessellation = loadShaderSourceWithIncludeTag("",
        "shaders/tess_eval.glsl");

    std::string tess_frag = loadShaderSourceWithIncludeTag("",
        "shaders/tess_frag.glsl");

    LOGI("Compiling vertex shader\n");
    _tessVertexProg = createShaderPipelineProgram(GL_VERTEX_SHADER, tess_vertex.c_str());

    LOGI("Compiling frag shader\n");
    _tessFragmentProg = createShaderPipelineProgram(GL_FRAGMENT_SHADER, tess_frag.c_str());

    initQuadData();

    CHECK_GL_ERROR();
}
           

绘制

draw(nv::matrix4f & camera_matrix)
{
    glBindProgramPipeline(_tessPipeline);
    CHECK_GL_ERROR();
    glUseProgramStages(_tessPipeline,GL_VERTEX_SHADER_BIT, _tessVertexProg);
    CHECK_GL_ERROR();
    glUseProgramStages(_tessPipeline, GL_FRAGMENT_SHADER_BIT, _tessFragmentProg);
    CHECK_GL_ERROR();
    GLuint nmvp = glGetUniformLocation(_tessVertexProg, "mvp");
    if (nmvp!=-)
    {
        glProgramUniformMatrix4fv(_tessVertexProg, nmvp,,GL_FALSE, camera_matrix._array);
        CHECK_GL_ERROR();
    }
    glBindVertexArray(_quad_vao);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quad_index_buffer);
    glDrawElements(GL_TRIANGLE_STRIP, , GL_UNSIGNED_SHORT, NULL);
    CHECK_GL_ERROR();
    glBindVertexArray();
    glBindProgramPipeline();
}
           

顶点着色器

layout(location = ) in vec3 vs_in_vertex;
uniform mat4 mvp;

out gl_PerVertex{
    vec4 gl_Position;
};

void main() {
    gl_Position = mvp*vec4(vs_in_vertex, );
}
           

片元着色器

layout(location = ) out vec4 fragColor;

void main() {
    fragColor = vec4(, , , );
}
           
opengl 独立着色器对象的使用

继续阅读