1

例如,我想在一个网格上绑定 80 个纹理并将其放入我的 VBO。我怎样才能做到这一点?

我读过 glActiveTexture 能够做到这一点,但是它最多允许大约 32 个纹理(取决于 GPU)。

我的 VBO 代码:

//Generating VBO
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d) + textureCoords.size()*sizeof(Vector2d), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size()*sizeof(Vector3d), vertices.data());
glBufferSubData(GL_ARRAY_BUFFER, vertices.size()*sizeof(Vector3d), textureCoords.size()*sizeof(Vector2d), textureCoords.data());

glGenBuffers(1, &IND);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size()*sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);

//Drawing VBO:
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

glVertexPointer(3, GL_DOUBLE, 0, 0);
glTexCoordPointer(2, GL_DOUBLE, 0, (void*)(vertices.size()*sizeof(Vector3d)));

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IND);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void*)0);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
4

2 回答 2

2

绑定许多(100 个)纹理

我不确定一次绑定那么多单独的纹理的方法。有无绑定的纹理,但我对该扩展没有太多经验。如果您的许多纹理大小相同,您也可以使用数组纹理。但是解决这个问题的标准方法是使用纹理图集,将大量纹理打包到其中,记录它们的放置位置并调整纹理坐标以匹配。

更新:您还可以使用许多纹理数组来存储纹理图集(请参阅评论和@Ethan 的答案)。


将多个纹理应用于网格

我将如何告诉 VBO,哪些面孔将具有哪些纹理?

我认为更直接的问题是如何将不同的纹理(或材质)应用于同一个网格。有几件事要考虑...

  1. 应用多个纹理的最常见情况是每个纹理都存储不同的材质属性,但它们都使用相同的纹理坐标/“UV”。例如漫反射贴图、法线贴图、镜面贴图。我猜在极端情况下,当你有 100 种不同的属性时,你会想要一个数组纹理。

  2. 如果每个纹理需要以不同方式映射,则每个纹理都有一个单独的每个顶点纹理坐标 VBO。然后,您必须决定纹理在应用时如何相互作用或混合。

  3. 每个面都有完全独立的材料/纹理。通常,网格上只有几种材料。您渲染它的方式是在单独的批次中,按材质分组。绑定正确的纹理,设置着色器制服,绘制三角形索引 A 到 B。

  4. 如果几乎每张脸都有不同的材料。我想如果您正在绘制具有许多不同图块的基于图块的游戏,可能就是这种情况。这里的问题是绘制调用的数量成为瓶颈,因此您必须将不同的材料组合到同一个绘制调用中。您可以通过将材质存储在顶点属性上来做到这一点,例如添加顶点颜色 VBO。除了颜色之外,您还可以存储每个顶点的纹理 ID,如果您使用的是纹理图集,则可以在图集中找到纹理的区域。这开始变得低效,因为您将在三角形的每个顶点上多次存储相同的材质数据。为了最小化开销,您可以为每个顶点存储一个材质索引,它指向在某处的表中定义的材质(在一个小的统一数组中,或者如果您需要更多材质,另一个纹理)。然后将纹理 ID 和图集区域添加到表中的材质中。

    希望最后一点能回答你的问题。

于 2015-05-26T14:03:15.273 回答
2

老实说,如果一个网格有超过 32 个纹理,那么您可能会遇到比绑定问题更大的问题。但是如果你坚持拥有这么多纹理,你有两个选择:无绑定或纹理数组。但是,也有缺点: Bindless 会限制你的硬件支持。纹理数组确实要求纹理具有相同的大小和格式。我个人认为 Texture Array 是一个可行的解决方案。如果可能,您可以尝试调整纹理的大小,然后将具有相同大小和格式的纹理组合到一个数组中。现在,您有 32 个数组可供使用,这应该绰绰有余,例如,一个数组用于所有反照率纹理,一个用于所有法线贴图等。关于调整大小,请考虑将纹理缩放到您拥有的最大尺寸,或者可能分为小、中、大等类别。避免任意大小。

于 2015-05-27T04:42:34.173 回答