[SOLVED] Odd OpenGL VBO Behavior - Debugging is leaving me in the dark

First Post, and thanks in advance to everyone who helps out on this site answering questions - I have found these tutorials a real blessing.

I started out trying to unravel the secrets of an efficient VBO by following this tutorial:
http://www.java-gaming.org/index.php?topic=24272.0

Thinking ahead to my future plans for it, I decided to try to lean out the actual draw methods as much as possible and discovered some weird un-explainable behaviors.
Here is the relevant code:
http://pastebin.com/2enngXsA

Odd Behavior 1:
If I comment out line 43, preventing the Vertex Array Object from drawing, the program will crash with the following error:


Java Result: -1073741819
BUILD SUCCESSFUL (total time: 2 seconds)

If I also comment out the next 4 methods (lines 46, 49, 52, 55) (line 58 doesn’t seem to have this problem) - the error goes away.

Within the method in question, I can comment out the draw command, but if I comment out either of the pointers, I get the error.

I am not sure how or why a couple of VAO pointers impact other VBOs and overall program stability. Why is this doing this? Any illumination on the subject would be appreciated.

Odd Behavior 2:
With all methods functioning (not commented out from OB1) - I get 7 identical triangles as expected.

If You look at lines 252-255 vs. 271-273
These are the drawing functions for the two interleaved examples (hereafter called “5” and “6”). If you notice line 251 is necessary in example “5” but not in example “6”

If I comment it out of example “5” then I get a weird tearing effect on triangle 5.

Not sure what else is different between the two that is requiring the re-buffering of the data in “5” but not in “6”. Why is this doing this? Any illumination on the subject would be appreciated.

I believe the problem you are having is due to the en/disableClientState() calls. VBOs do not need these calls. I think that, haven’t worked on this in a while so I’m not 100% sure, you’re problem is that you’re telling openGL that you’re about to draw a VAO and then you end up drawing a VBO. Try moving the enable/disable client state code into drawVertexArrays() (enable before setup and draw disable after) and see where that gets you.

Just realized that you’re using VAOs in a few places you could try the above, but you’d have to do it for each drawArrays call

Yes, I am doing a composite program to study the differences between VAOs and VBOs. In the original tutorial, the en/disableClientState() calls are in all of the VAO And VBO examples. Should I enable for the VAO then disable, then enable for all the VBOs separately as if the same command enables different things for different uses?

If I’m understanding you correctly then yes a drawElements call should look something like this


      /* enable shader */
		int vert_pos = shader.getAttribLocation("vert_pos");
		int color = shader.getAttribLocation("color");

		gl.glBindBuffer(GL.GL_ARRAY_BUFFER, m_vbo_handle[0]);
		gl.glEnableVertexAttribArray(vert_pos);
		gl.glEnableVertexAttribArray(color);
		gl.glVertexAttribPointer(vert_pos, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * (Vertex.SIZE - 4), 0);//start
		gl.glVertexAttribPointer(color, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * (Vertex.SIZE - 4), Buffers.SIZEOF_FLOAT * 3);//12
		
		gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, m_ind_handle[0]);
		gl.glDrawElements(GL.GL_TRIANGLES, m_index_array.length, GL.GL_UNSIGNED_INT, 0);
		
		gl.glDisableVertexAttribArray(vert_pos);
		gl.glDisableVertexAttribArray(color);
		
      /* disable shader */

You should be doing this for every draw call making sure to unbind (disable) all of the bindings or you’ll run into bugs.

Edit: VAOs are similar in that you’re going to want to dis/enable the client states

Edit 2: You may be thinking to yourself “isn’t that inefficient?” and you’d be right. That’s why there’s instance and batch rendering.

What I thought was meant, was the following (which didn’t work when tested):


        // Initialize States
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        
        drawImmediateMode();
        
        glTranslatef(0.05f, -0.05f, 0);
