Vertex Buffer Object (VBO)

Started by
14 comments, last by Decibit 14 years, 1 month ago
Hi! I am using OpenGL > C# > Tao, for drawing large datasets. I managed to draw all data using display lists, but I want more flexibility, because I have to be able to show/hide certain points. I fill a 2D array with MyVertex, which is a struct containing x, y and z coordinates. When drawing this it only shows one vertex (Gl_POINTS) at the centre of the screen. Help appreciated. * I have tried this, using one big array containing vertices data. Where every coordinate is at its own index. So MyVertex vertices = new MyVertex[nrChannel * DRAWDATASIZE * 3]. This gave me the same results.

int vboId;
MyVertex[,] vertices;

struct MyVertex
{
    public float x, y, z;
};

...


I am filling the buffer with vertices here:

vertices = new MyVertex[nrChannels, DRAWDATASIZE]; //nrChannels = 10, DRAWDATASIZE = 100

for (Byte channel = 0; channel < nrChannels; channel++)
{
    for (int position = 0; position < DRAWDATASIZE; position++)
    {
        vertices[channel, position].x = position;
        vertices[channel, position].y = depth; // Depth has been initialized, but not been included in the code snippet
        vertices[channel, position].z = 0;
    }
}

// generate a new VBO and get the associated ID
Gl.glGenBuffers(1, out vboId);

// bind VBO in order to use
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vboId);

// upload data to VBO
Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(sizeof(float) * 3 * vertices.Length), vertices, Gl.GL_STATIC_DRAW);



Then Drawing the scene:

...

Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
                
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vboId);
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, vertices);
Gl.glDrawArrays(Gl.GL_POINTS, 0, vertices.Length);

...


What am I doing wrong? Regards, Bas
Advertisement
You are calling Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, vertices); instead of
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, NULL);
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Although you are completely right, it doesn't fix the problem. I think I found a solution on OpenTK. By using Stride, defined in the MyVertex struct, instead of using (IntPtr)(sizeof(float) * 3 * vertices.Length).

I am able to draw the complete VBO. But it still doesn't give my the flexibility to hide/show certain point. I basically have an 2D array with [channel, vertexdata]. So every channel contains some vertices, which I want to draw. Is it possible to just draw one channel, or some specific channels? I can be using the following for loop, this works when every channel contains the same amount of data. But my channels don't.

 for (int i = 0; i < nrChannels; i++){if(somecondition)    Gl.glDrawArrays(Gl.GL_POINTS, i * DRAWDATASIZE, vertices.GetLength(1));} 
What's a channel?
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
A channel is basically a property of my data points. So every data point has a position (x,y,z) and has got some other properties, e.g. channel.

I want to be able to show or hide points belonging to the same channel. But is not really important what a channel is. My question should perhaps be asked more generally: Can I use multiple Vertex Buffer Objects (i.e. One per channel). And how am I able to draw vertices belonging to one VBO?

Do I just have to bind the buffer for each VBO, with a different index?

Like: Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vboId[ChannelNumber]);

Regards,

Bas
Sure, you can use multiple vertex buffer objects. You can use a single vertex buffer and multiple index buffers as well. The indices in the index buffers will reference the data in the vertex buffer. The draw call itself will be then glDrawElements instead of glDrawArrays.

You have to enable each vertex attribute separately. Have you called glEnableVertexAttribArray(0)?
you should not call glEnableVertexAttribArray(0). use the glEnableClient
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Thanks, V-Man and Decibit. I think I've got it right.

Just to make sure:

I only have to call glEnableVertexAttribArray(0) or glEnableClient when I am using index buffers, right? I am not using index buffers, so I should be fine by only calling Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);?

Regards,

Bas
Quote:Original post by BSchoen
Thanks, V-Man and Decibit. I think I've got it right.

Just to make sure:

I only have to call glEnableVertexAttribArray(0) or glEnableClient when I am using index buffers, right? I am not using index buffers, so I should be fine by only calling Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);?

Regards,

Bas

Not quite. The both functions glEnableVertexAttribArray and glEnableClientState do the same. glEnableVertexAttribArray is however more general and treats all the vertex attributes (positions, normals, etc.) same. Moreover glEnableClientState may be deprecated in some of the newest OpenGL profiles.

Still you have to call at least one of them if you are using vertex buffers.
Since he is using glVertexPointer, he must use glEnableClientState.
If you use glVertexAttribPointer, then you call glEnableVertexAttribArray.
These things go in pairs.

If glEnableClientState is deprecated, then so is glVertexPointer. You are probably thinking of GL 3.0
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

This topic is closed to new replies.

Advertisement