Question

Im failing to draw using a VBO.

Iv used this code successfully to draw using a vertex array, but when i try to pop it into a vbo and draw it im just getting a blank white screen.

Iv tried adding the initialization of the vbo to the glutinit function, but that causes a break. Iv also tried calling the VBO initialization in a separate func only once to see if making the VBO multiple times was causing the issue, and iv also stripped my proj down to just rendering this to see if that would work; but alas im still coming up trumps with the white screen.

  • just a note, i have read that this could be a issue to do with my card drivers not supporting the > OGL 2.0 ( knowing my luck there is nothing wrong with my code and this is the case)

    float f[] = {0, 2, -4, -2, -2, -4, 2, -2, -4};
    GLuint vbo;
    
    void DisplayGL()  // the update display callback?
    {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear out the stuff from the old window.     
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    //translate and rotate SWAP X AND Y DERP
    glRotatef(camera->rot.x, 0.0f, 1.0f, 0.0f); // deg, xflag, yflag, zflag
    glRotatef(camera->rot.y, 1.0f, 0.0f, 0.0f); // deg, xflag, yflag, zflag
    glTranslatef(camera->pos.x, camera->pos.y, camera->pos.z); // move us back a bit
    
    glGenBuffers(1, &vbo); // make a buffer
    glBindBuffer(GL_ARRAY_BUFFER, vbo); // bind the buffer - type, buffer add
    glBufferData(GL_ARRAY_BUFFER, sizeof(f), f, GL_STATIC_DRAW); //type, size of the data, the data, flag (GL_A_B)
    
    glBindBuffer(GL_ARRAY_BUFFER, vbo); // rebind?
    
    glEnableClientState(GL_VERTEX_ARRAY); // enable the client state 
    
    glVertexPointer(3, GL_FLOAT, sizeof(float), 0); // how may elemets per vertex, data type, how many bytes between vertex, starting point of data
    
    glDrawArrays(GL_TRIANGLES, 0, 3); // draw type, starting point (vertex), how many vertex
    
    glDisableClientState(GL_VERTEX_ARRAY); // disable the client state
    
    // render some text
    std::string text = "Mouse x, y: " + std::to_string(testx) + ", " + std::to_string(testy);
    drawText(text.data(), text.length(), 0, 575);
    
    text = "Cam x, y rotation: " + std::to_string(camera->rot.x) + ", " + std::to_string(camera->rot.y);
    drawText(text.data(), text.length(), 0, 560);
    
    glutSwapBuffers(); // swap our active buffer to our unactive buffer
    

    }

-one other quick question while im at it, i use GLM (opengl math lib). I was wondering if an vector of glm::vec3 can be used instead of an array or vector of floats. And if it can be, is there anything special you need to tell openGL for it to use the data inside the glm::vec3 datatype? i only ask since its data with in a struct and is accessed like this with in a for loop (*i).x ... etc not accessible like a standard array or vector of floats like: (*i)

Edit-

Here is the stripped down main with the issue:

#include <iostream>
#include <vector>

#include "..\..\externals\glm\glm\glm.hpp" // openGL Math header.
#include <gl/glew.h> // include glew depend's
#define FREEGLUT_STATIC     // defign the lib for glut
#include <gl/freeglut.h> // include glut

int g_iWindowWidth = 800; // our global window width and height
int g_iWindowHeight = 600;

int g_hWindowHandle = 0;  // out handler for our main window

void initGLUT(int argc, char* argv[]);  // the initalise func for glut

//call back funcs
void DisplayGL();  // the update display func callback's
void IdleGL(); // idle function

GLuint vbo;
std::vector< glm::vec3 > verts;

void makeVbo();

int main(int argc, char* argv[])
{
    verts.push_back(glm::vec3(0, 2, -4));
    verts.push_back(glm::vec3(-2, -2, -4));
    verts.push_back(glm::vec3(2, -2, -4));

    initGLUT(argc, argv); // initalise glut
    makeVbo(); // ***no matter where this is placed, i get a break or a white screen?***
    glutMainLoop(); // run our grafix
}

