在不同的VBO中存储不同的顶点属性

发布于 2024-12-01 23:24:56 字数 1125 浏览 0 评论 0原文

是否可以将不同的顶点属性存储在不同的顶点缓冲区中?

到目前为止我见过的所有例子都是这样的

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

绘图是这样完成的:

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

难道不能将位置数据和颜色数据存储在不同的VBO中吗?问题是我不明白这是如何解决的,因为你不能同时绑定两个缓冲区,可以吗?

如果有一个简单但低效的解决方案,我会更喜欢它而不是更复杂但高效的解决方案,因为我处于初级学习状态,我不想让事情变得太复杂。

另外,如果我的要求是可能的,这是一个好主意吗?

澄清一下:我确实了解如何在不同的 VBO 中存储不同的属性。我不明白以后要怎么画它们。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小嗲 2024-12-08 23:24:56

属性位置 X 和提供该属性的缓冲区对象之间的关联是通过glVertexAttribPointer 命令建立的。它的工作方式很简单,但不直观。

在调用 glVertexAttribPointer(这是很多人没有理解的部分),当前绑定到 GL_ARRAY_BUFFER 的任何缓冲区对象都会变成与属性 X 关联,其中 X 是 glVertexAttribPointer 的第一个参数。

因此,如果您想要一个来自一个缓冲区的属性和一个来自另一个缓冲区的属性,您可以这样做:

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

至于是否应该将属性拆分到不同的缓冲区中...我想说,只有当您有以下情况时才应该这样做:明显的需求

例如,假设您正在制作动态高度图,可能是为了某种水效果。每个元素的 Z 位置发生变化,但这也意味着法线发生变化。但是,XY 位置和纹理坐标不会改变。

高效的流通常需要双缓冲缓冲区对象或使它们无效(使用 glBufferData(NULL) 或 glMapBufferRange(GL_INVALIDATE_BIT) 重新分配它们)。仅当流数据位于非流数据的另一个缓冲区对象中时,任何一种方法都有效。

另一个明显需要的例子是,如果内存是一个问题并且多个对象共享某些属性列表。也许对象具有不同的位置和法线数组,但具有相同的颜色和纹理坐标数组。或者类似的东西。

但除此之外,最好将对象的所有内容都放入一个缓冲区中。即使您不交错数组。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文