我正在创建一个OBJ解析器,它读取文件并使用glDrawElements绘制它。这里的事情是模型被正确绘制,但当我尝试给它一个纹理时,它被错误地映射。我已阅读here" OpenGL只能使用一个索引缓冲区,而OBJ使用一个索引缓冲区属性"。我还研究了使用glDrawElements时纹理被错误映射的情况,并发现我需要重新排列纹理,因为只有顶点是共享的而不是纹理。说完所有这些之后,我应该如何重新排列纹理?我应该复制一些纹理吗?有关我得到的示例输出,请参阅此link。
答案 0 :(得分:2)
OBJ格式指定UNIQUE纹理坐标,顶点和面。
当然,Opengl与OBJ无关,所以它只需要在正确的地方提供正确的信息。
想象一下你的OBJ中有两个这样的面孔(注意两个面上的顶点1个texcoords)
f: v1 |t1| v2 t2 v3 t3
f: v1 |t2| v4 t4 v5 t5
您的INDEX缓冲区如下:
1 2 3 1 4 5
您的opengl VERTEX缓冲区首先如下所示:
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
因为你的indexbuffer将v1和t1链接在一起,所以注意OBJ和OpenGL中顶点之间的差异。
有几种方法可以解决这个问题。我建议摆脱indexbuffer,因为它只会使一切变得复杂。如果没有索引缓冲区,只需将所有面提供为唯一,并使用不同的绘制调用(glDrawArrays)。您的顶点缓冲区将如下所示:
v1 |t1| v2 t2 v3 t3 v1 |t2| v4 t4 v5 t5
你复制了v1,但实际上它并不是大部分时间的额外数据,因为你不必再指定一个索引缓冲区了。
考虑到这种东西真的很烦人,我尽力让它变得平易近人,我希望我没有犯任何错误。
答案 1 :(得分:0)
我对OBJ不太熟悉,但你说的是OBJ可以通过每个顶点的索引引用不同的属性。你有一个很大的xyz阵列,另一个很大的uv阵列。然后每个顶点都有一个xyz数组的索引和另一个进入uv数组的索引。但是opengl每个顶点只有一个索引!因此,如果xyz和uv索引不同,opengl将无法正常工作。解决这个问题的一个简单方法是循环遍历所有顶点,如果它们的uv索引与xyz索引不同,只需将两者的数据复制到缓冲区的末尾并将索引设置为。