PDA

View Full Version : getting started with vbo's



noeska
12-01-2008, 06:28 PM
I am trying to get vbo vertex buffer objects working. But i cannot get it to work. Tutorials or simple bare bone examples would be nice.

chronozphere
12-01-2008, 07:05 PM
A NeHe tutorial: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=45

Some Extra links:
http://www.ozone3d.net/tutorials/opengl_vbo.php
http://www.devmaster.net/articles/oglVertexBuffer/
http://www.songho.ca/opengl/gl_vbo.html

Hope they are usefull :)

JernejL
12-01-2008, 07:06 PM
which method are trying to use? there are many ways to get VBOs work, some code would be nice to see what you are doing wrong.

noeska
12-01-2008, 07:20 PM
This is the code i have now:
First i declare 4 vars:

var
FVBO: TGluInt;
FVBOPointer: PGlVoid;
i: integer;
VertexPointer: PVertex;

Then i initialize the vertex buffer object and fill it with the vertexes making up the triangle.

glGenBuffersARB(1, @FVBO); //create a vertex buffer
glBindBufferARB(GL_ARRAY_BUFFER_ARB, FVBO); //bind the buffer
glEnableClientState(GL_VERTEX_ARRAY); //enable the buffer

glBufferDataARB(GL_ARRAY_BUFFER_ARB, 3*SizeOf(TVertex), nil, GL_STATIC_DRAW_ARB); //reserve memory

FVBOPointer := glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); //get a pointer to the vbo

VertexPointer := FVBOPointer;
VertexPointer^.X := 1.0;
VertexPointer^.Y := -1.0;
VertexPointer^.Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));

VertexPointer := FVBOPointer;
VertexPointer^.X := -1.0;
VertexPointer^.Y := -1.0;
VertexPointer^.Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));

VertexPointer := FVBOPointer;
VertexPointer^.X := 0.0;
VertexPointer^.Y := 1.0;
VertexPointer^.Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));

glUnmapBufferARB(GL_ARRAY_BUFFER_ARB);


Now when i want to render it i do:

glInterleavedArrays(GL_V3F, SizeOf(TVertex), nil);
glDrawArrays(GL_TRIANGLES, 0, 3 );

JernejL
12-01-2008, 07:33 PM
aren't you supposed to call glEnableClientState before binding or creating it? shouldn't it be th first thing you call?

noeska
12-01-2008, 07:41 PM
I changed the possition of that line, but still nothing.

Also i forgot to post the typedef for PVertex:


type
PVertex = ^TVertex;
TVertex = packed record
X,Y,Z : TGLFloat;
end;

waran
12-01-2008, 08:01 PM
And more importantly: You aren't incrementing your VertexPointer.

You are doing this:

Set to 0
write data
inc
Set to 0 again
write data
inc
Set to 0 again
write data
inc

So you are just overwriting one Vertex all the time.

noeska
12-01-2008, 08:38 PM
changed that to


TVertex(FVBOPointer^).X := -1.0;
TVertex(FVBOPointer^).Y := 1.0;
TVertex(FVBOPointer^).Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));


TVertex(FVBOPointer^).X := -1.0;
TVertex(FVBOPointer^).Y := -1.0;
TVertex(FVBOPointer^).Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));


TVertex(FVBOPointer^).X := 1.0;
TVertex(FVBOPointer^).Y := -1.0;
TVertex(FVBOPointer^).Z := 0.0;
inc(Integer(FVBOPointer), SizeOf(TVertex));


As it turned out the vertexes were all wrong also.
Now i see a nice white triangle.

Ok on to something more exiting...

waran
13-01-2008, 04:47 AM
The last incrementation is useless and so is the cast to "TVertex".

If you don't do this usually:

var
a: integer;
b: ^integer;
begin
b := @a;
integer(b^) := -123;
end.


You might also have used GL_V2F instead of V3F since you aren't
using Z anyway.

Also you could cast the pointer to "cardinal" instead "integer" because
negative pointers don't make sense (to humans, the computer doesn't care).
It just sounds more logically.

Glad its working, now to make it more aesthetic; just giving tips here,
don't feel upset :)

noeska
13-01-2008, 10:52 AM
So instead of making FVBOPointer: PGlVoid; i should make that a PVertex?

is not your example the same as what i do with TVertex?

You are right the last increment is useless as nothing new is added. So when used in a loop i should take care that the last time the increment is not done. Ok cardinals are the way to cast pointers to.

Z was not used for this specific triangle, but might be for another one. (e.g. i was not making a 2d example.) So i decided to use V3F.

noeska
13-01-2008, 03:52 PM
Now larger meshes also work.
Now i read that there is also a thing called buffers with indexed arrays. If i understand it correctly i do not need to feed all the vertexes even double but only the unique ones and pass indices to them. So like i do in gld3ds where i have a list of vertexes and a list containing indices to them.

so i need two vbo's one for the vertexes and one for the indices.

but how are these combined? Simple example anyone?

User137
14-01-2008, 01:57 AM
I suppose glDrawElements does that. (This doesn't make vbo of indices but does use vertices from vbo)

Example:
type TN3DFaceIndices = array[0..2] of word;
var fa: array of TN3DFaceIndices;

glDrawElements(GL_TRIANGLES,Count*3,GL_UNSIGNED_SH ORT,@(fa[first]));


Here was my version of performance test about Vertex arrays, displaylists and VBO all in 1:
http://www.pascalgamedevelopment.com/viewtopic.php?t=4785