VBO Setup

I’m trying to convert my glBegin->glEnd triangle stripped terrain to be drawn with a vertex buffer object but I’m having a bit of trouble. All of the examples I find online don’t really explain the setup too well and most are written in C/C++ so the JOGL differences aren’t spelled out at all. My app doesn’t crash or throw any exceptions at the moment, but it doesn’t display anything, either. Code to follow… any help would be appreciated.


public void init(GLAutoDrawable drawable)
{
	GL gl = drawable.getGL();
	GLU glu = new GLU();
	
	renderer = new TextRenderer(new Font("Consolas", Font.BOLD, 15));
		
		
	// Setup GL States
        gl.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);  // Black Background
        gl.glClearDepth(1.0f);        // Depth Buffer Setup
        gl.glDepthFunc(GL.GL_LEQUAL);  // The Type Of Depth Testing (Less Or Equal)
        gl.glEnable(GL.GL_DEPTH_TEST);      // Enable Depth Testing
        gl.glShadeModel(GL.GL_SMOOTH);      // Select Smooth Shading
        // Set Perspective Calculations To Most Accurate
        gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);      
        gl.glEnable(GL.GL_TEXTURE_2D);      // Enable Textures
        gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f);    // Set The Color To White
}

public void drawTerrain(GLAutoDrawable drawable)
{
	GL gl = drawable.getGL();
	gl.glPushMatrix();
	
	gl.glClear (GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
	
	if( !vboIsSetup )
       {
    	    setupPointers(gl);
    	    vboIsSetup = true;
       }
    
    
	gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
	gl.glEnableClientState( GL.GL_NORMAL_ARRAY );
	gl.glEnableClientState( GL.GL_COLOR_ARRAY );


	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glColorPointer(3, GL.GL_DOUBLE, 0, vboIds[0]);
	
	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glNormalPointer(GL.GL_DOUBLE, 0, vboIds[0] + colorSize);
	
	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glVertexPointer(3, GL.GL_DOUBLE, 0, vboIds[0] + normalSize);	
	
	gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vboIds[1]);		
	gl.glDrawElements(GL.GL_TRIANGLE_STRIP, 1, GL.GL_UNSIGNED_INT, vboIds[1]);
	
	
	// reset everything
	gl.glBindBufferARB( GL.GL_ARRAY_BUFFER, 0 );
	gl.glDisableClientState( GL.GL_VERTEX_ARRAY );
	gl.glDisableClientState( GL.GL_NORMAL_ARRAY );
	gl.glDisableClientState( GL.GL_COLOR_ARRAY );
	
	
	gl.glPopMatrix();
}


private void setupPointers(GL gl)
{
	colorSize = colors.size() * 3 * BufferUtil.SIZEOF_DOUBLE;
	normalSize = normals.size() * 3 * BufferUtil.SIZEOF_DOUBLE;
	vertexSize = vertices.size() * 3 * BufferUtil.SIZEOF_DOUBLE;
	indexSize = indices.size() * BufferUtil.SIZEOF_INT;
	
	vbo = ByteBuffer.allocate(colorSize + normalSize + vertexSize);
	ibo = ByteBuffer.allocate(indexSize);
	
	colorOffset = 0;
	normalOffset = colorSize;
	vertexOffset = normalSize;
    
    for (int i = 0; i < indices.size(); i++)
    {
    	ibo.putInt(indices.get(i));
    }
    
    for (int j = 0; j < colors.size(); j++)
    {
    	vbo.putDouble(colors.get(j).x);
    	vbo.putDouble(colors.get(j).y);
    	vbo.putDouble(colors.get(j).z);
    }
    
    for (int j = 0; j < normals.size(); j++)
    {
    	vbo.putDouble(normals.get(j).x);
    	vbo.putDouble(normals.get(j).y);
    	vbo.putDouble(normals.get(j).z);
    }
    
    for (int i = 0; i < vertices.size(); i++)
    {
    	vbo.putDouble(vertices.get(i).getPosition().x);
    	vbo.putDouble(vertices.get(i).getPosition().y);
    	vbo.putDouble(vertices.get(i).getPosition().z);
    }

    vbo.rewind();
    ibo.rewind();

    
    
	gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
	gl.glEnableClientState( GL.GL_NORMAL_ARRAY );
	gl.glEnableClientState( GL.GL_COLOR_ARRAY );

    // Generate And Bind The VBO Buffer
    gl.glGenBuffersARB(1, vboIds, 0);  // Get A Valid Name
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]); // Bind The Buffer
    // Load The Data
    gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, colorSize + normalSize + vertexSize, vbo, GL.GL_STATIC_DRAW_ARB);
    
    // Generate And Bind The Index Buffer
    gl.glGenBuffersARB(1, vboIds, 1);  // Get A Valid Name
    gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vboIds[1]);  // Bind The Buffer
    // Load The Data
    gl.glBufferDataARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, indexSize, ibo, GL.GL_STATIC_DRAW_ARB);
    
    
	gl.glDisableClientState( GL.GL_VERTEX_ARRAY );
	gl.glDisableClientState( GL.GL_NORMAL_ARRAY );
	gl.glDisableClientState( GL.GL_COLOR_ARRAY );

    //vbo.clear();
    //ibo.clear();
}


