OpenGL Vertex Buffer Object (VBO)

This topic is 3145 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

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

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

Share on other sites
You are calling Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, vertices); instead of
Gl.glVertexPointer(3, Gl.GL_FLOAT, 0, NULL);

Share on other sites
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));}

Share on other sites
What's a channel?

Share on other sites
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

Share on other sites
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)?

Share on other sites
you should not call glEnableVertexAttribArray(0). use the glEnableClient

Share on other sites
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

Share on other sites
Quote:
 Original post by BSchoenThanks, 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.

Share on other sites
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

1. 1
2. 2
3. 3
Rutin
22
4. 4
5. 5

• 11
• 18
• 14
• 9
• 9
• Forum Statistics

• Total Topics
632929
• Total Posts
3009282
• Who's Online (See full list)

There are no registered users currently online

×