Drawing VBO

Hey guys, I’m learning about Vertex Buffer Objects right now and I’m trying to get one of the book’s C examples to work. This is what I have and it’s not displaying anything for me on the screen.

During init:

		IntBuffer buf = IntBuffer.allocate(1); {
			gl.glGenBuffers(1, buf);
			gl.glBindBuffer(GL.GL_ARRAY_BUFFER, buf.get(0));
		}
		FloatBuffer buffer = FloatBuffer.allocate(3); {
			buffer.put(0, 0.0f);
			buffer.put(1, 0.0f);
			buffer.put(2, 0.0f);
		}
		gl.glBufferData(GL.GL_ARRAY_BUFFER, 32 * 3, buffer, GL.GL_STATIC_DRAW);

Rendering:

		gl.glPointSize(3.0f);
		gl.glDrawArrays(GL.GL_POINTS, 0, 1);

What am I missing here?

Hi!

Use rather direct buffers, look at my source code, in the package “drawer”.

Looking at it now, but there are some dependencies making this difficult to track…I’m trying to create a dead-simple example of using VBO to display a single pixel on the screen.

Also, can someone explain to me the difference between ARB and non-ARB and when/why I should use one over the other?

Is there something specific I’m doing wrong in my sample code?

ByteBuffer.allocateDirect(n * 4).order(ByteOrder.nativeOrder()).asIntBuffer();’
ByteBuffer.allocateDirect(n * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();

-- gl.glBufferData(GL.GL_ARRAY_BUFFER, 32 * 3, buffer, GL.GL_STATIC_DRAW); ++ gl.glBufferData(GL.GL_ARRAY_BUFFER, 4 * 3, buffer, GL.GL_STATIC_DRAW);

Ah, thanks Riven. I was finally able to get it all to work:

For anyone interested:

Init:

		// Allocate my buffer to hold my single vertex for my point
		FloatBuffer buffer = FloatBuffer.allocate(3); {
			buffer.put(0.0f);
			buffer.put(0.0f);
			buffer.put(0.0f);
			
			buffer.rewind();
		}
		
		int[] ids = new int[1];
		gl.glGenBuffersARB(1, ids, 0);																			// Generate a buffer id
		id = ids[0];
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, id);															// Bind the buffer
		gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, buffer.capacity() * 4, buffer, GL.GL_STATIC_DRAW_ARB);		// Send the vertex buffer data to the video card

Render:

		gl.glPointSize(15.0f);																					// Set the pixel size so we can see it
		gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);																	// Make it red
		
		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);																// Enable vertex arrays
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, id);															// Bind the vertex buffer by id
		gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);																// Tell where to start on the vertex buffer
		gl.glDrawArrays(GL.GL_POINTS, 0, 1);																	// Draw the vertex buffer data to the screen
		gl.glDisableClientState(GL.GL_VERTEX_ARRAY);															// Disable vertex arrays

Thanks guys, I appreciate all your help.

Common misconception, nio buffers only need to be direct when the gpu/drivers need to store a reference for later. Off the top of my head, this means basically glVertexPointer() and its family require direct buffers. glBufferData and glTexImage, etc. access the memory right away and they work correctly without direct buffers.

If you don’t properly order your buffer, and you read or write from it, you get garbled data.

ELEMENT_BUFFER:
ib.put(13); // for the GPU this is index: 218103808 (13 << 24)

package drawer;

import com.sun.opengl.util.BufferUtil;
import java.nio.FloatBuffer;
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;


class StaticVertexBufferObject extends StaticVertexSet{
    
    
    private int[] id;
    
    
    StaticVertexBufferObject(float[] array,int mode){
        final GL gl=GLU.getCurrentGL();
        this.mode=mode;
        this.buffer=BufferUtil.newFloatBuffer(array.length);
        this.buffer.put(array);	
        this.buffer.position(0);
        this.id=new int[1];
        gl.glGenBuffersARB(1,id,0);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER,id[0]);
        gl.glBufferDataARB(GL.GL_ARRAY_BUFFER,BufferUtil.SIZEOF_FLOAT*buffer.capacity(),buffer,GL.GL_STATIC_DRAW_ARB);
        this.buffer.position(0);       
    }
    
    StaticVertexBufferObject(FloatBuffer floatBuffer,int mode){
        final GL gl=GLU.getCurrentGL();
        this.mode=mode;
        this.buffer=BufferUtil.copyFloatBuffer(floatBuffer);
        this.buffer.position(0);
        this.id=new int[1];
        gl.glGenBuffersARB(1,id,0);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER,id[0]);
        gl.glBufferDataARB(GL.GL_ARRAY_BUFFER,BufferUtil.SIZEOF_FLOAT*buffer.capacity(),buffer,GL.GL_STATIC_DRAW_ARB);
        this.buffer.position(0);
    }
    
    StaticVertexBufferObject(IVertexSet vertexSet,int mode){
        this(vertexSet.getBuffer(),mode);
    }    
            
    public void draw(){    
        final GL gl=GLU.getCurrentGL();
        //draw the vertex buffer object
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        //gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
        gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER,id[0]);
        gl.glInterleavedArrays(VertexSet.interleavedFormat,0,0);                       
        buffer.rewind();      
        gl.glDrawArrays(mode,0,buffer.capacity()/VertexSet.primitiveCount);
        buffer.rewind();       
        gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
        //gl.glDisableClientState(GL.GL_NORMAL_ARRAY);
        gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
    }
}

goussej, are there efficiencies/benefits to your code I should be aware of in contrast to the code I posted above?

Yes. My code is smart, it uses the proper methods to get the correct alignment and it always uses direct buffers (it avoids some stupid errors). It does the same thing than Riven’s suggestion but with BufferUtil. It uses interleaved arrays, it can be faster on some old graphics cards, I use a single buffer to handle vertices and texture coordinates.