Search code examples
c++openglglslshader

Color does not work in starting examples opengl


The picture is small ( black) square , should be iridescent (changing colors drawn from one to the other) but why it is stupid to black.

Thus it from was drawn, instead of threw out an error.

here's the code for drawing a small black square.

basic.vert and basic.frag standart starting textbooks (first examles).

void My_TwoSquares()
{
    GLfloat vertires[] =
    {
        -0.2f, -0.2f, 0.0f,
        -0.2f, 0.2f, 0.0f,
        0.2f, 0.2f, 0.0f,
        0.2f, -0.2f, 0.0f,
    };
     // color 
    GLfloat cwet[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f,
        1.0f, 0.0f, 1.0f
    };

    GLuint indices[] =
    {
        0,1,2, 
        0,2,3  
    };

    GLuint iboHandle;
    GLuint vaoHandle;
    GLuint vboHandles[2];

    glGenBuffers(2, vboHandles);
    GLuint positionBufferHandle = vboHandles[0];
    GLuint colorBufferHandle = vboHandles[1];

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), vertires, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 12*sizeof(GLfloat), cwet, GL_STATIC_DRAW);

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

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    glBindBuffer(GL_ARRAY_BUFFER, positionBufferHandle);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    glGenBuffers(1, &iboHandle);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, iboHandle);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLuint), indices, GL_STATIC_DRAW);

    ShaderProgram shaderprogram;
    shaderprogram.loadShaders("basic.vert", "basic.frag");
    shaderprogram.use();

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

}

here is the Shaders basic.frag and basic.vert

basic.frag

#version 330 core

uniform vec4 vertColor;
out vec4 frag_color;

void main()
{
    frag_color = vertColor;
}

basic.vert

#version 330 core

layout (location = 0) in vec3 pos;

uniform vec2 posOffset;

void main()
{
        gl_Position = vec4(pos.x + posOffset.x, pos.y + posOffset.y, pos.z, 1.0);
}

enter image description here


Solution

  • In your shader code vertColor is a Uniform variable. This uniform variable is never set and the default initialization of the uniform variable is 0 for all components. This causes that the rectangle is painted in black.

    But you have vertex attributes. Each vertex coordinate is associated to a single color. You have to add an input to the Vertex Shader, for the color attribute (Vertex shader input).

    #version 330 core
    
    layout (location = 0) in vec3 pos;
    layout (location = 1) in vec3 color;
    

    This attribute has to be passed to the Fragment Shader, by an output of the vertex shader (Vertex shader output),

    out vec3 vColor;
    
    void main()
    {
        vColor = color;
        // [...]
    }
    

    to an input to the fragment shader (Fragment shader input):

    in vec3 vColor;
    

    The outputs of the vertex shader (like the color) are interpolated according to its position on the (triangle) primitive (Barycentric coordinates). The input to the fragment shader is the interpolated attribute.
    By this technique a gradient color can be achieved.

    Vertex shader

    #version 330 core
    
    layout (location = 0) in vec3 pos;
    layout (location = 1) in vec3 color;
    
    out vec3 vColor;
    
    uniform vec2 posOffset;
    
    void main()
    {
        vColor      = color;
        gl_Position = vec4(pos.x + posOffset.x, pos.y + posOffset.y, pos.z, 1.0);
    }
    

    Fragment shader

    #version 330 core
    
    in  vec3 vColor;
    out vec4 frag_color;
    
    void main()
    {
        frag_color = vec4(vColor.rgb, 1.0);
    }