Main Menu

VBOs

Started by thalador, October 24, 2009, 15:22:53

Previous topic - Next topic

thalador

Hi,

it has been some time I used LWJGL the last time. I am now using version 2.1.0 and have some questions concerning the usage of VBOs:

I created 3 VBOs ( I plan to switched to one interleaved later on): one for geometry, one for color, one with the indices. During the update() of my gameloop I fill the buffers with these lines:
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);


Now the part I don't understand anymore, how is the actual rendering done?
I activate the renderstates:
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);


Then I bind the VBOs:
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, geometryVboId);
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, backgroundColorVboId);


Now I would set the VertexPointer and the ColorPointer, but I don't know which method I should use. I'd expected something like
glVertexPointer(offset, stride, geometryVboId) and not glVertexPointer(offset, stride, FloatBuffer) since I already filled the VBO with data in the update() method.

I am a bit lost here, can someone provide an example?

Ciardhubh

You use glVertexPointer with an offset (0 in example below) in the bound buffer, instead of a FloatBuffer.

Quick copy & paste from a model renderer I wrote some time ago:
       GL11.glPushClientAttrib(GL11.GL_CLIENT_VERTEX_ARRAY_BIT);

        // Indices into following buffers
        indexBuffer.bind();

        // Vertices
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        vertexBuffer.bind();
        GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0);

        // Normals
        if (normalBuffer != null) {
            GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
            normalBuffer.bind();
            GL11.glNormalPointer(GL11.GL_FLOAT, 0, 0);
        }

        // Colours
        if (colourBuffer != null) {
            GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
            colourBuffer.bind();
            GL11.glColorPointer(3, GL11.GL_FLOAT, 0, 0);
        }

        // Tex coords
        if (texCoordBuffers != null) {
            GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
            for (int i = 0; i < texCoordBuffers.length; i++) {
                GL13.glClientActiveTexture(textures[i].getUnit());
                texCoordBuffers[i].bind();
                GL11.glTexCoordPointer(modelData.getTexCoords()[i].getValuesPerCoord(),
                        GL11.GL_FLOAT, 0, 0);
            }
        }

        // Draw data
        GL11.glDrawElements(modelData.getMode(), modelData.getIndices().limit(),
                GL11.GL_UNSIGNED_INT, 0);

        // Restore client states. Tested; restores glClientActiveTexture, VBO bindings and array
        // states.
        GL11.glPopClientAttrib();


Here's a site that I found very helpful:
http://www.songho.ca/opengl/gl_vbo.html

thalador

Thank you for the link and the example, I am going to look into that!

jacekcichy

Hi!

I also have some problems with VBO so I decided not create new topic.
I was written code, it is compiling without any troubles but when I start game I see something strange.. It is probably because I put something wrong to buffor but I don't know what. :)

Thanks a lot
Jacek Cichy.

Here is code:
fragment of Init function:
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);

try {
			data();
		} catch (IOException e) {			
			e.printStackTrace();
		}
        VBO_ID=createVBOID();
        bufferData(VBO_ID, data);


VBO methods:
static void data() throws IOException {
        int loc = 0;
        objConverter teren = new objConverter("data/teren.obj");
        vertices = new float[27*teren.length];
        csize = 9*teren.length;
        
        for (int i=0;i<teren.length;i++){
        	vertices[loc] = teren.table[0][i]; //x vertex
        	vertices[loc+1] = teren.table[1][i]; //y vertex
        	vertices[loc+2] = teren.table[2][i]; //z vertex
        	
        	vertices[loc+3] = teren.table[3][i]; //x normal
        	vertices[loc+4] = teren.table[4][i]; //y normal
        	vertices[loc+5] = teren.table[5][i]; //z normal
        	
        	vertices[loc+6] = teren.table[6][i]; //x texCord
        	vertices[loc+7] = teren.table[7][i]; //y texCord
        	vertices[loc+8] = teren.table[8][i]; //z texCord
        	
        	loc +=3;
        }
        
        data = BufferUtils.createFloatBuffer(vertices.length);
        
        data.put(vertices).rewind();
    }
    
    static int createVBOID(){
        IntBuffer buffer = BufferUtils.createIntBuffer(1);
        ARBVertexBufferObject.glGenBuffersARB(buffer);
        return buffer.get(0);
    }
    
    static void bufferData(int id, FloatBuffer buffer) {
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
    }


render method:
GL11.glPushMatrix();
			GL11.glRotatef(-90,1,0,0);
						 
			GL11.glVertexPointer(3, GL11.GL_FLOAT, 36, 0);
			
			GL11.glNormalPointer(GL11.GL_FLOAT, 36, 12);
			
			GL11.glTexCoordPointer(3, GL11.GL_FLOAT, 36, 24);
			
	        GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, csize);
	        
	        GL11.glPopMatrix();


thalador

Hi Jacekcichy,

I just had a quick look at your code and I saw the line "loc +=3;". Shouldn't this be "loc += 9;" because you are adding 3 vertices á 3 floats?

Ciardhubh

Are you sure there actually are 3 texture coordinates and not only 2?

jacekcichy

QuoteI just had a quick look at your code and I saw the line "loc +=3;". Shouldn't this be "loc += 9;" because you are adding 3 vertices á 3 floats?

Yeah it was my mistake :)

QuoteAre you sure there actually are 3 texture coordinates and not only 2?
I have 3 tex cords but 3rd is in most situation zero ;)

Now my vbo works but when I load other models problem sometimes appear again so I have a question should I delate/destroy any buffer or array when I finished create VBO?

Thanks a lot for help   ;D

broumbroum

Quote from: jacekcichy on November 05, 2009, 16:57:34
Now my vbo works but when I load other models problem sometimes appear again so I have a question should I delate/destroy any buffer or array when I finished create VBO?
you may delete the java Buffer when it's been loaded into the GL buffer.
Why using ARB extensions ? there's a glbindbuffer available.

jacekcichy

Broumbroum:
Thanks :) I have a question is this method faster?

BTW. I found what was wrong and now it works well. Maybe it will help somebody..

Last change:
vertices = new float[9*teren.length];
        csize = 1*teren.length;
        loc +=9;

broumbroum

Quote from: jacekcichy on November 05, 2009, 21:44:11
Broumbroum:
Thanks :) I have a question is this method faster?
What method ? clearing the array you made frees up RAM memory, which is directly involved in the CPU threads execution. Whereas using ARB extensions does naturally increase the GPU threads execution, but may not be available with opengl software drivers => see if you're running an average g-card, ARB may not be accessed, then opengl can provide the software hitherto.
moreover your sample of code :
data = BufferUtils.createFloatBuffer(vertices.length);        
        data.put(vertices).rewind();

I'd make the following  change, that wraps a direct buffer instead of a RAM copy :
data = FloatBuffer.wrap(vertices);

jacekcichy

I mean which have better performance? using GL15 or ARB_extension? Thanks a lot for tips with buffer ;) I really love this forum it is very helpful  ;D

broumbroum

ok, ARB_* stuff is intended to be faster. but making both available in the coding is recommended for compatibility.
I mean checking for the specific ARB_vertex_array_object (isn't it that?) extension availability, then choosing GL15 functions when arb ain't supported. :)

jacekcichy

Ok thank You very much  ;D

broumbroum

you're welcome =)