Andrew Lis
Andrew Lis

Reputation: 37

Texture coordinates in obj file for webgl

There is a .obj file with the following content:

# texcoords
vt 0.306641 0.5
vt 0.841797 0.5
vt 0.888672 0.5
vt 0.935547 0.5

# verts
v 0 2 0
v 0 2 -4
v 0 6 0
...

# faces
f 3/3/1 2/3/1 1/3/1
f 4/3/1 2/3/1 3/3/1
f 7/4/1 6/4/1 5/4/1
...

In faces part we have three items: X/Y/Z where X is a index of vertix and Y is a index of texture coords.

After parsing I have three arrays: arrays of vertices, array of faces and array of texture coords. But as we expected lengths of vertices and texture coords are not equal. Length of texture coords is equal length of faces array. But now I don't know how I can use my texture coords? Can I pass texture coords to ARRAY_BUFFER_ELEMENT or is there other way?

Upvotes: 0

Views: 437

Answers (1)

user128511
user128511

Reputation:

In general unless you use uncommon techniques you need to flatten the positions and texture coordinates into parallel arrays.

Walk the faces, for each face, generate a new position-texcoord pair (or position-normal-texcoord triple)

pseudo code

loadedPositions = [...];
loadedTexcoords = [...];

renderablePositions = [];
renderableTexcoords = [];


for each face
  renderablePositions.push(loadedPositions[face.positionIndex])
  renderableTexcoords.push(loadedTexcoords[face.texcoordIndex])

Now you can render renderablePositions/rendeableTexoords with drawArrays

It's up to you if you want to try to re-index the new renderablePositon/renderableTexcoords.

pseudo code

loadedPositions = [...];
loadedTexcoords = [...];

renderablePositions = [];
renderableTexcoords = [];
renderableIndices = [];
idToIndexMap = {};


for each face
  id = `${face.positionIndex},${face.texcoordIndex}`;
  if (idToIndexMap[id] === undefined) {
    const index = renderablePositions.length   // or length / 3
    idToIndexMap[id] = index;
    renderablePositions.push(loadedPositions[face.positionIndex])
    renderableTexcoords.push(loadedTexcoords[face.texcoordIndex])
  }
  renderableIndices.push(idToIndexMap[id])

now you can render with drawElements

A few things, a face can have more than 3 vertices so you'll have to generate triangles if you want to handle that case.

A face can have negative indices indicating an index relative to the number of positions/normals/texcoords encountered in the file so far.

the best .obj reference I've found is this one

Upvotes: 1

Related Questions