LWJGL Forum

Programming => OpenGL => Topic started by: thalador on October 24, 2009, 15:22:53

Title: VBOs
Post by: thalador on October 24, 2009, 15:22:53
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?
Title: Re: VBOs
Post by: Ciardhubh on October 25, 2009, 04:51:33
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
Title: Re: VBOs
Post by: thalador on October 25, 2009, 08:52:50
Thank you for the link and the example, I am going to look into that!
Title: Re: VBOs
Post by: jacekcichy on November 04, 2009, 22:06:38
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();

Title: Re: VBOs
Post by: thalador on November 05, 2009, 07:13:19
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?
Title: Re: VBOs
Post by: Ciardhubh on November 05, 2009, 09:05:57
Are you sure there actually are 3 texture coordinates and not only 2?
Title: Re: VBOs
Post by: jacekcichy on November 05, 2009, 16:57:34
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
Title: Re: VBOs
Post by: broumbroum on November 05, 2009, 21:02:44
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 (http://www.lwjgl.org/javadoc/org/lwjgl/opengl/GL15.html#glBindBuffer(int,%20int)) available.
Title: Re: VBOs
Post by: jacekcichy on November 05, 2009, 21:44:11
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;
Title: Re: VBOs
Post by: broumbroum on November 06, 2009, 11:24:27
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);
Title: Re: VBOs
Post by: jacekcichy on November 07, 2009, 12:14:57
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
Title: Re: VBOs
Post by: broumbroum on November 07, 2009, 14:41:49
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. :)
Title: Re: VBOs
Post by: jacekcichy on November 07, 2009, 16:56:13
Ok thank You very much  ;D
Title: Re: VBOs
Post by: broumbroum on November 08, 2009, 01:04:06
you're welcome =)