Can't draw triangle using Opengl

前端 未结 2 763
死守一世寂寞
死守一世寂寞 2021-01-28 14:34

in this code i want to draw a simple triangle on a blue background using openGL however when i compile and run the code only a window with the blue background appears (without t

相关标签:
2条回答
  • 2021-01-28 15:25
    glClearColor(0, 0, 1,1);
    ...
    fColor = vec4(0.0, 0.0, 1.0, 1.0);
    

    You're trying to draw a blue triangle on top of a blue background. You'll have to dial up your contrast pretty high to see that :)

    Make one of them a different color, like red.

    You're also:

    • Missing a VAO
    • Not requesting a Core context
    • Using #version 320 core instead of #version 150 core

    Try this:

    #include <GL/glew.h>
    #include <GL/freeglut.h>
    #include <vector>
    #include <iostream>
    
    struct Program
    {
        static GLuint Load( const char* vert, const char* geom, const char* frag )
        {
            GLuint prog = glCreateProgram();
            if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
            if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
            if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
            glLinkProgram( prog );
            CheckStatus( prog );
            return prog;
        }
    
    private:
        static void CheckStatus( GLuint obj )
        {
            GLint status = GL_FALSE, len = 10;
            if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
            if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
            if( status == GL_TRUE ) return;
            if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
            if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
            std::vector< char > log( len, 'X' );
            if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
            if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
            std::cerr << &log[0] << std::endl;
            exit( -1 );
        }
    
        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 );
        }
    };
    
    #define GLSL(version, shader) "#version " #version "\n" #shader
    
    const char* vert = GLSL
    ( 
        150 core,
        layout(location = 0) in vec4 vPosition;
        void
        main()
        {
            gl_Position = vPosition;
        }
    );
    
    const char* frag = GLSL
    ( 
        150 core,
        out vec4 fColor;
        void
        main()
        {
            fColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
    );
    
    // VAO & VBO objects
    GLuint VAO;
    GLuint VBO;
    GLuint prog;
    void init()
    {
        // vertex Data (position)
        float vertex[] = { -1.0, -1.0 , 0.0,
                            1.0, -1.0 , 0.0,
                            0.0,  1.0 , 0.0 };
    
        glGenVertexArrays( 1, &VAO );
        glBindVertexArray( VAO );
    
        glGenBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);
    
        prog = Program::Load( vert, NULL, frag );
        glUseProgram( prog );
    
        glEnableVertexAttribArray(0);
        glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
    }
    
    void display()
    {
        glClearColor(0, 0, 1,1);
        glClear(GL_COLOR_BUFFER_BIT);
    
        // Drawing the triangle
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glutSwapBuffers();
    }
    
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
        glutInitWindowSize(1000, 400);
        glutInitWindowPosition(100, 100);
        glutInitContextVersion(3, 2);
        glutInitContextProfile(GLUT_CORE_PROFILE);
        glutCreateWindow("My First GLUT/OpenGL Window");
    
        glewExperimental = GL_TRUE;
        if( GLEW_OK != glewInit() )
            return -1;
    
        init();
    
        glutDisplayFunc(display);
        glutMainLoop();
        return 0;
    }
    

    EDIT: Ported to GL 2.1:

    #include <GL/glew.h>
    #include <GL/glut.h>
    #include <vector>
    #include <iostream>
    
    struct Program
    {
        static GLuint Load( const char* vert, const char* geom, const char* frag )
        {
            GLuint prog = glCreateProgram();
            if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
            if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
            if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
            glLinkProgram( prog );
            CheckStatus( prog );
            return prog;
        }
    
    private:
        static void CheckStatus( GLuint obj )
        {
            GLint status = GL_FALSE, len = 10;
            if( glIsShader(obj) )   glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
            if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, &status );
            if( status == GL_TRUE ) return;
            if( glIsShader(obj) )   glGetShaderiv( obj, GL_INFO_LOG_LENGTH, &len );
            if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, &len );
            std::vector< char > log( len, 'X' );
            if( glIsShader(obj) )   glGetShaderInfoLog( obj, len, NULL, &log[0] );
            if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
            std::cerr << &log[0] << std::endl;
            exit( -1 );
        }
    
        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 );
        }
    };
    
    #define GLSL(version, shader) "#version " #version "\n" #shader
    
    const char* vert = GLSL
    ( 
        120,
        attribute vec4 vPosition;
        void main()
        {
            gl_Position = vPosition;
        }
    );
    
    const char* frag = GLSL
    ( 
        120,
        void main()
        {
            gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
    );
    
    // VBO objects
    GLuint VBO;
    GLuint prog;
    void init()
    {
        // vertex Data (position)
        float vertex[] = { -1.0, -1.0 , 0.0,
                            1.0, -1.0 , 0.0,
                            0.0,  1.0 , 0.0 };
    
        glGenBuffers(1,&VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);
    
        prog = Program::Load( vert, NULL, frag );
        glUseProgram( prog );
    
        int posLoc = glGetAttribLocation( prog, "vPosition" );
        glEnableVertexAttribArray( posLoc );
        glVertexAttribPointer( posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0 );
    }
    
    void display()
    {
        glClearColor(0, 0, 1,1);
        glClear(GL_COLOR_BUFFER_BIT);
    
        // Drawing the triangle
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glutSwapBuffers();
    }
    
    int main(int argc, char** argv)
    {
        glutInit(&argc, argv);
        glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
        glutInitWindowSize(1000, 400);
        glutInitWindowPosition(100, 100);
        glutCreateWindow("My First GLUT/OpenGL Window");
    
        if( GLEW_OK != glewInit() )
            return -1;
    
        init();
    
        glutDisplayFunc(display);
        glutMainLoop();
        return 0;
    }
    
    0 讨论(0)
  • 2021-01-28 15:25

    You have provided invalid buffer size in the following line:

    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(vertex), vertex, GL_STATIC_DRAW);
    

    Because sizeof(vertex) should return the total size of the array (e.g 36) not the underlying type, thus no need to multiply by 9. If you still want to use multiplication try following:

    9 * sizeof(float)
    

    I have to write this down... You should separate your initialization and draw cycle like in genpfault's answer.

    0 讨论(0)
提交回复
热议问题