VBO problems

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);
            }

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)
};

  1. 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)); 

[source]#define offsetof(st, m) ((size_t) ( (char *)&((st *)(0))->m - (char *)0 ))[/source]

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

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

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,

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 34 + 1024 = 120+80 = 200.

  2. Interleave attributes (xyz-txty-nxnynz):
    In this case stride = sizeof(pos) + sizeof(texcord) + sizeof(normal). In your case 34 + 24 + 34 = 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 (34 + 24)

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);
            }

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.

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);

anyone see a another error ?