问题
I am creating an OBJ parser which reads the file and draw it using glDrawElements. The thing here is the model is correctly drawn but when I try to give it a texture, it is incorrectly mapped. I have read here that "OpenGL can only use one index buffer, whereas OBJ use one index buffer by attribute". I have also researched about the textures being incorrectly mapped when using glDrawElements and found out that I need to rearrange the textures because only vertices are shared but not the textures. Having said all of this, how should I suppose to rearrange the textures? Should I duplicate some textures? Please refer to this link for the sample output I get.
回答1:
The OBJ format specifies UNIQUE texture coordinates, vertices and faces.
Opengl has nothing to do with OBJ, of course, so all it wants is the right information at the right place.
Imagine two faces like this in your OBJ (Notice vertex 1 texcoords in both faces)
f: v1 |t1| v2 t2 v3 t3
f: v1 |t2| v4 t4 v5 t5
Your INDEX buffer like this:
1 2 3 1 4 5
Your opengl VERTEX buffer first looks like this:
v1 v2 v3 v4 v5
If you add texture coordinates, where do you add them? Like this?
v1 t1 v2 t2 v3 t3 v4 t4 v5 t5
This is likely what you have now, its wrong because opengl makes the faces like this:
f: v1 |t1| v2 t2 v3 t3
f: v1 |t1| v4 t4 v5 t5
Because v1 and t1 are linked together by your indexbuffer, notice the difference between the vertices in the OBJ and in OpenGL.
There are a couple of ways to solve this. I'd recommend getting rid of the indexbuffer, because it only complicates everything. Without the index buffer, you simply supply all faces as if they are unique, and use a different draw call (glDrawArrays). Your vertex buffer will look like this:
v1 |t1| v2 t2 v3 t3 v1 |t2| v4 t4 v5 t5
You duplicate v1, but really its not so much extra data most of the time, since you don't have to specify an index buffer anymore.
This kind of stuff is really annoying to think about, I tried my best to make it approachable, and I hope I didn't make any mistakes.
回答2:
I am not too familiar with OBJ, but what you say is that OBJ can reference different attributes by index per vertex. You have one big array of xyz, another big array of uv. And every vertex then has an index into the xyz array and another index into the uv array. But opengl only has one index per vertex! So if the xyz and uv index are different opengl will not work. One easy way to fix this is to loop through all vertices, and if their uv index is not the same as the xyz index, just copy the data of both to the end of their buffers and set the index to that.
来源:https://stackoverflow.com/questions/31649682/opengl-texture-are-mapped-incorrectly-using-gldrawelements