OpenGL -纹理使用glDrawElements被错误地映射
OpenGL - texture are mapped incorrectly using glDrawElements
我正在创建一个OBJ解析器,它读取文件并使用glDrawElements绘制它。这里的事情是模型是正确绘制的,但当我试图给它一个纹理,它是不正确的映射。我在这里读到"OpenGL只能使用一个索引缓冲区,而OBJ通过属性使用一个索引缓冲区"。我还研究了纹理在使用glDrawElements时被错误映射,并发现我需要重新排列纹理,因为只有顶点是共享的,而不是纹理。说了这么多,我该如何重新排列纹理呢?我应该复制一些纹理吗?
OBJ格式指定唯一的纹理坐标、顶点和面。
Opengl与OBJ无关,当然,所以它想要的只是在正确的位置有正确的信息。
想象在你的OBJ中有两个这样的面(注意两个面的顶点1的文本坐标)
f: v1 |t1| v2 t2 v3 t3
f: v1 |t2| v4 t4 v5 t5
你的INDEX缓冲区像这样:
1 2 3 1 4 5
你的opengl顶点缓冲区首先看起来像这样:
v1 v2 v3 v4 v5
如果你添加纹理坐标,你在哪里添加它们?像这样的吗?
v1 t1 v2 t2 v3 t3 v4 t4 v5 t5
这很可能是你现在的样子,这是错误的,因为opengl使脸像这样:
f: v1 |t1| v2 t2 v3 t3
f: v1 |t1| v4 t4 v5 t5
因为v1和t1通过indexbuffer链接在一起,请注意OBJ和OpenGL中的顶点之间的差异。
有几种方法可以解决这个问题。我建议去掉indexbuffer,因为它只会使一切变得复杂。如果没有索引缓冲区,您只需提供所有的面,就好像它们是唯一的一样,并使用不同的绘制调用(glDrawArrays)。你的顶点缓冲区看起来像这样:
v1 |t1| v2 t2 v3 t3 v1 |t2| v4 t4 v5 t5
您复制了v1,但实际上大多数时候没有那么多额外的数据,因为您不再需要指定索引缓冲区。
这种事情想起来真的很烦人,我尽力让它平易近人,我希望我没有犯任何错误。
我不太熟悉OBJ,但你说的是OBJ可以通过索引每个顶点引用不同的属性。你有一个大的xyz数组,另一个大的uv数组。每个顶点都有一个到xyz数组的索引和另一个到uv数组的索引。但是opengl每个顶点只有一个索引!因此,如果xyz和uv索引不同,opengl将无法工作。解决这个问题的一个简单方法是循环遍历所有顶点,如果它们的uv索引与xyz索引不相同,只需将两者的数据复制到它们的缓冲区的末尾,并将索引设置为该值。
- C++映射分割错误(核心转储)
- 错误处理.将系统错误代码映射到泛型
- 删除映射和分割错误中的一个过去结束元素
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- OpenGL 4.3 错误地将第 4 个纹理坐标映射到与第 3 个纹理坐标相同的位置
- 线程时访问静态映射时出现隔离错误
- C++ 将元素分配给映射值时访问错误
- C++映射容器 erase() 分段错误
- 为C++中的无序映射获取给定输入键的错误值
- std::映射服装比较函数和函数/lambda错误
- 自定义哈希表实现-将字符串映射到整数时出现内存错误
- 使用无序映射进行错误索引
- std::映射导致插入时出现C2664错误
- 与映射和unordered_map相关的编译错误:"attempting to reference a deleted function"
- 在共享内存中插入映射映射时出现编译器错误
- 访问range_expression中的嵌套元素会返回不完整的映射(段错误)
- std::map 擦除 - 将迭代器传递给错误的映射
- 解析序列/映射节点时出现无效的 yaml 节点错误
- 为什么 du -sh 输出错误大小的内存映射文件
- C ++尝试访问映射中的元素会给我一个不匹配的函数调用错误