Code Assist, OpenGL VAO/VBO Classes not drawing

2k views Asked by At

Edit II:
Current Code works great! Thanks everyone. I went ahead and included my shader code for reference at the bottom though they do absolutely nothing at this point really.

I am trying to get up and going with OpenGL 4.1 and am still very early in development. Currently I'm not even really using 4.0 features yet in this project, so this is just as much an OpenGL 3 question as well.

The goal I was working on first was simply working out two classes to handle VAOs and VBOs. I had some misconceptions but finally got past the blank screen.

/* THIS CODE IS NOW FULLY FUNCTIONAL */
/* well, fully is questionable lol, should work out of the box with glew and glfw */

/* A simple function that will read a file into an allocated char pointer buffer */
/* Borrowed from OpenGL.org tutorial */
char* filePull(char *file)
{
    FILE *fptr;
    long length;
    char *buf;

    fptr = fopen(file, "r"); /* Open file for reading */
    if (!fptr) /* Return NULL on failure */
        return NULL;
    fseek(fptr, 0, SEEK_END); /* Seek to the end of the file */
    length = ftell(fptr); /* Find out how many bytes into the file we are */
    buf = (char*)malloc(length+1); /* Allocate a buffer for the entire length of the file and a null terminator */
    fseek(fptr, 0, SEEK_SET); /* Go back to the beginning of the file */
    fread(buf, length, 1, fptr); /* Read the contents of the file in to the buffer */
    fclose(fptr); /* Close the file */
    buf[length] = 0; /* Null terminator */

    return buf; /* Return the buffer */
}


class VBO
{
    public:

    GLuint buffer;
    bool isBound;
    vector<void*> belongTo;
    vector<GLfloat> vertex;
    GLenum usage;

    void Load()
    {   glBufferData(GL_ARRAY_BUFFER, vertex.size()*sizeof(GLfloat), &vertex[0], usage);    }
    void Create(void* parent)
    {
        glGenBuffers(1, &buffer);
        glBindBuffer(GL_ARRAY_BUFFER, buffer);
        glBufferData(GL_ARRAY_BUFFER, vertex.size()*sizeof(GLfloat), &vertex[0], usage);
        isBound=true;
        belongTo.push_back(parent);

    }
    void Activate()
    {
        if(!isBound)    glBindBuffer(GL_ARRAY_BUFFER, buffer);
        isBound=true;
    }
    void Deactivate(){  glBindBuffer(GL_ARRAY_BUFFER, 0);  }

    VBO() : isBound(false), usage(GL_STATIC_DRAW)
    {      }
    ~VBO()  {   }

    private:
};

class VAO
{
    public:
    GLuint buffer;
    string key;
    unsigned long long cursor;

    vector<VBO> child;

    void Create()
    {
        glGenVertexArrays(1, &buffer);
        for(unsigned int i=0; i<child.size(); i++)
            child[i].Create(this);
    }
    void Activate()
    {
        glBindVertexArray(buffer);
        for(unsigned int i=0; i<child.size(); i++)
            child[i].Activate();
    }
    void Release(){ glBindVertexArray(0); }
    void Remove(){  glDeleteVertexArrays(1, &buffer);   }

    VAO() : buffer(1)   {     }
    ~VAO()  {       }

    private:
};

int main()
{
    int     width=640, height=480, frame=1;    bool    running = true;

    glfwInit();

    if( !glfwOpenWindow( width, height, 0, 0, 0, 0, 0, 0, GLFW_WINDOW ) )
    {        glfwTerminate();   return 13;   }
    glfwSetWindowTitle("Genesis");

    glewInit();
    cout<<(GLEW_VERSION_4_1?"yes":"no"); //yes


    GLchar *vsource, *fsource;
    GLuint _vs, _fs;
    GLuint Shader;

    vsource = filePull("base.vert");
    fsource = filePull("base.frag");

    /* Compile Shaders */
    _vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(_vs, 1, (const GLchar**)&vsource, 0);
    glCompileShader(_vs);
//    glGetShaderiv(_vs, GL_COMPILE_STATUS, &IsCompiled_VS);
    _fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(_fs, 1, (const GLchar**)&fsource, 0);
    glCompileShader(_fs);
/***************** ^ Vertex | Fragment v *********************/
    glAttachShader(Shader, _vs);
    glAttachShader(Shader, _fs);
//    glGetShaderiv(_fs, GL_COMPILE_STATUS, &IsCompiled_FS);
    glBindAttribLocation(Shader, 0, "posIn");
    glLinkProgram(Shader);
//    glGetProgramiv(shaderprogram, GL_LINK_STATUS, (int *)&IsLinked);

    VAO Object3D;
    VBO myVBO[3];

    glUseProgram(Shader);

    for(int i=0; i<9; i++)
        myVBO[0].vertex.push_back((i%9)*.11); //Arbitrary vertex values

    Object3D.child.push_back(myVBO[0]);
    Object3D.Create();

    glClearColor( 0.7f, 0.74f, 0.77f, 0.0f ); //Black got lonely

   int i=0; while(running)
    {
        frame++;

        glfwGetWindowSize( &width, &height );
        height = height > 0 ? height : 1;
        glViewport( 0, 0, width, height );
        glClear( GL_COLOR_BUFFER_BIT );

        /*   Bind, Draw, Unbind */
        Object3D.Activate();
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 9);

        Object3D.Release();
        glfwSwapBuffers();

        // exit if ESC was pressed or window was closed
        running = !glfwGetKey(GLFW_KEY_ESC) && glfwGetWindowParam( GLFW_OPENED);
        i++;
    }

    glUseProgram(0); glDisableVertexAttribArray(0);
    glDetachShader(Shader, _vs); glDetachShader(Shader, _fs);
    glDeleteProgram(Shader); glDeleteShader(_vs); glDeleteShader(_fs);
    glDeleteVertexArrays(1, &Object3D.buffer);

    glfwTerminate();
    return 0;
}

Basically I'm just hoping to get anything on the screen at this point. I am using glfw and glew. Am I completely leaving some things out or do I only need to correct something? Code is somewhat mangled at the moment, sorry.

base.vert

// Fragment Shader – file "base.vert"    
#version 300

in  vec3 posIn;
out vec4 colorOut;

void main(void)
{
    gl_Position = vec4(posIn, 1.0);
    colorOut = vec4(3.0,6.0,4.0,1.0);
}

base.frag

// Vertex Shader – file "base.frag"
#version 300

out vec3 colorOut;

void main(void)
{
    colorOut = vec3(1.0,10,1.0);
}
2

There are 2 answers

1
Bahbar On BEST ANSWER
&vertex

vertex is a vector. Taking its address will not give you a pointer to the data.

Edit to add: Right. It still does not work, because you have at least 2 more issues:

  1. You don't call any gl*Pointer call. The GL won't know what it needs to pull from your vertex buffer objects
  2. your vertex data that you put in your vertex array is 3 times the same vertex. A triangle with the 3 points at the same location:

    for(int i=0; i<9; i++) myVBO[0].vertex.push_back((i%3)*.2); //Arbitrary vertex values

It creates 3 (.0 .2 .4) vectors, all at the same location.

1
datenwolf On

That iBound member of VBO looks suspicious. The OpenGL binding state may change, for example after switching the bound VAO, but the VBO class instance still thinks it's active. Just drop iBound altogether and re-bind every time you need the object. With modern drivers rebinding an already bound object is almost for free.