void initGLUT(int argc, char* argv[])
{
    glutInit(&argc, argv); // initalise the widow with out global params

    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); // when we close the window return to the main func or previous func

    int iScreenWidth = glutGet(GLUT_SCREEN_WIDTH); // our window W and H
    int iScreenHeight = glutGet(GLUT_SCREEN_HEIGHT);

    glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA | GLUT_DOUBLE | GLUT_DEPTH); // rgb with alpha and a depth to our view

    glutInitWindowPosition((iScreenWidth - g_iWindowWidth) / 2, (iScreenHeight - g_iWindowHeight) / 2); // set the window pos on screen
    glutInitWindowSize(g_iWindowWidth, g_iWindowHeight); // windwow size

    g_hWindowHandle = glutCreateWindow("My OpenGL Template!"); // title & our window_H

    glutDisplayFunc(DisplayGL); // bind callback functions
    glutIdleFunc(IdleGL);

    glEnable(GL_DEPTH_TEST);
}

void DisplayGL()  // the update display func callback?
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear out the stuff from the old window.

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    //translate

    glTranslatef(0, 0,-6); // move us back a bit

    glEnableClientState(GL_VERTEX_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableClientState(GL_VERTEX_ARRAY);

    glutSwapBuffers(); // swap our active buffer to our unactive buffer
}
void IdleGL() // logic here
{
    glutPostRedisplay(); // redrawwindow
}
void makeVbo()
{
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData
        (
        GL_ARRAY_BUFFER,
        sizeof(glm::vec3) * verts.size(),
        &verts[0],
        GL_STATIC_DRAW
        );
}

Edit 2- Been at this all day looking around and fiddling. seems alot of comments say to call glewinit(); before making the vbo to make sure gl call pointers are correct.

void makeVbo()
{

    glewInit();
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData
        (
        GL_ARRAY_BUFFER,
        sizeof(glm::vec3) * verts.size(),
        &verts[0],
        GL_STATIC_DRAW
        );
}

This works now if its called within the main as shown in my previous edit, but the screen is a blank black window without the object drawn? in tried moving about with my "camera" but cannot see it in the viewport anywhere?

Edit 3- The only other thing i noticed different between our code was the way we were looking at the world. You are using glortho(...); while i'm using gltranslatef(...); After i changed it out i got it to render on screen:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-5, 5, -5, 5, -5, 5);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
render...

so, my question now would be why will it render fine in an array loop but not in an VBO using glTranslatef(...); ?

Edit 4 - Final Solution It seems im not using perspective to set one up correctly, after a little digging and playing about iv swapped glOrtho(...); with gluPerspective(45, g_iWindowWidth / g_iWindowHeight, 1.0, 500.0); and then preformed my relative translations with in the Model view, this in a nutshell has given me what i want. - sees i have alot more reading to do :)

Was it helpful?

Solution

glVertexPointer(3, GL_FLOAT, sizeof(float), 0);
                             ^^^^^^^^^^^^^

Your vertex data is tightly packed so stride should be 0.

drawText() might be mangling your state; no way to know.

Something like this:

screenshot

#include <GL/glew.h>
#include <GL/glut.h>
#include <glm/glm.hpp>
#include <vector>

GLuint vbo = 0;
void init()
{
    std::vector< glm::vec3 > verts;
    verts.push_back( glm::vec3( 0, 2, -4 ) );
    verts.push_back( glm::vec3( -2, -2, -4 ) );
    verts.push_back( glm::vec3( 2, -2, -4 ) );

    glGenBuffers( 1, &vbo );
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData
        ( 
        GL_ARRAY_BUFFER, 
        sizeof( glm::vec3 ) * verts.size(), 
        &verts[0], 
        GL_STATIC_DRAW 
        ); 
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( -5, 5, -5, 5, -5, 5 );

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glEnableClientState( GL_VERTEX_ARRAY );

    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glVertexPointer( 3, GL_FLOAT, 0, 0 );

    glDrawArrays( GL_TRIANGLES, 0, 3 );

    glDisableClientState( GL_VERTEX_ARRAY );

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInitWindowSize( 600, 600 );
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutCreateWindow( "GLUT" );
    glewInit();

    glutDisplayFunc( display );
    init();
    glutMainLoop();
    return 0;
}

I was wondering if an vector of glm::vec3 can be used instead of an array or vector of floats.

Yup. See example.

And if it can be, is there anything special you need to tell openGL for it to use the data inside the glm::vec3 datatype?

Nope.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top