Thread: 3d model file format for use in OGL: should faces share vertices or not?

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    125

    3d model file format for use in OGL: should faces share vertices or not?

    So I'm dabbling in game design for a bit, and am trying to get some 3d models onto the screen without using any deprecated OpenGL features. Obviously that means no fixed functionality, so no glTexCoord or glVertex; everything's in vertex buffer objects now.
    This however causes a new problem; as far as I can tell when rendering from a VBO you only pass a single index buffer object that refers to one VBO or a single set of equally sized (same amount of indices) VBOs.
    Now, with fixed functionality I could have a set of 3d vertices, a set of texture vertices and a set of triangles that each consisted of 3 indices to 3d vertices and 3 indices for texture vertices (for each UV layer). This way, you generally end up with less 3d and texture vertices than faces.
    With VBOs however since apparently you can pass only one index for each vertex, each vertex that has different texture coordinates (on any layer) now has to be a unique vertex. If you have more than one UV layer, that's going to be practically every vertex. So, I guess I could just make 3 whole new vertices for each triangle. (i.e. the index buffer object would look like [0,1,2,3,4,5,6,7,8,9,10...], just passing each vertex in order)
    This seems like a waste of memory space though; for a regular sized model (say, 10000 triangles) that would mean 30000 vertices; at 12 floating point numbers per vertex that would mean a single model would take up over 1MB of video memory!
    So my question is basically, is there any alternative to just making a whole new vertex for every point on a triangle that has one property (be it any texture coordinate or even normal direction) different from all other vertices? (at which point each triangle might as well have their own vertices since there will be very few shared vertices anyway, especially when working with disjointed lightmaps) Maybe some way to pass more than one index when rendering from VBOs?
    Or, a bit more generally, what is a good format to store a model in video memory?
    Thanks!
    Last edited by Boksha; 07-11-2011 at 04:16 PM.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Direct3D overcomes some of this by using index buffers. I'm not sure if OGL has an equivalent feature.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    Actually as far as I can tell D3D works exactly like OpenGL does; you provide a buffer of vertices, each with their own data, and a buffer of indices to describe the order in which the vertices used. The problem is still the same: if any property of a triangle-corner is different from the corner of a neighbouring triangle, the triangles can't share a vertex at that point.
    In the end I decided that, for a big organic model like the 10000 triangles example I gave, the chances of all variables at a triangle corner being the same between two triangles goes up, hence it's still worthwhile to check whether two triangles can share their vertices. If it does turn out practically each triangle needs their own vertex, so be it, but I'll see how it goes first.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Normally you do not actually mess with the vertices in a model. You simply load the vertices, indices, normals, keyframes, and any other data needed to render the mesh correctly. There is a lot of modelling software out there that will handle all the nitty gritty vertex/index stuff for you. Your system should only load the data and use the data but it should not need to alter the data, save for sending the vertices to PhysX or some other physics API that might do soft body transforms on it.

  5. #5

    Join Date
    May 2005
    Posts
    1,042
    So I'm dabbling in game design for a bit, and am trying to get some 3d models onto the screen without using any deprecated OpenGL features. Obviously that means no fixed functionality, so no glTexCoord or glVertex; everything's in vertex buffer objects now.
    Why? If you're really just 'dabbling' I think you could get a lot of mileage out of immediate mode. Use of the gl***Pointer functions is still an improvement over manually stepping through the data. I was testing this today because I was using Paraview to render CFD results on a high speed boat with 13 million panels. There's an option in Paraview to use immediate mode rendering, and there was no notable change in latency while interacting (I think this is just due to how fast our hardware is).

    I think the reason for the lack of sharing is due to the glDrawArrays function, such that when you set your glVertexPointer, texpointer, etc, the stride has to be set to zero, etc.

    If you really need it to be done this way, you may be able to develop a work-around simply by using triangle strips.

    Good luck.
    I'm not immature, I'm refined in the opposite direction.

  6. #6
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    Quote Originally Posted by BobMcGee123 View Post
    Why? If you're really just 'dabbling' I think you could get a lot of mileage out of immediate mode.
    For what it's worth, after getting everything set up and working out a few silly kinks in my own code, I found using VBOs and shaders to actually be a lot more intuitive and versatile than what immediate mode can offer. For example, with fragment shaders setting up a model rendered with two blended textures and two blended lightmaps (the result of which multiplies the textures) both with different texture coordinates is a matter of just writing a simple shader with the operations, instead of having to browse through the OpenGL reference to figure out what immediate mode functions to combine. To me at least, it feels like deprecating the immediate mode functionality was not just a matter of promoting faster functions; it really did clean the API up, leaving programmers with a few simple, fundamental building blocks instead of a different function for every imaginable situation.

    As for the lack of shared vertices between faces, this was in part a wrong assumption on my part and a bug in the script I wrote export my models from Blender; like I said in my previous post, as the amount of polygons in a model goes up (and the amount of seams stays the same), the chance of a vertex being on a seam (i.e. not sharing texture coordinates between adjacent triangles) goes down, meaning more shared vertices.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  7. #7

    Join Date
    May 2005
    Posts
    1,042
    Those are good points, and defensible reasons to use shaders.

    Have you made any progress with the original problem?
    I'm not immature, I'm refined in the opposite direction.

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    On the original problem, what I do now is, in my export script (I'm making models in Blender) keep a list of vertices (initially empty), go through all the triangles of the model and for each point on the triangle, check whether a vertex with (approximately) equal parameters already exists in the list; if it does, the triangle will use that vertex, and if it doesn't, a new vertex is added to the list for that triangle. It turns out that for a complex organic model (like the inside of a cave, or a humanoid game character), this still results in a reasonably low amount of vertices per triangle, even when using multiple texture coordinates with many seams.
    Basically, I expected it to be a problem, but it turned out it wasn't.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  9. #9

    Join Date
    May 2005
    Posts
    1,042
    Well that's encouraging. What are you using for a shader compiler?
    I'm not immature, I'm refined in the opposite direction.

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Blender has a remove duplicate vertices feature for meshes.

  11. #11
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    Blender internally saves its data in a way it can't directly be rendered with VBOs in OpenGL. In fact, what could be one vertex in Blender might have to be 2 or more different vertices in a VBO if the vertex is on a texture seam, since texture coordinates are stored per face in Blender, and per vertex in a VBO. Any script exporting a Blender model to a format that can be directly loaded into a VBO has to take this into account.

    Quote Originally Posted by BobMcGee123 View Post
    What are you using for a shader compiler?
    I'm currently using OpenGL 2.0 (omitting features dropped from 3.X); precompiled shaders weren't introduced until OpenGL 4.1 as far as I'm aware, so all shaders are currently compiled from text files at runtime by the OpenGL implementation.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Which model exporter are you using and are you using the new Blender 2.5? You can also make Python scripts to create your own custom exporters. This would allow you to take Blender's internal data and output it in a format that your code can read and use. This is a vital step to nearly every game development process out there b/c streamlining the content delivery pipeline and being able to render what an artist has created in program X inside of your system is worth its weight in gold. The less obstacles there are to content creation and delivery to the engine the quicker content can be created and tested and the faster the overall game development.

    If you want to pay for a modelling program you can purchase 3DS Max or Maya. They both support writing custom plug-ins and tools as well. You probably will not get the exact format you are looking for in your engine and will probably have to create your own or settle for using an existing format and write code to read that format in.
    Last edited by VirtualAce; 07-31-2011 at 11:41 PM.

  13. #13

    Join Date
    May 2005
    Posts
    1,042
    You can also make Python scripts to create your own custom exporters
    Do you also have any experience doing this in Paraview by any chance? I've had to use Python inside Paraview for work, the Python was easy, but Paraview's interfaces are totally incomprehensible.
    I'm not immature, I'm refined in the opposite direction.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I have no experience with Paraview and it does not sound fun to work with based on your post.

  15. #15
    Registered User
    Join Date
    Mar 2002
    Posts
    125
    Yes, I wrote the export script for Blender myself; it's nice to have your files laid out in such a way you can just load them into VBOs directly.
    I'm afraid I never did anything with Paraview other than visualize electromagnetic fields and the like; I never did any scripting with it.
    Typing stuff in Code::Blocks 8.02, compiling stuff with MinGW 3.4.5.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Format for exporting a 3ds Max model to use with DX
    By alanb in forum Game Programming
    Replies: 2
    Last Post: 09-15-2009, 01:03 PM
  2. 3d Model file format
    By glo in forum Game Programming
    Replies: 4
    Last Post: 09-15-2008, 04:33 PM
  3. MD2 Model Format Issues
    By Thunderco in forum Game Programming
    Replies: 6
    Last Post: 04-17-2004, 06:37 PM
  4. model format and editor
    By Hershlag in forum Game Programming
    Replies: 3
    Last Post: 07-30-2002, 08:26 AM
  5. winding vertices
    By confuted in forum Game Programming
    Replies: 0
    Last Post: 07-21-2002, 09:54 PM