So, in both D3D and OpenGL there's ability to draw from an index buffer.
The OBJ file format however does something weird. It specifies a bunch of vertices like:
v -21.499660 6.424470 4.069845 v -25.117170 6.418100 4.068025 v -21.663851 8.282170 4.069585 v -21.651890 6.420180 4.068675 v -25.128481 8.281520 4.069585
Then it specifies a bunch of normals like..
vn 0.196004 0.558984 0.805680 vn -0.009523 0.210194 -0.977613 vn -0.147787 0.380832 -0.912757 vn 0.822108 0.567581 0.044617 vn 0.597037 0.057507 -0.800150 vn 0.809312 -0.045432 0.585619
Then it specifies a bunch of tex coords like
vt 0.1225 0.5636 vt 0.6221 0.1111 vt 0.4865 0.8888 vt 0.2862 0.2586 vt 0.5865 0.2568 vt 0.1862 0.2166
THEN it specifies "faces" on the model like:
f 1/2/5 2/3/7 8/2/6 f 5/9/7 6/3/8 5/2/1
Where we're v/t/n the first number is an index into the vertices array, the second an index into the tex coord array, the third, into the normals array.
So, in trying to render this with vertex buffers,
In OpenGL I can use glVertexPointer
, glNormalPointer
and glTexCoordPointer
to set pointers to each of the vertex, normal and texture coordinate arrays respectively.. but when it comes down to drawing with glDrawElements
, I can only specify ONE set of indices, namely the indices it should use when visiting the vertices.
Ok, then what? I still have 3 sets of indices to visit.
In d3d its much the same - I can set up 3 streams: one for vertices, one for texcoords, and one for normals, but when it comes to using IDirect3DDevice9::DrawIndexedPrimitive, I can still only specify ONE index buffer, which will index into the vertices array.
So, is it possible to draw from vertex buffers using different index arrays for each of the vertex, texcoord, and normal buffers (EITHER d3d or opengl!), or must I create a single interleaved array and then visit IT?
An index buffer is essentially an array of pointers into the vertex buffer. It allows you to reorder the vertex data, and reuse existing data for multiple vertices.
The index buffer contains integers, three for each triangle in the mesh, which reference the various attribute buffers (position, colour, UV coordinates, other UV coordinates, normal, …). It's a little bit like in the OBJ file format, with one huge difference : there is only ONE index buffer.
A constant buffer allows you to efficiently supply shader constants data to the pipeline. You can use a constant buffer to store the results of the stream-output stage. Conceptually, a constant buffer looks just like a single-element vertex buffer, as shown in the following illustration.
OBJ was not designed to map to OpenGL or DirectX.
Everything you said is true, and no, it's not possible to use per-attribute indices.
You have to convert the OBJ representation to something that only uses a single index per vertex (possibly duplicating some vertex data along the way).
What you really want to be doing (speaking from the D3D side of the fence, I don't know OpenGL sorry) is loading the OBJ in to an array of custom vertex format--that way you have a struct with the index, vertex, normal and tex coord in it and you can just render it using one DrawIndexedPrimtive.
Am I misunderstanding your problem definition here? I think you need to give a little more detail--you shouldn't need multiple index buffers to render a single OBJ file (unless you are deliberately batching it). If that is the case, that you are deliberately batching it, then you should take a look at the arguments to DrawIndexedPrimitive which allow you to specify an offset in to the VB to use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With