Jump to content
  • Advertisement
Sign in to follow this  
BSchoen

OpenGL Vertex Buffer Object (VBO)

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

If you intended to correct an error in the post then please contact us.

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

// 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

Share this post


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

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
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.

Share this post


Link to post
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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!