The problem is that obj files contain vertex data in parts:pos,tex,normal and indices in them point to each of these parts individually. In OpenGL you need to combine those parts into one data object - vertex. And have your indices point to vertices, not their parts.
My code (scala, but should be ok)
val vertexListB = new RList[vec3]()//output positions
val texListB = new RList[vec2]()//output texCoords
val normalListB = new RList[vec3]()//output normals
val indexListB = new RList[Int]()//output indices
val vertices = new RList[VertexFull]()//output vertex structure list, consists of pos, tex, normal
for(i <- 0 until vertexIndicesTriangleList.size()){
val vI = vertexIndicesTriangleList(i) //vertexIndicesTriangleList - all scanned vertex positions from obj file
val tI = texCoordsIndicesTriangleList(i) //texCoordsIndicesTriangleList - all scanned vertex texture coords from obj file
val nI = normalIndicesTriangleList(i)//normalIndicesTriangleList - all scanned vertex normals from obj file
//we are looping through all vertex positions
val v = vertexList(vI) //some pos
val t = textureList(tI)//some texCoord that corresponds to that pos
val n = normalList(nI)//some normal that corresponds to that pos
val hv = vertexListB.getIndex(v,false)
val ht = texListB.getIndex(t, false)
val hn = normalListB.getIndex(n, false)
if(ht != -1 && hv == ht && hn == ht){ //check for duplicate vertex data, its duplicated if and only if all of 3 components:pos, tex and normal are equal
indexListB << hv //if ht != -1 then our list doesntdoes contain that vertex yetalready
}
else{
vertexListB << v //if doesnt contain/not duplicated then put data into the lists
texListB << t
normalListB << n
indexListB << vertexListB.size() - 1//index points to the last put vertex, vertexListB, texListB, normalListB are equal sized
}
}
for(i <- 0 until vertexListB.size()){
vertices << new VertexFull(vertexListB(i), texListB(i), normalListB(i))
}