Problem with passing matrices with Uniform Buffer to shader

Hi! I’m learning OpenGL from OpenGL SuperBible (6 ed.) and I tried to wrote some code to practice Uniform Buffer Objects. I have some troubles with very basic code, I just want to pass matrix to vertex shader.

Vertex Shader:


static const GLchar* vs[] = {
        "#version 430 core                                           
"
        "                                                            
"
        "layout (location=0) in vec4 position;                       
"
        "                                                            
"
        "layout (binding = 1) uniform TransformBlock                 
"
        "{                                                           
"
        "    float curTime;                                          
"
        "     float mvp[4];                                          
"
        "} transformBlock;                                           
"
        "                                                            
"
        "out vec4 testColor;                                         
"
        "                                                            
"
        "void main(void)                                             
"
        "{                                                           
"
        "    testColor = vec4(0.0, transformBlock.mvp[0], 0.0, 1.0);
"
        "    gl_Position =  position;                                
"
        "}                                                           
"
    };

Fragment Shader:


static const GLchar* fs[] = {
        "#version 430 core                         
"
        "                                          
"
        "in vec4 testColor;                        
"
        "out vec4 color;                           
"
        "                                          
"
        "void main(void)                           
"
        "{                                         
"
        "    color = testColor;                    
"
        "}                                         
"
    };

And buffers initialization:

glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    vector<GLfloat> vertices = {
        -0.5f, -0.5f, -0.1f, 1.0f,
        0.5f, 0.5f, -0.1f, 1.0f,
        0.5f, -0.5f, -0.1f, 1.0f
    };

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertices.size(), &vertices[0], GL_STATIC_DRAW);
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnableVertexAttribArray(0);

    program = createShaderProgram();

    glGenBuffers(1, &ubo);
    glBindBuffer(GL_UNIFORM_BUFFER, ubo);

    static const char* uniformNames[2] = {
        "TransformBlock.curTime",
        "TransformBlock.mvp"
    };

    GLuint uniformIndices[2];

    glGetUniformIndices(program, 2, uniformNames, uniformIndices);

    GLint uniformOffsets[2];
    GLint arrayStrides[2];
    GLint matrixStrides[2];

    glGetActiveUniformsiv(program, 2, uniformIndices, GL_UNIFORM_OFFSET, uniformOffsets);
    glGetActiveUniformsiv(program, 2, uniformIndices, GL_UNIFORM_ARRAY_STRIDE, arrayStrides);
    glGetActiveUniformsiv(program, 2, uniformIndices, GL_UNIFORM_MATRIX_STRIDE, matrixStrides);

    GLubyte* buffer = new GLubyte[2048];

    *((float*)(buffer + uniformOffsets[0])) = 1.0f;

    GLfloat vec[] = { 1.0f, 0.0f, 1.0f, 1.0f};

    GLuint offset = uniformOffsets[1];
    for (int i = 0; i < 4; i++)
    {
        *((float*)(buffer + offset)) = vec[i];
        offset += arrayStrides[1];
    }

    glBufferData(GL_UNIFORM_BUFFER, sizeof(buffer), buffer, GL_STATIC_DRAW);
    glBindBufferBase(GL_UNIFORM_BUFFER, 1, ubo);

    //delete[] buffer;

mvp meant to be a 4x4 matrix, but no triangle was displayed, so I switched to an array to do some testing.

When I changed passing data to glSubBufferData I could pass vector or single float as they don’t use strides and triangle was rendered. When I used matries or array of floats, nothing was rendered.

Could you help?

buffer is a pointer. If you ask for the size of a pointer, you get the size of a pointer. Just use a std::vector if you want to keep track of the size of the array.

Thanks alot! I’m pretty sure I wouldn’t find this mistake for many hours. Cheers!