//        drawVertexArrays();      // This is the command that MUST be there to prevent crash
        
        // Clean up States
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
        // Initialize States
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);
        
        glTranslatef(0.05f, -0.05f, 0);
        drawVBO();
        
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOIndexed();
        
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved1();
        
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved2();
        
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved3Mapped();
        
        // Clean up States
        glDisableClientState(GL_COLOR_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

    }


I haven’t got into shaders yet, so I am not sure how your code sample functions.

What is this Attrib feature that is referenced repeatedly? (AttribLocation)(AttribArray)(etc…)

It appears to work similar to a pointer, but the standard pointer used in the tutorials is not there.

Just to make sure the discussion travels in the direction I am hoping to go, I want to explain a little bit more about my goals.
I am trying to design the most efficient system I can come up with for using VBOs. I have many topics to research, and my search is still young. The tutorial mentioned in my OP helped immensely in getting me started. Now I am trying to pick it apart a little to understand how everything works.

Ultimately I want to have a system where everything is streamlined.
One Class contains all of the OpenGL setup and option work
One Class contains all of the Rendering loop and calls to a collection of drawable objects’ draw() methods
One Class contains the collection of drawable objects

The Objects to add to the drawable collection, need to be a standardized class with:
an initialize() to pre-load the buffers into the VRAM and generate their handles along with each instance’s object’s translation/rotation settings and textures
a draw() to translate/rotate and draw the object to the screen

The rendering loop then would (each frame):
initialize the environment with the matrix settings, enable/disable settings
Call each object’s draw() method - (Possibly to hundreds of VBOs)
clean up environment by disabling settings and unbinding anything no longer needed

I eventually want to be able to use Lighting, Textures, Interleaving, Indexing, Double Buffering, MipMapping, and anything else that will either improve performance or appearance. I just don’t know how all these things work together yet. There aren’t any tutorials I have been able to find that do All of these things. Some do one or two, others do others. I will probably have to pull from many sources before I am done.

Hey sorry, I was away for the weekend. First off you don’t need to enable the clientstate for immediate mode, in fact you should avoid it.

OK, so let me preface this with I’m not an expert and I will try to push you in the right direction, but some of the info follow won’t be 100% true, I’ll specify where I’m not sure. Also, take a look at cplusplusguy on youtube, not really easy to follow and he does some bad stuff (code smells), but good info overall.

Anyway, the code I posted is for VBOs (vertex buffer object). Anytime you’re calling drawArray() you’re working with a VAO (vertex array object) drawElements() is a VBO, which can contain multiple VAOs (something I’m fuzzy on so that may not be right, but I’m sticking with it until told otherwise) - http://stackoverflow.com/questions/11821336/what-are-vertex-array-objects.

Regardless the process is the same, just the calls are different. FYI the gl.gl* is because I use JOGL


//m_vbo_handle is the "index"/start position of the buffer we want to draw (positional and color data are stored in here)
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, m_vbo_handle[0]);
//vert_pos is an index in GLSL referencing the bind position of this array (basically where
//the positional data is in the shader)
gl.glEnableVertexAttribArray(vert_pos);
//same as vert_pos but for color data
gl.glEnableVertexAttribArray(color);
//similar to calling glEnableClientState(GL_VERTEX_ARRAY) 
//glVertexAttribPointer(bind_position, number of values, type of values, ... , size in bytes, position of first element in array
gl.glVertexAttribPointer(vert_pos, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * Vertex.SIZE, 0);//start
//similar to calling glEnableClientState(GL_COLOR_ARRAY) 
//glVertexAttribPointer(bind_position, number of values, type of values, ... , size in bytes, position of first element in array
gl.glVertexAttribPointer(color, 3, GL.GL_FLOAT, false, Buffers.SIZEOF_FLOAT * Vertex.SIZE, Buffers.SIZEOF_FLOAT * 3);//12

