Search code examples
c++openglshaderglfw

OpenGL program to draw a triangle gives a yellow screen


I am trying to draw a triangle with OpenGL.

My code compiles fine, and does not produce any errors but it still does not do what its supposed to.

I have a vertex shader and a fragment shader and both of them are in the same program.

My code is below:

#include "../../include/sb7.h"

GLuint compile_shaders(void)
{
    GLuint vertex_shader;
    GLuint fragment_shader;
    GLuint program;

    // Source code for Vertex Shader
    static const GLchar * vertex_shader_source[] =
    {
        "#version 450 core                                                  \n"
        "                                                                   \n"
        "void main(void)                                                    \n"
        "{                                                                  \n"
        "   //Decalre a hardcoded array of positions                        \n"
        "   const vec4 vertices[3] = vec4[3](vec4(0.25, -0.25, 0.5, 1.0),   \n"
        "                                    vec4(-0.25, -0.25, 0.5, 1.0),  \n"
        "                                    vec4(0.25, 0.25, 0.5, 1.0));   \n"
        "   //Index into our array using gl_VertexID                        \n"
        "   gl_Position = vertices[gl_VertexID];                            \n"
        "}                                                                  \n"
    };

    // Source code for Fragment Shader
    static const GLchar * fragment_shader_source[] =
    {
        "#version 450 core                                  \n"
        "                                                   \n"
        "out vec4 color;                                    \n"
        "                                                   \n"
        "void main(void)                                    \n"
        "{                                                  \n"
        "   color = vec4(0.0, 0.8, 1.0, 1.0);               \n"
        "}                                                  \n"
    };

    // Create and compiler Vertex Shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex_shader, 1, vertex_shader_source, NULL);
    glCompileShader(vertex_shader);

    // Create and compiler Fragment Shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment_shader, 1, fragment_shader_source, NULL);
    glCompileShader(fragment_shader);

    // Create program, attach shaders to it, and link it
    program = glCreateProgram();
    glAttachShader(program, vertex_shader);
    glAttachShader(program, fragment_shader);
    glLinkProgram(program);

    // Delete shaders as program has them now
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);

    return program;
};

class my_application : public sb7::application
{
public:

    void startup()
    {
        rendering_program = compile_shaders();
        glCreateVertexArrays(1, &vertex_array_object);
        glBindVertexArray(vertex_array_object);
    }

    void shutdown()
    {
        glDeleteVertexArrays(1, &vertex_array_object);
        glDeleteProgram(rendering_program);
        glDeleteVertexArrays(1, &vertex_array_object);
    }

    // Our rendering function
    void render(double currentTime)
    {
        // Sets Colour
        static const GLfloat color[] = { 0.0f, 0.2f, 0.0f, 1.0f };
        glClearBufferfv(GL_COLOR, 0, color);

        // Use program object we created for rendering
        glUseProgram(rendering_program);

        // Draw one triangle
        glDrawArrays(GL_TRIANGLES, 0, 3);
    }

private:

    GLuint rendering_program;
    GLuint vertex_array_object;
}; 

I am following the OpenGL Superbible, 7th edition.

The same program (with small changes) was also not drawing a point even when I changed the point size and the output was the same screen (full yellow) that I am getting for this.

I have seen similar problems that arise during drawing of triangles but they are all different from what I'm doing.

How do I fix this?


Solution

  • Workin' fine here:

    screenshot of blue triangle on dark green background

    All together:

    #include <GL/glew.h>
    #include <GLFW/glfw3.h>
    #include <iostream>
    #include <cstdarg>
    #include <cstdlib>
    
    struct Program
    {
        static GLuint Load( const char* shader, ... )
        {
            GLuint prog = glCreateProgram();
            va_list args;
            va_start( args, shader );
            while( shader )
            {
                const GLenum type = va_arg( args, GLenum );
                AttachShader( prog, type, shader );
                shader = va_arg( args, const char* );
            }
            va_end( args );
            glLinkProgram( prog );
            CheckStatus( prog );
            return prog;
        }
    
    private:
        static void CheckStatus( GLuint obj )
        {
            GLint status = GL_FALSE;
            if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
            if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
            if( status == GL_TRUE ) return;
            GLchar log[ 1 << 15 ] = { 0 };
            if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
            if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
            std::cerr << log << std::endl;
            exit( EXIT_FAILURE );
        }
    
        static void AttachShader( GLuint program, GLenum type, const char* src )
        {
            GLuint shader = glCreateShader( type );
            glShaderSource( shader, 1, &src, NULL );
            glCompileShader( shader );
            CheckStatus( shader );
            glAttachShader( program, shader );
            glDeleteShader( shader );
        }
    };
    
    const char* vert = R"GLSL(
    #version 450 core                                                
    void main(void)                                                  
    {                                                                
        //Decalre a hardcoded array of positions                      
        const vec4 vertices[3] = vec4[3]
            (
            vec4(0.25, -0.25, 0.5, 1.0), 
            vec4(-0.25, -0.25, 0.5, 1.0),
            vec4(0.25, 0.25, 0.5, 1.0)
            );
        //Index into our array using gl_VertexID                      
        gl_Position = vertices[gl_VertexID];                          
    }                                                                
    )GLSL";
    
    const char* frag = R"GLSL(
    #version 450 core                           
    out vec4 color;                             
    void main(void)                             
    {                                           
        color = vec4(0.0, 0.8, 1.0, 1.0);        
    }                                           
    )GLSL";
    
    int main( int argc, char** argv )
    {
        glfwInit();
    
        glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 4 );
        glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 5 );
        glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
        glfwWindowHint( GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE );
        GLFWwindow* window = glfwCreateWindow( 640, 480, "51307782", NULL, NULL );
        glfwMakeContextCurrent( window );
        glewInit();
        glfwSwapInterval( 1 );
    
        GLuint rendering_program = Program::Load
            (
            vert, GL_VERTEX_SHADER,
            frag, GL_FRAGMENT_SHADER,
            NULL
            );
    
        GLuint vertex_array_object = 0;
        glCreateVertexArrays( 1, &vertex_array_object );
        glBindVertexArray( vertex_array_object );
    
        while( !glfwWindowShouldClose( window ) )
        {
            glfwPollEvents();
    
            static const GLfloat color[] = { 0.0f, 0.2f, 0.0f, 1.0f };
            glClearBufferfv( GL_COLOR, 0, color );
            glUseProgram( rendering_program );
            glDrawArrays( GL_TRIANGLES, 0, 3 );
    
            glfwSwapBuffers( window );
        }
    
        glDeleteVertexArrays( 1, &vertex_array_object );
        glDeleteProgram( rendering_program );
    
        glfwDestroyWindow( window );
        glfwTerminate();
    }