OpenGL:零活动制服

时间:2018-06-30 14:50:27

标签: pointers opengl

我指的是OpenGL SuperBible。我使用他们的框架来创建自己的程序。我想对接口块(特别是统一块)做一些事情。如果我打电话

glGetActiveUniformsiv(program, 1, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);

我得到一个错误,即GL_INVALID_VALUE。 但是,如果我用0而不是1调用同一函数,则不会发生该错误。当时我以为我没有活动制服。我应该有3个。 如何激活它们?这是我的着色器:

        #version 450 core                        
        layout (location = 0) in vec4 position;  
        layout (location = 1) in vec4 color;     
        out vec4 vs_color;                       
        uniform TransformBlock {                
            mat4 translation;                    
            mat4 rotation;                        
            mat4 projection_matrix;             
        };                                      
        void main(void)                          
        {                                        
            mat4 mvp = projection_matrix * translation * rotation ;    
            gl_Position = mvp * position;  
            vs_color = color;                   
        }                                       

在这里,我将通过“启动”方法为您提供一个基本的代码段:

    /////////////////////////////////

    vmath::mat4 transl_matrix = vmath::translate(0.0f, 0.0f, -3.0f);
    vmath::mat4 rot_matrix = vmath::rotate( 30.0f, 0.0f, 0.5f, 1.0f);
    vmath::mat4 proj_matrix = vmath::perspective(60.0f, (float)info.windowWidth / (float)info.windowHeight, 0.1f, 10.0f);


    //////////////////

    static const GLchar * uniformNames[3] = {
        "TransformBlock.translation",
        "TransformBlock.rotation",
        "TransformBlock.projection_matrix",
    };
    GLuint uniformIndices[3];
    glUseProgram(program);

    glGetUniformIndices(program, 3, uniformNames, uniformIndices);

    GLint uniformOffsets[3];
    GLint matrixStrides[3];
    glGetActiveUniformsiv(program, 3, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);
    glGetActiveUniformsiv(program, 3, uniformIndices, GL_UNIFORM_MATRIX_STRIDE, matrixStrides);

    unsigned char * buffer1 = (unsigned char*)malloc(4096);
    //GLuint * buffer1 = (GLuint *) malloc(4096);

    int j;
    for (int i = 0; i < 4; ++i) {
        GLuint offset = uniformOffsets[0] + matrixStrides[0] * i;
        for (j = 0; j < 4; ++j) {
            *((float *)(buffer1 + offset)) = transl_matrix[i][j];// 
            offset += sizeof(GLfloat);
        }
    }

    for (int i = 0; i < 4; ++i) {
        GLuint offset = uniformOffsets[1] + matrixStrides[1] * i;
        for (j = 0; j < 4; ++j) {
            *((float *)(buffer1 + offset)) = rot_matrix[i][j];
            offset += sizeof(GLfloat);
        }
    }

    for (int i = 0; i < 4; ++i) {
        GLuint offset = uniformOffsets[2] + matrixStrides[2] * i;
        for (j = 0; j < 4; ++j) {
            *((float *)(buffer1 + offset)) = proj_matrix[i][j];
            offset += sizeof(GLfloat);
        }
    }

    GLuint block_index = glGetUniformBlockIndex(program, "TransformBlock");
    glUniformBlockBinding(program, block_index, 0);
    glBindBufferBase(GL_UNIFORM_BUFFER, 0, (GLuint)buffer1);
    free(buffer1);

在此,我指的是上述《 SuperBible》的第5章(称为“数据”)。

但是,由于函数返回GL_INVALID_VALUE,因此调用出现错误:

*((float *)(buffer1 + offset)) = ...

,整个程序中断。不添加offset,我在这里没有收到错误,因此我认为第二个错误取决于第一个错误。

谢谢您的回答。

编辑:

我给您解决的任务现在可以正常工作。我已经更改了uniformNames变量。我现在有没有TransformBlock关键字的它们。但是,现在在我的render()函数中,使用glDrawArrays时出现了另一个错误。我将在此处显示我的render()函数:

virtual void render(double currentTime) {
    const GLfloat color[] = {(float)sin(currentTime)*0.5f + 0.5f, (float)cos(currentTime)*0.5f + 0.5f, 0.0f, 1.0f};
    glClearBufferfv(GL_COLOR, 0, color);
    glUseProgram(program);      
    glDrawArrays(GL_TRIANGLES, 0, 3);
}

错误消息是这样的:

Access violation by reading at position 0x00000125.

那是因为不是所有其他东西都在工作,还是我必须调用其他绘图函数而不是glDrawArrays吗?

1 个答案:

答案 0 :(得分:1)

我认为glGetUniformIndices出了问题,因为您在统一名称前加上了TransformBlock。您也不会使用它来访问GLSL代码中带有该前缀的制服。如果需要,您必须为统一块设置实例名称,而块名称与访问/命名统一根本无关。如果将访问同一接口块的多个着色器链接在一起,则仅用于匹配接口。