//m_ind_handle is the "index"/start position of the buffer we use to reference the correct order in which to draw the above buffer
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, m_ind_handle[0]);
gl.glDrawElements(GL.GL_TRIANGLES, m_index_array.length, GL.GL_UNSIGNED_INT, 0);
     
//Unbind the buffers so we don't render this again anywhere else
gl.glDisableVertexAttribArray(vert_pos);
gl.glDisableVertexAttribArray(color);

So a similar process for VAOs would be:


drawVAO()
{
   glEnableClientState(GL_VERTEX_ARRAY);
   glEnableClientState(GL_COLOR_ARRAY);
   //Think of it as equivalent to glEnableVertexAttribArray(vert_pos), but remember it's not
   glBindBuffer(GL_ARRAY_BUFFER, pos_handle);
   //Similar to glVertexAttribPointer() for the positional data in the above example
   glVertexPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);
 
   //Think of it as equivalent to glEnableVertexAttribArray(color), but remember it's not
   glBindBuffer(GL_ARRAY_BUFFER, color_handle);
   //Similar to glVertexAttribPointer() for the positional data in the above example
   glColorPointer(3, GL_FLOAT, /* stride */3 << 2, 0L);
 
   // Draw
   glDrawArrays(GL_TRIANGLES, 0, 3 /* elements */);
       
   glBindBuffer(GL_ARRAY_BUFFER, 0);
   glDisableClientState(GL_COLOR_ARRAY);
   glDisableClientState(GL_VERTEX_ARRAY);
}

Now, in your code you’re deleting the buffers after the draw calls

glDeleteBuffers();

You don’t want to be doing this every frame, or before you’re done drawing that object forever(basically), as it opens that bind position to overrides. Meaning another buffer can be stored in that location like a quad or something. Instead you should just be unbinding the data:

glBindBuffer(GL_ARRAY_BUFFER, 0);

and disable the bind target in the appropriate manner either by disableClientState() or disableVertexAttribPointer().

I fell like it’s a good time to say that vertices are not only positions, they contain can colors, normals, texture coordinates, alpha values, and various other bits of data. So try to keep that in mind.

So in review:

    public static void drawThem(){
        // Initialize States
        glEnableClientState(GL_VERTEX_ARRAY);  //<-- Remove
        glEnableClientState(GL_COLOR_ARRAY);  //<-- Remove
       
        drawImmediateMode();
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVertexArrays(); //Add enable/disable in this function
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVBO(); //Add enable/disable in this function
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOIndexed(); //Add enable/disable in this function
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved1(); //Add enable/disable in this function
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved2(); //Add enable/disable in this function
       
        glTranslatef(0.05f, -0.05f, 0);
        drawVBOInterleaved3Mapped(); //Add enable/disable in this function
       
        // Clean up States
        glDisableClientState(GL_COLOR_ARRAY);  //<-- Remove
        glDisableClientState(GL_VERTEX_ARRAY);  //<-- Remove
 
    }

and don’t forget to remove deleteBuffers from the draw code! Should have a cleanup function when closing the program instead.

Thanks for the in depth reply - I hopefully will be able to test this tonight.

FYI: I am also having a different problem now with a completely from scratch program I started:
http://www.java-gaming.org/topics/fatal-exception-what-d-i-do/36343/view.html

These problems are unrelated in code, but indicitive of my problems trying to figure out these blanken VBOs…

Understandable, let us know how it goes.

Check!

Check! I don’t know anything about Shaders, GLSL, or Attrib values in your previous code, but this one looks familiar. Doublechecked that that is what I have.

Check! Removed!

Good to know.

Moving the enable/disable calls into the different methods didn’t seem to have any effect. They both work equally well. However I did move the enableClientState() to After the immediate mode method.

With the removal of the

glDeleteBuffers();

command, the crash and java error code are finally gone!!!

Odd Behavior 2 (glitchy triangle) is gone too!!!

That was my problem!!! Thank you So much @thedanisaur!

Yay! happy to help.