Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

Is it possible to store different vertex attributes in different vertex buffers?

All the examples I've seen so far do something like this

float data[] = 
{
//position
   v1x, v1y, v1z,
   v2x, v2y, v2z,
   ...
   vnx, vny, vnz,

//color
   c1r, c1g, c1b,
   c2r, c2g, c2b,
   ...
   cnr, cng, cnb,   
};
GLuint buffname;
glGenBuffers(1, &buffname);
glBindBuffer(GL_ARRAY_BUFFER, buffname);
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);

And the drawing is done something like this:

glBindBuffer(GL_ARRAY_BUFFER, buffname);
glEnableVertexAttrib(position_location);
glEnableVertexAttrib(color_location);
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, (void*)(3*n));

glDrawArrays(GL_TRIANGLES, 0, n/3);

glDisableVertexAttrib(position_location);
glDisableVertexAttrib(color_location);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Isn't it possible to store position data and color data in different VBOs? The problem is I don't understand how this would work out because you can't bind two buffers at once, can you?

If there is a simple but inefficient solution, I would prefer it over a more complicated but efficient solution because I am in primary learning state and I don't want to complicate things too much.

Also, if what I'm asking is possible, is it a good idea or not?

To clarify: I do understand how I could store different attributes in different VBO's. I don't understand how I would later draw them.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
180 views
Welcome To Ask or Share your Answers For Others

1 Answer

The association between attribute location X and the buffer object that provides that attribute is made with the glVertexAttribPointer command. The way it works is simple, but unintuitive.

At the time glVertexAttribPointer is called (that's the part a lot of people don't get), whatever buffer object is currently bound to GL_ARRAY_BUFFER becomes associated with the attribute X, where X is the first parameter of glVertexAttribPointer.

So if you want to have an attribute that comes from one buffer and an attribute that comes from another, you do this:

glEnableVertexAttrib(position_location);
glEnableVertexAttrib(color_location);
glBindBuffer(GL_ARRAY_BUFFER, buffPosition);
glVertexAttribPointer(position_location, 3, GL_FLOAT, GL_FALSE, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, buffColor);
glVertexAttribPointer(color_location, 3, GL_FLOAT, GL_FALSE, 0, 0);

As for whether you should split attributes into different buffers... I would say that you should only do it if you have a demonstrable need.

For example, let's say you're doing a dynamic height-map, perhaps for some kind of water effect. The Z position of each element changes, but this also means that the normals change. However, the XY positions and the texture coordinates do not change.

Efficient streaming often requires either double-buffering buffer objects or invalidating them (reallocating them with a glBufferData(NULL) or glMapBufferRange(GL_INVALIDATE_BIT)). Either way only works if the streamed data is in another buffer object from the non-streamed data.

Another example of a demonstrable need is if memory is a concern and several objects share certain attribute lists. Perhaps objects have different position and normal arrays but the same color and texture coordinate arrays. Or something like that.

But otherwise, it's best to just put everything for an object into one buffer. Even if you don't interleave the arrays.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...