Phoebus
Phoebus

Reputation: 321

Vertex shader not passing value to fragment shader

I've encountered following problem:

I got this vertex shader:

#version 410 core

in vec3 vertex_position;

out vec3 color;

void main()
{
    color = vec3(0.0, 0.0, 0.0);
    gl_Position = vec4(vertex_position, 1.0);
}

And following fragment shader:

#version 410 core

in vec3 color;

out vec4 frag_color;

void main()
{
    frag_color = vec4(color, 1.0);
}

I want to pass the color vector from the vertex shader to the fragent shader, however, nothing is showing up on the screen. When I set the frag_color within the fragment shader like: frag_color = vec4(0.0, 0.0, 0.0, 1.0); it works. Thus, something with passing the value between the 2 stages must be wrong.

This is my shader code:

void Shader::CreateShaders(std::string filePathVert, std::string filePathFrag)
{
    // setup shaders
    std::string vertex_shader_source   = LoadSourceFile(filePathVert);
    std::string fragment_shader_source = LoadSourceFile(filePathFrag);
    const GLchar* vs_source = vertex_shader_source.c_str();
    const GLchar* fs_source = fragment_shader_source.c_str();

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vs_source, NULL);
    glCompileShader(vs);
    CheckShaderError(vs, GL_COMPILE_STATUS, false, "Error: Shader compilation failed: ");

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fs_source, NULL);
    glCompileShader(fs);
    CheckShaderError(fs, GL_COMPILE_STATUS, false, "Error: Shader compilation failed: ");

    this->shader_program = glCreateProgram();
    glAttachShader(this->shader_program, fs);
    glAttachShader(this->shader_program, vs);
    glLinkProgram(this->shader_program);
    CheckValidationError(this->shader_program);

    glDeleteShader(vs);
    glDeleteShader(fs);
}

void Shader::Bind()
{
    glUseProgram(this->shader_program);
}

void Shader::Destroy()
{
    glDeleteProgram(this->shader_program);
}

static std::string LoadSourceFile(std::string filePath)
{
    std::ifstream ifs(filePath);
    std::string content( (std::istreambuf_iterator<char>(ifs) ),
                        (std::istreambuf_iterator<char>()    ) );

    if(content.empty())
    {
        std::cerr << "source file was empty or not correctly loaded\n";
    }

    return content;
}

And my drawing code:

GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);

glBindBuffer(GL_ARRAY_BUFFER, vbo_positions);
glVertexAttribPointer(glGetAttribLocation(shader.GetProgramID(), "vertex_position"), 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
glVertexAttribPointer(glGetAttribLocation(shader.GetProgramID(), "vertex_color"), 3, GL_FLOAT, GL_FALSE, 0, NULL);


while(!glfwWindowShouldClose(display.GetWindowID())) {
    display.UpdateFPSCounter();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    shader.Bind();
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    update();

    glfwSwapBuffers(display.GetWindowID());
    display.CheckWindowShouldClose();
}

Does anyone see what I'm doing wrong?

Thanks in advance!

Upvotes: 1

Views: 1178

Answers (2)

Reto Koradi
Reto Koradi

Reputation: 54652

The problem is here:

glEnableVertexAttribArray(0);
glVertexAttribPointer(glGetAttribLocation(shader.GetProgramID(), "vertex_position"),
                      3, GL_FLOAT, GL_FALSE, 0, NULL);

Both of these calls take the attribute location as the first argument. While the location for the position may happen to be 0, this is not guaranteed, and you should pass the same argument to both these calls:

GLuint posLoc = glGetAttribLocation(shader.GetProgramID(), "vertex_position");
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, NULL);

Upvotes: 0

Poriferous
Poriferous

Reputation: 1582

vertex_color doesn't match the variable in your vertex shader.

Upvotes: 1

Related Questions