Search code examples
c++openglglslshadervertex

How to send data to vertex shader with OpenGL?


I've got some problem with sending data to my vertex shader :

#version 450 core

layout (location = 5) in vec3 in_Vertex;
layout (location = 6) in vec3 in_Color;

in int gl_InstanceID;

layout (location = 0) uniform mat4 projection;
layout (location = 1) uniform mat4 modelview;
layout (location = 2) uniform float posX;
layout (location = 3) uniform float posY;
layout (location = 4) uniform uint posZ;

out vec4 v_color;

void main()
{

    float tmpX = posX;
    float tmpY = posY;
    uint tmpZ = posZ;

    gl_Position = projection * modelview * vec4(in_Vertex.x + tmpX*2, in_Vertex.y + tmpY*2, in_Vertex.z + tmpZ, 1.0) + vec4(in_Color, 0.0);

    v_color = vec4(in_Color,1.0);
}

The in_Vertex is working fine but the in_Color seems to have bad values, I send the data as :

glUseProgram(m_shaderPerso.getID());

    glBindBuffer(GL_ARRAY_BUFFER, m_vbo);

        glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
        glEnableVertexAttribArray(5);

            glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor));
            glEnableVertexAttribArray(6);

                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo);


                    glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(projection));
                    glUniformMatrix4fv(1, 1, GL_FALSE, glm::value_ptr(modelview));

                    for( auto &x : m_mapPos)
                    {
                        glUniform1f(2, x.second.getX());
                        glUniform1f(3, x.second.getY());
                        glUniform1ui(4, s_map->getHauteur(x.second.getXint(),x.second.getYint()));

                        glDrawElements(GL_TRIANGLES, m_tailleI, GL_UNSIGNED_BYTE, 0);
                    }


                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

            glDisableVertexAttribArray(6);

        glDisableVertexAttribArray(5);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

glUseProgram(m_shaderPerso.getID());

And I initialize the VBO with :

glGenBuffers(1, &m_vbo);

glBindBuffer(GL_ARRAY_BUFFER, m_vbo); //Verrouillage VBO

    glBufferData(GL_ARRAY_BUFFER, (tailleV * sizeof(float)) + (m_tailleI*3 * sizeof(float)), 0, GL_STATIC_DRAW); //Allocation memoire

    glBufferSubData(GL_ARRAY_BUFFER, 0, tailleV * sizeof(float), m_vertices); //Transfert données vertices

    glBufferSubData(GL_ARRAY_BUFFER, tailleV * sizeof(float), m_tailleI*3 * sizeof(float), m_color); //Transfert données couleurs

glBindBuffer(GL_ARRAY_BUFFER, 0);


glGenBuffers(1, &m_ibo); //Generation IBO (indices)

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibo); //Verrouillage IBO

    glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_tailleI * sizeof(GLubyte), 0, GL_STATIC_DRAW); //Allocation memoire

    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, m_tailleI * sizeof(GLubyte), m_indices); //Transfert données

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

I really don't know where my mistake is, so I gave you all the code that could be usefull. I do know that the arrays m_vertices, m_color and m_indices are correctly initialized, and the vertices are correctly display, so the VBO for the vertices and the indices are good in the VRAM. I probably done a mistake when I sended the data but I can't find it for 2 days, and I think that a new look could help me.

Thanks for reading and probably helping :)


Solution

  • Besides what @HolyBlackCat said, you are mixing interleaved mode with batch mode. When your are filling your buffer, you are using batch mode:

    glBindBuffer(GL_ARRAY_BUFFER, m_vbo); //Verrouillage VBO
    glBufferData(GL_ARRAY_BUFFER, (tailleV * sizeof(float)) + (m_tailleI*3 * sizeof(float)), 0, GL_STATIC_DRAW); //Allocation memoire
    glBufferSubData(GL_ARRAY_BUFFER, 0, tailleV * sizeof(float), m_vertices); //Transfert données vertices
    glBufferSubData(GL_ARRAY_BUFFER, tailleV * sizeof(float), m_tailleI*3 * sizeof(float), m_color); //Transfert données couleurs
    

    First you fill with vertices points, and, at the end of the buffer, with color attributes.

    But when you are using the buffer, you are using it in interleaved mode*:

    glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor));
    

    Choose one and stick with it.

    *in glVertexAttribPointer function, stride can have an incorrect value.

    Probably, you can solve your problem by changing:

    glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(m_offsetColor))
    

    to:

    glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), BUFFER_OFFSET(tailleV * sizeof(float)))