Jump to content
  • Advertisement
Sign in to follow this  
Corefanatic

OpenGL glDrawElements, ,obj format and indices problem

This topic is 3066 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to code up an importer of .obj files in to my game. Now, an .obj file looks something like this: # cube.obj # mtllib cube_texture.mtl g cube usemtl blinn1SG v 0.0 0.0 0.0 v 0.0 0.0 1.0 v 0.0 1.0 0.0 v 0.0 1.0 1.0 v 1.0 0.0 0.0 v 1.0 0.0 1.0 v 1.0 1.0 0.0 v 1.0 1.0 1.0 vn 0.0 0.0 1.0 vn 0.0 0.0 -1.0 vn 0.0 1.0 0.0 vn 0.0 -1.0 0.0 vn 1.0 0.0 0.0 vn -1.0 0.0 0.0 vt 0.0 0.0 vt 1.0 0.0 vt 1.0 1.0 vt 0.0 1.0 f 1/1/2 7/3/2 5/2/2 f 1/1/2 3/4/2 7/3/2 f 1/1/6 4/3/6 3/4/6 f 1/1/6 2/2/6 4/3/6 f 3/1/3 8/3/3 7/4/3 f 3/1/3 4/2/3 8/3/3 f 5/2/5 7/3/5 8/4/5 f 5/2/5 8/4/5 6/1/5 f 1/1/4 5/2/4 6/3/4 f 1/1/4 6/3/4 2/4/4 f 2/1/1 6/2/1 8/3/1 f 2/1/1 8/3/1 4/4/1 v are vertices, vn are normals and vt are texture coordinates. F are faces, with three vertices with indices to their vertex value, texture coordinates and normals, in format vertex/uv/normal. there also groups (example above is a single group), which have their own faces, like body of a car would be one group and each wheel would have a group on its own. Since the .obj file format is based on indices, I thought I'd use the same approach in opengl to avoid multiple copies of data as much as possible. Now my problem lies with glDrawElements and its use of a single index array. consider this code: glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3,GL_FLOAT,0,&m_vertices[0]); glNormalPointer(GL_FLOAT,0,&m_normals[0]); glTexCoordPointer(2,GL_FLOAT,0,&m_uvs[0]); glDrawElements(GL_TRIANGLES,m_vertIndex.size(),GL_UNSIGNED_INT,&m_vertIndex[0]); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); I use index array for my vertices (m_vertIndex, a stl vector of unsigne ints) and my geometry draws fine, but my texture coordinates and normals are all over the place. This is of course due to the fact that indices to vertices do not apply correctly to arrays of texture coordinates and normals. Is there a way to use a separate index array for my texture coordinates and my normals, so that I can make use of shared data? I know I can go around this my using glBegin and glEnd for each face by looking up correct values for each vertex coordinate, texture coordinate and normal for each of the three vertices of a triangle, but it seems to me that it may not be the most efficient way of doing things, especially with very large and detailed geometry. Any help is greatly appreciated, thx.

Share this post


Link to post
Share on other sites
Advertisement
Quote:

Is there a way to use a separate index array for my texture coordinates and my normals, so that I can make use of shared data?

No, all attributes must share the same index, therefore you must duplicate any attributes from the obj that are shared yet have differing secondary attributes.

You definitely want to do this, so don't concern yourself with the tiny amount of extra memory it will use to duplicate the verts.

Quote:
I know I can go around this my using glBegin and glEnd for each face by looking up correct values for each vertex coordinate, texture coordinate and normal for each of the three vertices of a triangle, but it seems to me that it may not be the most efficient way of doing things, especially with very large and detailed geometry.

You are right, this is a bad way to do it. You simply will not be able to push any high resolution models with glBegin/End, it is orders of magnitude slower than using buffers.



Also, don't forget to subtract 1 from all the obj indices to make them zero-based. This trips up a lot of first time obj converters.

Share this post


Link to post
Share on other sites
Quote:
Original post by karwosts
Quote:

Is there a way to use a separate index array for my texture coordinates and my normals, so that I can make use of shared data?

No, all attributes must share the same index, therefore you must duplicate any attributes from the obj that are shared yet have differing secondary attributes.

You definitely want to do this, so don't concern yourself with the tiny amount of extra memory it will use to duplicate the verts.

Quote:
I know I can go around this my using glBegin and glEnd for each face by looking up correct values for each vertex coordinate, texture coordinate and normal for each of the three vertices of a triangle, but it seems to me that it may not be the most efficient way of doing things, especially with very large and detailed geometry.

You are right, this is a bad way to do it. You simply will not be able to push any high resolution models with glBegin/End, it is orders of magnitude slower than using buffers.



Also, don't forget to subtract 1 from all the obj indices to make them zero-based. This trips up a lot of first time obj converters.


Thx, I'm parsing the file fine, didn't forget the -1 for the indices :). So, now that I don't have to worry about the size of my uv and normal array (their maximum size is gonna be same as the amount of vertices), wondering whether I should just create and arrays of uvs and normals according to the index array?




Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!