PDA

View Full Version : VBO problems



Pierre
03-19-2010, 03:16 PM
Hello to all the community

I have a problem with VBO.

I have a table with all the vertex (x, y, z), texture (tx, tz), and normal (nx, ny, nz).
And another picture index.

Normally the two tables have the correct values.

But nothing appears.

Here is my code, thank you for helping me, I'm really block:



if (vbo.ContainsKey(mesh.material))
{
// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, 0);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, 3);
Gl.glNormalPointer(Gl.GL_FLOAT, 0, 5);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);

// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_UNSIGNED_INT, 0);


Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
}
else
{
uint[] tableau = new uint[2];
// Génération des buffers
Gl.glGenBuffers(2, tableau);

// Buffer d'informations de vertex
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, tableau[0]);
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)mesh.FloatArray.Length, mesh.FloatArray, Gl.GL_STATIC_DRAW);

// Buffer d'indices
Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, tableau[1]);
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(mesh.IndexArray.Length), mesh.IndexArray, Gl.GL_STATIC_DRAW);

vbo.Add(mesh.material, tableau);

// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, 0);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, 3);
Gl.glNormalPointer(Gl.GL_FLOAT, 0, 5);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);


// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_UNSIGNED_INT, 0);

Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
}

yooyo
03-19-2010, 06:05 PM
Here is a problem:



Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, 0);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, 3);
Gl.glNormalPointer(Gl.GL_FLOAT, 0, 5);


1. you need to set correct offset in bytes. Assume your vertex format looks like


struct vertex
{
float pos[3]; // offset = 0
float tex[2]; // offset = 3 * sizeof (float)
float normal[3]; // offset = 5 * sizeof (float)
};


2. You need to pass correct stride, which is sizeof your vertex struct in bytes.


Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glVertexPointer(3, Gl.GL_FLOAT, sizeof(vertex), 0);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, sizeof(vertex), 12); // 12 = 3 * sizeof(float)
Gl.glNormalPointer(Gl.GL_FLOAT, sizeof(vertex), 20); // 20 = 5 * sizeof(float)


Instead of calculating offsets you can use offsetof macto


#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))


Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glVertexPointer(3, Gl.GL_FLOAT, sizeof(vertex), offsetof(vertex, pos));
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, sizeof(vertex), offsetof(vertex, tex));
Gl.glNormalPointer(Gl.GL_FLOAT, sizeof(vertex), offsetof(vertex, normal));

Stephen A
03-19-2010, 06:43 PM
#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))

Wrong programming language, this looks like C# w/ Tao Framework. :)

The offsets are indeed wrong, fix them and you should see something on screen.

Pierre
03-20-2010, 08:05 AM
Ok thank you.
I'm in C # / tao framework.

But it's the same thing.

I do not understand how I calculate the last two arguments:

Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, 0);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, 3);
Gl.glNormalPointer(Gl.GL_FLOAT, 0, 5);


In my program, my offset table index are classified as follows:


enum ArrayIndexes : int
{
VERTEX_X = 0,
VERTEX_Y = 2,
VERTEX_Z = 1,
TEX_U = 3,
TEX_V = 4,
NORMAL_X = 5,
NORMAL_Y = 6,
NORMAL_Z = 7
}

How I can calculate from this the two arguments?

Thank you again,

yooyo
03-20-2010, 01:33 PM
Depending how do you pack vertex attributes in array you must adjust stride. There is a two ways how to store data in VBO. Remember one float takes 4 bytes of memory:

1. store all positions (xyzxyzxyzxyzxyz...) then all mapping coords(uvuvuvuvuvuv...) then all normals (xyzxyzxyzxyzxyz...)
In this case, stride = 0 and offset is from where in buffer stats some attribute array.. in BYTES.
For example.. say you have 10 positions, following by 10 texcords, following by 10 normals.
offset for position is 0 (because it starts from beginning of VBO bufer)
offset for texcoords = 10 * 3 * 4 = 120. 10 -> number of vertices, 3 -> number of components in vector (x, y and z)
offset for normals = 10 *3*4 + 10*2*4 = 120+80 = 200.

2. Interleave attributes (xyz-txty-nxnynz):
In this case stride = sizeof(pos) + sizeof(texcord) + sizeof(normal). In your case 3*4 + 2*4 + 3*4 = 32 bytes.
offset is distance of first component of attribute from beggining of buffer in BYTES. so..
pos offset = 0
texcoord offset = 12 (3*4)
normal offset = 20 (3*4 + 2*4)

Pierre
03-20-2010, 03:56 PM
Ok thank now I have understand but but nothing appears, my code is:


if (vbo.ContainsKey(mesh.material))
{
// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 32, 12);
Gl.glNormalPointer(Gl.GL_FLOAT, 32, 20);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 32, 0);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);

// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_UNSIGNED_INT, 0);


Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
}
else
{
uint[] tableau = new uint[2];
// Génération des buffers
Gl.glGenBuffers(2, tableau);

// Buffer d'informations de vertex
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, tableau[0]);
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(mesh.FloatArray.Length), mesh.FloatArray, Gl.GL_STATIC_DRAW);

// Buffer d'indices
Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, tableau[1]);
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(mesh.IndexArray.Length), mesh.IndexArray, Gl.GL_STATIC_DRAW);

vbo.Add(mesh.material, tableau);

// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);

Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 32, 12);
Gl.glNormalPointer(Gl.GL_FLOAT, 32, 20);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 32, 0);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);


// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_UNSIGNED_INT, 0);

Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
}

yooyo
03-20-2010, 05:00 PM
Any gl errors? Did you setup modelview and projection matrices and did you setup viewport.

Few more questions...
mesh.FloatArray.Length returns number of elements in float array or size in bytes? You need to pass size in bytes to glBufferData call.

mesh.IndexArray.Length returns number of elements in Index array or size in bytes? Also make sure you use unsigned int in IndexArray, because in you glDrawElements call you pass GL_UNSIGNED_INT as type.

Pierre
03-20-2010, 05:34 PM
My other 3d are draw, and they are at the same place.

mesh.FloatArray.Length return the numbers of case in array.
mesh.IndexArray.Length is the same thing.

My array for i use int in indexarray.

My news code is: But it's the same thing. I have another problem but what ?


if (vbo.ContainsKey(mesh.material))
{
// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);
Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 32, 12);
Gl.glNormalPointer(Gl.GL_FLOAT, 32, 20);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 32, 0);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);

// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_INT, 0);


Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
}
else
{
uint[] tableau = new uint[2];
// Génération des buffers
Gl.glGenBuffers(2, tableau);

// Buffer d'informations de vertex
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, tableau[0]);
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(mesh.FloatArray.Length*4), mesh.FloatArray, Gl.GL_STATIC_DRAW);

// Buffer d'indices
Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, tableau[1]);
Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(mesh.IndexArray.Length*4), mesh.IndexArray, Gl.GL_STATIC_DRAW);

vbo.Add(mesh.material, tableau);

// Utilisation des données des buffers
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo[mesh.material][0]);

Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 32, 12);
Gl.glNormalPointer(Gl.GL_FLOAT, 32, 20);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 32, 0);

Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, vbo[mesh.material][1]);

// Activation d'utilisation des tableaux
Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
Gl.glEnableClientState(Gl.GL_NORMAL_ARRAY);


// Rendu de notre géométrie
Gl.glDrawElements(Gl.GL_TRIANGLES, mesh.IndexArray.Length, Gl.GL_INT, 0);

Gl.glDisableClientState(Gl.GL_NORMAL_ARRAY);
Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY) ;
Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);

Pierre
03-23-2010, 05:50 AM
anyone see a another error ?