c++ - 在着色器程序中重新编译、重新链接、顶点着色器

标签 c++ opengl shader

我有一个系统来检测对我的着色器文件所做的更改。当着色器发生变化时,比方说顶点着色器,我想编译那个着色器并将其替换为旧版本(同时更改着色器的输入/输出,从而重用 VAO、VBO等)。

std::pair<bool, std::string> Shader::recompile() {
std::string vertex_src = load_shader_source(vertex_filepath);

glDetachShader(gl_program, vertex_shader); // gl_program is a GLuint for the shader program
glDeleteShader(vertex_shader);

vertex_shader = glCreateShader(GL_VERTEX_SHADER);

auto raw_str = vertex_src.c_str();
glShaderSource(vertex_shader, 1, &raw_str, NULL);

glCompileShader(vertex_shader);

GLint vertex_shader_status;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &vertex_shader_status);

GLint fragment_shader_status = 1;

if (vertex_shader_status == 1) {
    glAttachShader(gl_program, vertex_shader);
    // glLinkProgram(gl_program);

    // Logging - mostly irrelevant to the question
    GLint is_linked = 0;
    glGetProgramiv(gl_program, GL_LINK_STATUS, &is_linked);
    SDL_Log("Shader relinking is success: %i", is_linked == GL_TRUE);

    std::string err_log = "";
    GLint max_log_lng = 0;
    glGetProgramiv(gl_program, GL_INFO_LOG_LENGTH, &max_log_lng);
    err_log.reserve(max_log_lng);
    glGetProgramInfoLog(gl_program, max_log_lng, NULL, (char *) err_log.c_str());
    SDL_Log("%s", err_log.c_str());

    return {true, ""};
}

使用这种方法的结果是什么都没有改变,但是当我链接程序时(在 if 语句内)它就消失了。我假设这是因为链接更改了所有绑定(bind),从而使现有绑定(bind)无效,导致根本没有呈现任何内容。

那么,是否可以在着色器程序中像这样热交换特定着色器?

最佳答案

链接不会使任何属性绑定(bind)无效,因为它们是 VAO 状态的一部分,而不是程序的一部分。重新链接程序时可能会发生两件事:

  • 属性的索引可能会改变。这可以通过在两个着色器中修复它们 (layout (location=...)) 或在编译和加载之间修复它们 (glBindAttribLocation ) 来防止。同样的事情也可能发生在制服上,可以用同样的方式处理。
  • 制服的值(value)丢失了。这不能简单地避免,但在每一帧中设置它们应该可以解决问题。

关于c++ - 在着色器程序中重新编译、重新链接、顶点着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40019000/

相关文章:

c++ - 项目文件的树

c++ - 超过三次函数根二分搜索时间限制

c++ - 对 'imp____glewEnableVertexAttribArray' 的 undefined reference

ios - 为什么我的场景相机在使用 SCNTechnique 时只显示黑屏?

c++ - 如何在 OpenGL 中制作好看的 cel 着色线?

c++ - 在 for... 循环中使用 short 而不是 int 的好处

c++ - 通过索引访问 map 值?

c++ - 为什么尽管源代码没有变化,但一个系统与另一个系统的碎片数量却有很大差异?

c++ - 使用 glTexCoordPointer() 的问题

opengl-es - 自从将 SKShader 添加到 Sprite 后,如何计算当前时间?