MeIGuess
MeIGuess

Reputation: 33

Passing colour coords into a vertex shader through a vertex attrib pointer

I am trying to get vec3 colour data to a vertex shader (as an attrib pointer) , and then passing that into the fragment to be all settup .

It all started off by not being able to pass texture coords into the vertex shader . I've looked everywhere but not been able to find a definitive soloution . I can (by setting the colour manually in the vertex shader) , get a white square to renderer, but the colour data from the VAO cannot seem to be passed to it.

Also i'm certain that the shader loading system works . My best idea is that info is not being passed to the 'layout = 1' of the vertex shader, but I'm most likely wrong.

VAO / Buffer / shader settup

float vert[] = {
        //Vert Locs   Normal Coords
        -0.5f,-0.5f,  1.0f,1.0f,1.0f,  //0
         0.5f,-0.5f,  1.0f,1.0f,1.0f,  //1
         0.5f,0.5f,   1.0f,1.0f,1.0f,  //2
        -0.5f, 0.5f,  1.0f,1.0f,1.0f,  //3
    };


    unsigned int index[] = {
        0,1,2, //Order of drawing vertices
        2,3,0
    };

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

    unsigned int buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, 5 * 4 * sizeof(float), vert, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT,GL_FALSE, 5 * sizeof(float), 0);
    glVertexAttribPointer(1, 3,  GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2 * sizeof(float)));


    glEnableVertexAttribArray(0); // vao ^^

    unsigned int ibo;
    glGenBuffers(1, &ibo);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), index, GL_STATIC_DRAW);

    Shader v("VertexN.shader", GL_VERTEX_SHADER);
    Shader f("FragmentN.shader", GL_FRAGMENT_SHADER);

    unsigned int shaders2[] = {v.id, f.id};
    unsigned int program2 = Shader::getProgram(shaders2);

    glUseProgram(0);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

Render loop

glClearColor(0, 0, 0, 1);
        /* Render here */
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

        glUseProgram(program2);
        //tex.bind(slot);
        glBindVertexArray(vao);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); //Drawing mode, Type indecies , type of index buffer , pointer to index buffer

        glfwSwapBuffers(window);

        glfwPollEvents();

        glFlush();

        glBindVertexArray(0);
        glUseProgram(0);
        glActiveTexture(0);

Vertex shader

#version 330 core

layout(location = 0)in vec2 pos;
layout(location = 1)in vec3 normals;

out vec3 normal;

void main() {

    normal = normals;

    gl_Position = vec4(pos, 0.0f, 1.0f);

};

Fragment shader

#version 330 core

layout(location = 0)out vec4 colour;

in vec3 normal;

void main() {
    colour = vec4(normal, 1.0f);
};

Upvotes: 1

Views: 803

Answers (1)

derhass
derhass

Reputation: 45322

I have no idea what that source code comment here:

glEnableVertexAttribArray(0); // vao ^^

is supposed to mean. However, I get the impression that you misunderstood what this function does.

The GL manages a set of generic vertex attributes (the spec guarantees that there are at least 16, maybe more), and for each such attribute, the data can come from an array. Besides having to specify the attribute pointer and data formats, you also have to enable the array from each attribute individually. When a draw call is made, for each vertex index i, the GPU will fetch the i-the value in the attribute array for each attribute where the array is enabled. For attributes where the array is disabled, it will use a constant value throughout the whole draw call. (You can set it via the glVertexAttrib*() familiy of functions before issuing the draw call).

Since you never enable the array for attribute 1 (your normals input for the shader), all vertices will see the current value of attribute 1 - most likely just vec4(0) as that is the initial default, and you never seem to have changed it.

The solution of course is to enable all the attribute arrays you want to fetch from:

glEnableVertexAttribArray(1);

And, while you're at it: In your render loop, you have

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);

That is not necessary. The VAO will store this information already, there is no need to re-bind it for drawing.

Upvotes: 1

Related Questions