4

Reading my obj file, and only taking into account the vertices and the indices thereof, my object renders the required object as far as vertices are concerned; for now I'm using just a basic color array so I can ascertain my loader works. What I realized is that OpenGL wasn't drawing my object correctly before because the uv indices were being read with the vertex indices - I read all the indices from a line say:

f 2/3/4 3/6/1 1/3/6

Into one vector which I then passed to GL_ELEMENT_ARRAY_BUFFER. Unfortunately OpenGL (nor DirectX) allow more than one index buffer. So, that means I can't have a separate vector which only holds uv indices, with another holding vertex indices; or another holding the normal indices. With only having one index buffer, and therefore only one vector which holds the indices for vertices, textures and normals; how can I instruct OpenGL to draw the primitive prescribed in the obj file without omitting one index in favor of another?

Note: I'm drawing the primitive using glDrawElements(..); I have used glDrawArrays(..) in the past but this time I want to use the former method for efficiency.

Poriferous
  • 1,566
  • 4
  • 20
  • 33
  • See http://stackoverflow.com/q/23349080/3530129. My answer there has some pseudo-code to build the vertex and index buffer. – Reto Koradi Dec 02 '14 at 08:19

2 Answers2

2

If they allowed multiple index buffers, it would just give you a nice performance gun to shoot yourself in the foot with.

What you can do, though, is to unpack your model data into an (i.e. interleaved) VBO with [Position, Normal, Texccord] structure and fill it manually with appropriate data. This will consume more memory, but will allow you to simply render it unindexed.

The "efficiency" you speak of would only happen shall the triplets have common duplicates. If they indeed do so, it's up to you to find them, number the unique triplets accordingly and create an index buffer for them.

Have fun :)

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
1

Instead of creating separate vertex arrays with that hold vertex positions and uvs

verts = [vec3f, vec3f, ...]
norms = [vec3f, vec3f, ...]
uvs = [vec2f, vec2f, ...]

You should create a single array that defines each vertex in terms of all three attributes

verts = [(vec3f, vec3f, vec2f), (vec3f, vec3f, vec2f), ...]

Then each index will correspond to a single vertex. This does mean you will have to duplicate some of your information from the OBJ file into the vertex array, since each vertex corresponds to a unique triplet in the OBJ file. You can specify your attributes using different sizes in the stride and position arguments to glVertexAttribPointer

Mokosha
  • 2,737
  • 16
  • 33
  • So, I got three vectors: vertices, normals and textures. You're saying I should put all the data therein to one vector? So what do I do with the indices? Should they still be in a single vector too? – Poriferous Dec 01 '14 at 15:56
  • Yes, you should have a total of two vectors (or arrays, or whatever): one with vertices, one with indices. You will have to regenerate the indices to match the newly constructed vertices from the unique triplets in the faces of your OBJ file. – Mokosha Dec 01 '14 at 15:58
  • I'd have to pass something like this after: glBindBuffer(GL_ARRAY_BUFFER, vertHandle); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, ?, NULL); Although I'm not sure what to use as the stride... – Poriferous Dec 01 '14 at 16:04
  • For `glVertexAttribPointer`, the stride is the number of bytes between vertex attributes. For a full example, take a look at "Rendering a triangle #2" [here](https://www.opengl.org/wiki/VBO_-_just_examples) – Mokosha Dec 01 '14 at 16:15