1

I am trying to solve a bug with my excercice of VBO/OpenGL, but after some hours (days), I am unable to found what is wrong.

The problem is the windows stay black, the cube is not (correctly) drawn.

-

The OpenGL context seem to be correctly created for OpenGL 3.2

Vertex Shader:

#version 150 core
uniform mat4 RotationMatrix;
uniform mat4 ProjectionMatrix;

in vec3 in_Position;

void main(void)
{
    gl_Position = ProjectionMatrix * RotationMatrix * vec4(in_Position, 1.0);
}

VBO initialization:

// <-- Create OpenGL 3.2 context
// <-- Load Shaders
// <-- Set ClearColor, clearDepth, DepthFUnc, enable Depth
// <-- Set Viewport, init projection and modelview matrix.
float positionData[] = 
{
    -0.5f, 0.5f, -0.5f,
    0.5f, 0.5f, -0.5f,
    0.5f, -0.5f, -0.5f,
    -0.5f, -0.5f, -0.5f,
    -0.5f, 0.5f, 0.5f,
    0.5f, 0.5f, 0.5f,
    0.5f, -0.5f, 0.5f,
    -0.5f, -0.5f, 0.5f,
};

GLuint indexes[] = 
{
    0, 1, 2, 0, 2, 3,
    4, 5, 6, 4, 6, 7, 
    0, 3, 7, 0, 7, 4, 
    1, 5, 6, 1, 6, 2, 
    0, 4, 5, 0, 5, 1, 
    2, 3, 7, 2, 7, 6
};
glGenBuffers(2, vboHandles);
glBindBuffer( GL_ARRAY_BUFFER, vboHandles[0]);
glBufferData(GL_ARRAY_BUFFER, 24*sizeof(float), positionData, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles[1]); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 36*sizeof(GLuint), 
    indexes, GL_STATIC_DRAW);

In the OpenGL draw function:

//<--Clear buffer, set Uniform variables for projection and modelview

glBindBuffer(GL_ARRAY_BUFFER, vboHandles[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboHandles[1]);

glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, NULL);

//<-- Flush Opengl and swap buffers

Correct / Incorrect

Correctly drawn cube, without VBO Incorrectly drawn cube, with VBO

EDITED: Fragment shader:

#version 150 core
out vec4 out_Color;
void main(void){
    out_Color = vec4(1.0, 0.0, 0.0, 1.0f);
}

EDITED 2: Adding context creation

SDL_Window* window;
SDL_GLContext context;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
    return 0;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);

SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,  4);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,  1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,  16);

if ((window = SDL_CreateWindow( "Practica 4 and lot of stuff for the final prictice", 
    SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
    800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN)) == NULL)
{
    SDL_Quit();
    return 0;
}
if (NULL== (context = SDL_GL_CreateContext(window)))
{
    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

glewExperimental = GL_TRUE;
GLuint glewStatus = glewInit();
if (glewStatus != GLEW_OK)
{
    cout << "Error" << endl;
}
Adrian Maire
  • 14,354
  • 9
  • 45
  • 85
  • Your comment about flushing OpenGL and swapping buffers strikes me as odd... swapping buffers using any of the standard window APIs (e.g. GLX, CGL, EGL, WGL) implicitly flushes OpenGL's command queue. This implies that at minimum, swapping buffers is equivalent to calling `glFlush (...)` and it does not need to be done separately. In some implementations (e.g. Microsoft's GDI renderer) WGL even invokes `glFinish (...)` and waits for everything to finish before it returns when you swap buffers. – Andon M. Coleman Apr 21 '14 at 19:36
  • 1
    In the end, replacing important bits of code with comments like that makes it hard to diagnose your actual problem though. I can only assume that your comment means you are calling `glFlush (...)` and then `*SwapBuffers (...)`. – Andon M. Coleman Apr 21 '14 at 19:40

1 Answers1

1

Workin' fine here:

#include <GL/glew.h>
#include <GL/freeglut.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace glm;

#include <iostream>
using namespace std;


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;
        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( -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,
    uniform mat4 RotationMatrix;
    uniform mat4 ProjectionMatrix;

    in vec3 in_Position;

    void main(void)
    {
        gl_Position = ProjectionMatrix * RotationMatrix * vec4(in_Position, 1.0);
    }
);

const char* frag = GLSL
(
    150 core,
    out vec4 out_Color;
    void main(void){
        out_Color = vec4(1.0, 0.0, 0.0, 1.0f);
    }
);

GLuint vbo = 0;
GLuint ibo = 0;
void display()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    double ar = w / h;
    mat4 projection = glm::ortho< float >( -1 * ar, 1 * ar, -1.0, 1.0, -1.0, 1.0 );

    mat4 modelview = mat4( 1.0 );

    // prepare to render
    static GLuint prog = Program::Load( vert, NULL, frag );
    glUseProgram( prog );

    GLint proj = glGetUniformLocation( prog, "ProjectionMatrix" );
    glUniformMatrix4fv( proj, 1, GL_FALSE, glm::value_ptr( projection ) );

    GLint model = glGetUniformLocation( prog, "RotationMatrix" );
    glUniformMatrix4fv( model, 1, GL_FALSE, glm::value_ptr( modelview ) );

    float positionData[] = 
    {
        -0.5f, 0.5f, -0.5f,
        0.5f, 0.5f, -0.5f,
        0.5f, -0.5f, -0.5f,
        -0.5f, -0.5f, -0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f, -0.5f, 0.5f,
        -0.5f, -0.5f, 0.5f,
    };
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData( GL_ARRAY_BUFFER, sizeof( positionData ), positionData, GL_STREAM_DRAW );

    GLuint indexes[] = 
    {
        0, 1, 2, 0, 2, 3,
        4, 5, 6, 4, 6, 7, 
        0, 3, 7, 0, 7, 4, 
        1, 5, 6, 1, 6, 2, 
        0, 4, 5, 0, 5, 1, 
        2, 3, 7, 2, 7, 6
    };
    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo ); 
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indexes ), indexes, GL_STREAM_DRAW );

    GLint pos = glGetAttribLocation( prog, "in_Position" );
    glVertexAttribPointer( pos, 3, GL_FLOAT, GL_FALSE, 0, 0 );
    glEnableVertexAttribArray( pos );

    glDrawElements( GL_TRIANGLES, sizeof( indexes ) / sizeof( GLuint ), GL_UNSIGNED_INT, 0 );

    glutSwapBuffers();
}

int main(int argc, char **argv)
{
    glutInit( &argc, argv );
    glutInitContextVersion( 3, 2 );
    glutInitContextProfile( GLUT_CORE_PROFILE );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 600, 600 );
    glutCreateWindow( "GLUT" );

    glewExperimental = GL_TRUE;
    glewInit();

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

    glGenBuffers( 1, &vbo );
    glGenBuffers( 1, &ibo );

    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • I am currently looking for differences, I will accept and add a comment when I will found the exact problem. Thanks you. – Adrian Maire Apr 21 '14 at 19:30
  • 1
    My wrong was I missed the VAO, so the VBO was not linked to the shader. – Adrian Maire Apr 21 '14 at 22:36
  • 1
    @AdrianMaire: You must be using a ***core*** profile then. VAOs are not required in *compatibility* profiles. Your context profile is important information you should include in OpenGL 3.2+. – Andon M. Coleman Apr 21 '14 at 22:45
  • I did not know that was core profile, the context is created with SDL. Also, I include gl.h, not gl3.h – Adrian Maire Apr 22 '14 at 07:11