Can't draw triangle using Opengl

跟風遠走 提交于 2019-12-02 10:15:04
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:

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;
}

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!