8

複数の均一なバッファーを使用すると問題が発生します。

これが私のGLSLコードです:

layout(std140) uniform MaterialInfo {
    vec3 Ka;
    vec3 Ks;    
    vec3 Kd;
};


layout(std140) uniform LightInfo {
    vec3 La;
    vec3 Ls;
    vec3 Ld;
};

そして、これが私のバッファを作成して埋める方法です:

    blockIndex = glGetUniformBlockIndex(program, "MaterialInfo");
    if (blockIndex == -1) {
        fprintf(stderr, "Could not bind uniform block\n");
    }
    glGenBuffers(1, &materialUbo);
    glBindBuffer(GL_UNIFORM_BUFFER, materialUbo);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(MaterialBlock), &mesh->material, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, blockIndex, materialUbo);


    blockIndex = glGetUniformBlockIndex(program, "LightInfo");
    if (blockIndex == -1) {
        fprintf(stderr, "Could not bind uniform block\n");
    }
    glGenBuffers(1, &lightUbo);
    glBindBuffer(GL_UNIFORM_BUFFER, lightUbo);
    glBufferData(GL_UNIFORM_BUFFER, sizeof(LightBlock), &light->lightBlock, GL_DYNAMIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, blockIndex, lightUbo);

構造が次のように定義されている場合:

struct LightBlock { 
    glm::vec4 La;
    glm::vec4 Ld;
    glm::vec4 Ls;
};

struct MaterialBlock {
    glm::vec4 Ka;
    glm::vec4 Ks;
    glm::vec4 Kd;
};

このコードは、1つの均一なバッファーのみを使用する場合は正常に機能します。それがMaterialInfoです。lightInfoの2番目のバッファーを含めると、レンダリングの後半でglDrawElements()に到達したときにクラッシュします。

このような複数の均一なバッファーを使用することに問題はありますか?1つのUBOにすることはできますか?

4

2 に答える 2

13

glGetUniformBlockIndexそのようには機能しません。その特定の均一ブロックを識別する番号を取得します。に渡されるのは、均一なバッファバインディングインデックスではありませんglBindBufferRange/Base

UBOバインディングは、テクスチャバインディングとよく似ています。プログラムにどのスロットを調べるかを指示します。テクスチャを使用すると、テクスチャの均一な位置を取得し、その均一の値をテクスチャユニットインデックスに設定します。UBOを使用すると、ブロックのブロックインデックスを取得し、そのブロックインデックスのバインディング値を、それが表示される均一なバッファバインディングポイントに設定します。

したがって、インデックスを取得し、それglGetUniformBlockIndexを使用glUniformBlockBindingしてバッファバインディングポイントを割り当てる必要があります。次に、ユニフォームブロックに割り当てたバインディングポイントにバッファをバインドします。

于 2012-10-05T15:25:24.430 に答える
4

ニコルの答えを拡張するためだけに。ほとんどのサンプルは割り当てと使用法を混同しており、使用法スロットをハードコーディングして、サポートされるバッファーが1つだけになるようにします。これは非常に混乱し、自分で1日を失っただけです。

シェーダー初期化のセットアップ:

    m_ubo_transform_block_index = glGetUniformBlockIndex(m_gl_program_object, "transform_uniforms");
    if (m_ubo_transform_block_index != -1)
    {
        glUniformBlockBinding(m_gl_program_object, m_ubo_transform_block_index, UBO_TRANSFORM_INDEX);
    }

UBO_TRANSFORM_INDEXは、テクスチャユニットと同じようにスロットです。

ドロー時の使用法:

        if(m_ubo_transform_block_index != -1)
        {
            glBindBufferBase(GL_UNIFORM_BUFFER, UBO_TRANSFORM_INDEX, uniform_buffer->m_uniform_transform_buffer_object);
        }
于 2016-04-14T12:54:18.523 に答える