opengl 独立着色器对象的使用

本文介绍了一种使用独立着色器对象的方法,通过这种方式可以在不同的管线阶段复用着色器代码。文中提供了创建和使用独立着色器的示例代码,并详细展示了如何通过设置uniform变量来控制着色器的行为。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

例子代码:
创建

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

    const char * shaderPrefix = "#version 440\n";
    const GLchar * fullSrc[2] = {
        shaderPrefix,src
    };
    object = glCreateShaderProgramv(target, 2, (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 = 0;
    }
    return object;
}

渲染初始化

initRendering(void)
{
    //全局初始化
    glGenProgramPipelines(1, &_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!=-1)
    {
        glProgramUniformMatrix4fv(_tessVertexProg, nmvp,1,GL_FALSE, camera_matrix._array);
        CHECK_GL_ERROR();
    }
    glBindVertexArray(_quad_vao);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _quad_index_buffer);
    glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, NULL);
    CHECK_GL_ERROR();
    glBindVertexArray(0);
    glBindProgramPipeline(0);
}

顶点着色器

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

out gl_PerVertex{
    vec4 gl_Position;
};

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

片元着色器

layout(location = 0) out vec4 fragColor;

void main() {
    fragColor = vec4(0.5, 0.5, 0.5, 1.0);
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值