Hi!

Use several buffers for colors, normals and vertices or call glInterleavedArray. Watch my source code in the package “drawer” if you still need an example.

Ok, I’ll give it a try.

just a little searching…a little … would have yielded you several threads, and even one where I detailed VBO setup to a great detail.

sigh…gen y

http://www.java-gaming.org/index.php/topic,18710.msg147236.html

Actually, there is no need to change your code as gouessej suggested, the current approach is just fine, except that you use gl....Pointer() incorrectly:

This is the specification:
gl.glColorPointer(3, GL.GL_DOUBLE, stride, offset);
glDrawElements(mode, count, type, buffer_offset);


	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glColorPointer(3, GL.GL_DOUBLE, 0, 0);
                // ------------------- color offset is 0
	
	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glNormalPointer(GL.GL_DOUBLE, 0, colorSize);
                // ------------------- normal offset is colorSize
	
	gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vboIds[0]);
	gl.glVertexPointer(3, GL.GL_DOUBLE, 0, colorSize + normalSize);
                // ------------------- vertex offset is colorSize + normalSize
	
	gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vboIds[1]);		
	gl.glDrawElements(GL.GL_TRIANGLE_STRIP, 1, GL.GL_UNSIGNED_INT, 0);
                // ------------------- begin using indices at offset 0

Your stride has the ‘magic value’ of zero, meaning that the OpenGL driver will calculate the stride for you. This is OK.

Riven, I’ve tried that before and had the same issue. (I’ve tried all kinds of combinations)

gouessej, my array isn’t interleaved, it’s just set up with all color values, then all normals, then all vertices.

Z-Knight, I didn’t find your post when searching. Thank you for the link, however, aside from you running through multiple objects, it didn’t help me fix it.

Instead of:

ByteBuffer bb = ByteBuffer.allocate(N);

Do this:

ByteBuffer bb = ByteBuffer.allocate(N).order(ByteOrder.nativeOrder());

Also apply all the fixes I mentioned earlier, just in case you reverted them.

If it still doesn’t work, please provide some updated sourcecode, so we can work from there.

Sorry it wasn’t as helpful as I hoped. I though you may have wanted an example of using VBOs that actually works and that solution I provided is basically the simplest case I could come up with. Good luck.

Z-Knight, it’s pretty much the same thing I’m doing except I’m just doing one VBO right now (to get it working) and I have my vertices/normals/colors in the same array.

I added the normal order call and still nothing.

To make sure I was creating my vbo correctly, I created a new draw using glBeing and glEnd but using the vbo buffer and ibo buffer as my dataset. it renders fine.

post your code…we’ll debug it for you here. I guarantee it is something small that you just can’t see so different eye could help.

I do appreciate it. I know it’s probably something like a glEnable I’m missing somewhere.

I don’t think my helper classes and listeners will be of much use. But, if you don’t find anything here, I can post them later. Again, thanks for the help; this has been bugging me for a few days now.

(also, what’s up with *.java files being invalid on a java forum?)

gl.glDrawElements(GL.GL_TRIANGLE_STRIP, [b]1[/b], GL.GL_UNSIGNED_INT, 0);

You do realize you’re only rendering one triangle here?

I assumed that using GL_TRIANGLE_STRIP meant that the value there would be how many strips. I’ll update it to have total # of triangles and see what I get. However, I haven’t even seen one triangle in my scene. But if it works, I’ll be happy.

Well now I feel retarded…

My colors are all off but I think I can figure that out. (they’re all stripes. blue laced with what it should be)

Anyway, thanks for your help. I appreciate it.

EDIT: I was storing my colors per index and not per vertex. switched it and it all looks good. my normals are probably off as well. In case anyone else reads this and has a similar issue.