2016-10-13 13 views
0

シェーダファイルの変更を検出するシステムを用意しました。シェーダが変更されたとき、頂点シェーダを言いましょう。そのシェーダをコンパイルして旧バージョンに置き換えます(ではなく、シェーダの入出力を変更して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文内で)すべてが消えてしまいます。私はリンクがすべてのバインディングを変更し、既存のものを無効にするため、何もレンダリングされないため、これが仮定されています。

シェーダプログラムでこのような特定のシェーダをホットスワップすることは可能ですか?

答えて

1

リンクは、プログラムではなくVAO状態の一部であるため、属性バインディングを無効にしません。属性のインデックスが変更される場合があります

  • :プログラムを再リンクする際happpen可能性が2つあります。これは、両方のシェーダ(layout (location=...))にコンパイルしたり、コンパイルとロードの間でそれらを固定することによって(glBindAttribLocation​)防ぐことができます。同じことが制服にも起こり、同じように扱うことができます。
  • ユニフォームの値が失われます。これは単に防止することはできませんが、フレームごとに設定することで問題を解決できます。
+0

はい!すべての属性のインデックスが変更されたため、何も表示されませんでした。私はすべての属性とバムを再リンクしました。 :) – Entalpi

関連する問題