Skip to main content
GameDev.net gamedev.net
🔒 Locked

OpenGL mesh file format

Started by rick_appleton Dec 12, 2005 at 7:45 AM 25 replies 22.3k views
Original Post
rick_appleton
rick_appleton
There's a discussion going on in the General forum about the why people use OpenGL or D3D. One of the topics that has come up has been the lack of a supporting library for OpenGL. What I wanted do discuss here is the lack of a mesh file format for OpenGL. D3D has .x files which are universally accepted (as far as I know). Would Collada be able to fulfill a similar role for OpenGL? Or could OpenGL hiyack the .x format for it's meshes. I've just started looking into Collada myself and it seems quite fully featured. The only lack I can think of at the moment is that it is obviously a text based format, which would make loading somewhat slow for large files. Has anyone used this format and found it lacking in other ways?
Trienco
Trienco
If I get that right from my quick glimpse it is using xml. Creating a binary version including a converter would be pretty simple in that case. Assign an id to each kind of tag, use any xml lib like tinyxml and replace the end tag by adding the chunk size next to the tag id. With some naive optimism I dare claim that such a converter could have less than 30 lines of code (using tinyxml, not including setting up the mapping of tag-names to id).

I'd have to take a closer look if it might not be a bit too fully featured. Especially for games a "light" version would probably be enough (and speed up loading). The key difference between what I would have in mind and what most formats are is this: model format vs. scene format.
f@dzhttp://festini.device-zero.de
rick_appleton
rick_appleton
Yes I understand you comment about the difference between model and scene format. Although Collada is meant as a scene format, it specifically mentions somewhere that it is NOT a scenegraph, although it does indeed have a somewhat similar structure.

However, I feel this isn't necessarily a problem. A light version could strip out the scenegraph tags, and concentrate on the geometry and materials.
Stani R
Stani R
Quote:
Original post by rick_appleton
D3D has .x files which are universally accepted (as far as I know).

Is that true? From what I've seen, most engines out there roll their own (like n3d), or use an existing format like wavefront obj or md3 (or md5 now). Do we have any documented examples of .x files used in a released game?

Also, is there a specific reason why the file format has to depend on the rendering api?
Guimo
Guimo
Of course you could use Kaydara's FBX. Another good format is Softimage XSI which is like a .x on steroids.

Luck!
Guimo
GamerSg
GamerSg
Ill admit one thing, i hate writing exporters and while the last one i made(my 2nd) in MaxScript did what i wanted, the code was all over the place and much harder to then it would have been in C++, mainly because of my familiarity with C++/STL. However the MaxSDK has some of the worst syntax and the IGame was not much better either, both lacking decent documentation.

I almost considered using .x as an intermediate format, then me writing a .x converter for my own format. This way every major DCC tool could be used, MS would be maintaing the file format and Alias,Discreet, etc.. would be doing the dirty work of maintaining/updating the exporters. And its not like MS/DX was going to disappear anytime soon. But DirectX stores all it's stuff in weird coordinates, Z is up, Y is depth, etc....
To avoid these potential problems, i looked again. Something which could support whatever i need, would need and which had wide support.

Then i stumbled upon Ogre's xml format. There were exporters for almost every DCC tool out there and it was in xml allowing me to easily understand it's format. I tried their 3dmax exporter, but at that time, it had some problems with splitting vertices with muliple tex Coords/normals. This gave me doubts over the future of the exporter. In the end i settled to write my own exporter with much help from the source of Ogre's 3dmax exporter.

While it wasnt easy, i managed to write one with whatever i needed. But there was 1 major limitation, users of my library will only be able to use Max. Then i stumbled upon Collada. Since it is supported by the very creators of DCC Tools, they are the best people to write the exporters since they know their API best. The exporters have already been out there for quite some time now, but im feeling a little lazy to interpret/load the xml files every since i heard of the Collada API which has yet to be released. The API not only loads Collada files, but can also perform optimisations such as optimal cache reordering of indices/vertices, tri-stripping, etc... It was supposed to be released in November but has been constantly delayed.

So i am just going to improve my library in the meantime until they release the API and i write a Collada->myFormat converter using the API. And since i think Collada mainly came into existence for PS3 development because Sony did not want to lose out to MS's much hyped XNA for Xbox360/PC, it should be well supported by Sony until it matures and becomes widely supported amongst developers. It's a good thing they made it an open standard and soon it is going to support physics as well.
Red Ghost
Red Ghost
Do we really need another 3D object format ?

I have a preference for a library for loading major file formats into each of OpenGL structures.
I have a few arguments for that solution:
- the programmer must have the choice of the structure to load his object in (interlaced array, compiled vertex array, colors array, extension based array, ...).
- the elements describing an object are always the same. Only the way to externalize them differ: there are many formats available which cover practically every aspect of object loading (even binary ones). Most of the formats will be covered and maintained by existing companies.
- when looking at the needs of OpenGL programmers, I feel they are less interested in a file format than in helper functions that will give them the means to load a model and use it. The environment of OpenGL rewards quick setup (look at glut framework or OpenGL tutorials). Helper functions for loading any object file are better than transcribing from existing export files by packages into another one.

But there is a drawback. Using so many different file formats may be difficult to maintain: even if we restrain to four major file format (lightwave, milkshape, DirectX, ...), this is still four file formats times we need to maintain in the object loader library. To my mind, the only way to have a special OpenGL format would be to export the binary content of existing OpenGL structures directly in a file.

Now there are a few elements that are missing and could benefit a specialized format. Here is what I propose:
- a structure holding pointers to each OpenGL structures used for a 3D object that describes it. This is used as a binary 3D object file description when exporting a full object from OpenGL structures.
- functions for import/export of text/binary versions of OpenGL structures.
- 3D object skeletal animation library for OpenGL (perhaps a specialized OpenGL library to animate a mesh). OpenGL is kinda raw for skeletal animations.

I could propose some code for that if you are interested.
Ghostly yours,
Red.
Ghostly yours,Red.
GamerSg
GamerSg
The problem with using multiple existing formats is that you are limited by the limitations of the format. ie.You cant get skinning information from MD2.

Also there might come a time when you wish to add additional information into the format which existing formats do not support. For example you might want to include some information on particle emitters(their position,orientation, particle type) on the mesh. Or perhaps a flag indicating whether the indices are in triangles or tri-strip format. Or maybe some inverse kinematics information for the joints. Not all formats would support all your required features. It would be better to define a format to meet your requirements and

1) write a exporter for your format like Ogre/Nebula/other engines

2) Use a existing format which has all this information and convert it.

The thing about Collada is that it's goal is to retain every detail required to load the file back and be presented with the exact same results before it was exported. This goal is supposed to be cross-DCCTool compatible, meaning my 20k poly skinned King Kong with 4 material layers modelled in Max can be exported to Collada and loaded in Maya looking the same. Ofcourse Max only features which cannot be reproduced in Maya will not appear when opened in Maya, but they will be retained in the format incase the file is opened in Max again. While i doubt every feature can be reproduced, anything required for today's games should be easily available in the format.

Trienco
Trienco
Quote:
Original post by Red Ghost
I have a preference for a library for loading major file formats into each of OpenGL structures.


What do you mean with OpenGL structures? Beyond using data in arrays in one form or another it doesn't really have any structures. Everything that would be of interest to store a mesh/model is FAR beyond what OpenGL cares about. A loader for any file format doesn't make sense (as in: you couldn't write one) without having a common structure to fill. D3DX has its own mesh class, OpenGL doesn't. So any specific file format would need a specific internal representation for meshes to go along with it.

Now, considering that in most "serious" cases there will be special requirements and custom internal ways to store the data a loader library would only be interesting for beginners or prototyping. Unless we figure out a mesh/model class that is not just really flexible but also still efficient.

Usually a file format looks the way it is useful to the application. File formats meant to be universally useful and supported will have to very complex to put everything into the specs. But using xml/chunks at least allows to easily ignore unknown or "don't care" elements and also lets you add your own tags without breaking existing loaders.

What it all boils down to is that internal format, file format and loaders should be pretty much one package. File format is relatively optional if one supports multiple formats, but a streamlined "only what's really needed" format would of course be more efficient to load. A "Collada light" (and/or binary version) would then be more or less counted as an own format.
f@dzhttp://festini.device-zero.de
Red Ghost
Red Ghost
@Trienco:
I understand the need of a format to manage a mesh and I agree with you that OpenGL is very low level for mesh management contrary to D3D. This is why I proposed to add a structure that would link together all the data arrays. This would cover the most basic mesh needs and be consistent with the OpenGL framework:
- a list of vertices
- a list of faces
- a list of materials (texture + color)
- a list of texture coordinates
- a list of lights (material, description and position)

When I read your reaction, I have the feeling you want structure and helper functions like in D3D to cover interactions within a mesh like in most file formats:
- skeletal information
- animation information
- particle emitters description
- scene graph information

These are not covered by OpenGL since it is just a rendering API. IMHO, I feel that providing such structure and helper functions is closer to realizing a 3D graphics engine than simply augmenting OpenGL. What difference does it make then to use Collada or another file format ?

@all:
Now back to the subject at hand. The .x format is quite open and can easily be extended to add other information. Would using this format not tie OpenGL development to windows platform ?
Besides I would not suggest to hijack the .x format for meshes unles we decide to improve on it. Here are the drawbacks I found based on DX version 8 of the format:
- there are more than one way to declare the mesh object (within a bone, independantly of any other blocks, scattered between many bones).
- the mesh object cannot be multitextured on the same faces.
- The format mixes scene graph et skeletal information (both are declared in the same block. This means that either you declare a vertebrate model, or you declare a scene else the file format becomes very confusing).
- The binary format is dependant on the program which generated it: either it is a translation of a text format into binary format or it is a native binary format taking advantage of all the space optimization.

To sum up, I like the open part only if it is consistent from one file to another. However, it is not always the case due to the .x format block declaration alternatives. This format still needs to mature.

Ghostly yours,
Red.

EDIT: I looked into the COLLADA file format. It does seem cleaner and better organized than microsoft x file format. As to the fact that it only exists in text, you can take microsoft cue (look at the binary x format) and translate the text format into a tokenized binary one.

EDIT 2: Someone mentioned FBX. After a quick search, I stumbled upon Alias website where they are offering a FBX lib to load and save in that file format plus a converter to convert from other file format into that one. They also had a press release the 29th of Sept announcing they would provide a COLLADA converter. I was wondering if after all this a format file and helper classes was still in order ...

Red.

[Edited by - Red Ghost on December 13, 2005 8:27:46 AM]
Ghostly yours,Red.
Trienco
Trienco
Quote:
Original post by Red Ghost
@Trienco:
I understand the need of a format to manage a mesh and I agree with you that OpenGL is very low level for mesh management contrary to D3D. This is why I proposed to add a structure that would link together all the data arrays. This would cover the most basic mesh needs and be consistent with the OpenGL framework:
- a list of vertices
- a list of faces
- a list of materials (texture + color)
- a list of texture coordinates
- a list of lights (material, description and position)

When I read your reaction, I have the feeling you want structure and helper functions like in D3D to cover interactions within a mesh like in most file formats:
- skeletal information
- animation information
- particle emitters description
- scene graph information


The problem is, if you offer a library of loaders for a dozen formats and they don't do more than filling a couple of vertex/index/normal arrays it becomes useless, as everybody will then have to go and still write his own loader to get bone data and animations from the file. The trick would be finding a point where it does enough to be useful, but not so much that it becomes too complex to be useful. Alternatively it handles a lot but is open source so all functions can be changed/removed/added anyway somebody might want (but even for that a certain degree of "completeness" means people not daring to go near it and try to rewrite it).

Without a useful structure to fill a loader is meaningless and without some helper functions making any format the "inofficial OpenGL format" would be the same. That would be like declaring dotxsi the new official D3D format but without offering a library or anything to use it. Once we would have settled on a format, what would we be going to do with/for it?

So, in my eyes, the first step would be to determine how complete such a format complementing library should be. Preferably it would be as compact as possible while still being useful for simple games or prototypes and easy to extend so you won't have to throw it away when doing serious development.

Hmmm, from that point of view I doubt if a format that seems to be meant to hold each and every bit of 3D related information a 3D application could ever think of is the right choice. So I'm back at determining a "core" or subset that is a must for typical use in games. Maybe even a model declaring different stages or shells ranging from completely basic to all out information overkill.
f@dzhttp://festini.device-zero.de
owl
owl
With a little of couriosity from your part you would discover CAL3D. Which happens to be renderer-independent, cross-platform, open-source and has exporters for almost every important modeling application.

Not to mention that it's main purpose is to make skeletal-animation as accesible as the air you breathe.
[size="2"]I like the Walrus best.
rick_appleton
rick_appleton
I heartily agree with Trienco, that not only would we need a file format, but also some universal way of mesh storage. I've been working on my own vertex buffer classes, and have begun to have an inkling of the amount of work that would go into a good buffer class.

A second point is, what will we aim such buffers at. There is potentially a large difference in making them for fixed-function use, or for programmable pipeline use. Would we aim to make something that would fulfill both these requirements, make two separate ones, or only one and drop the other (presumable make one for the programmable pipeline and not for the fixed pipeline)? Because OpenGL is backwards compatible, I would say we at least have support for the fixed function pipeline.

I'll be taking a look at Cal3D this evening.
owl
owl
You won't regret. Just be patient while dismantleing the "cally demo" source code to learn how to use the library. There is no material on the subject, yet.

It could be a great exuse for a tutorial being submitted to gdnet...
[size="2"]I like the Walrus best.
Red Ghost
Red Ghost
Before defining the storage, we should define the exact need for the mesh loader/helper functions library. I have three needs for meshes:
- landscape meshes (textured and lit)
- character model (with skeletal animation)
- navigation meshes (with added custom information)

The third mesh can be considered a subset of the first one (no material, no light). Still it introduces the need for adding custom information.

Do you agree on that perimeter or do you have other propositions ?

I also think we should consider who we are targetting for: beginner, intermediate programmer , seasoned veteran. Or we could consider wether we want to consider the hobbyist programmer, the indie programmer or development teams.

Who is the target ?

CAL3D: I glanced at the system. I must say that I am not in favor of the separation of an object into 4 files (skeleton, animation, mesh and material). I prefer to have one file for one mesh. The file formats are tailored to character models. IMHO I think they do not suit landscape meshes. Besides when looking through the format, I did not see anything about the organization of faces in individual triangles or in strips (perhaps I missed that point).

Ghostly yours,
Red.
Ghostly yours,Red.
Trienco
Trienco
Quote:
Original post by rick_appleton
A second point is, what will we aim such buffers at. There is potentially a large difference in making them for fixed-function use, or for programmable pipeline use. Would we aim to make something that would fulfill both these requirements, make two separate ones, or only one and drop the other (presumable make one for the programmable pipeline and not for the fixed pipeline)? Because OpenGL is backwards compatible, I would say we at least have support for the fixed function pipeline.


Don't look at me, unifying arrays and buffer objects was about as far as I went (which is hardly an achievement, seeing how they are pretty much the same). But even with that I would start wondering about a ton of implementation details. Waste space on an internal copy for easy manipulation (and avoiding mapping the buffer)? Only doing it for static use? Completely leave that part to the user?

Though managing the collection of buffers in a "know what to bind where and when for rendering"-way would be interesting, especially when mixing generic attributes with established "aliases" like vertex or normal. For my file format that was easy by simply determining that the order (for generic attributes) must reflect the number of the attribute. Supporting multiple passes would also add a new layer (as in node/chunk/tag) to collect tex coords/textures/material settings/shaders in. So far I lived by the attitude "if I can't do it in one pass I'm not interested in it" *cough*
f@dzhttp://festini.device-zero.de
Trienco
Trienco
Quote:
Original post by Red Ghost
Before defining the storage, we should define the exact need for the mesh loader/helper functions library. I have three needs for meshes:
- landscape meshes (textured and lit)
- character model (with skeletal animation)
- navigation meshes (with added custom information)


I would leave out #1 and #3. Terrain is probably coming from height maps over 90% of the time and is radically different from regular models to justify it's own class. Nav meshes are very different as well and probably only used for maps and level data. And more something I would put into OpenAI. A low res collision/shadow mesh might be useful, though one half should be physics and the other is for stencil shadows that I don't really like as a technique. Me? Imposing my preferences? Nah *fg*

Quote:
CAL3D: I glanced at the system. I must say that I am not in favor of the separation of an object into 4 files (skeleton, animation, mesh and material). I prefer to have one file for one mesh.


Ah, but that would mean a whole ton of redundant data. Lots of humanoid models can use the same skeleton, but have different animations and so on. Just like many different models can share the same material library. Loading that for each model would just make loading times more annoying.

Shameless plug: my suggested format allows animations, skeletons, meshes, etc. to be either included in the same file or referenced from other files. If something is shared alot the skeleton and animations could be in a seperate file and if they aren't would all be in the same file as the mesh.

Quote:
The file formats are tailored to character models. IMHO I think they do not suit landscape meshes.


Because: who is using meshes for terrain? Maybe more than I think, but the needs and requirements that justify it suggest an advanced level of use where someone will need his own custom terrain class anyway.

Repeating myself, as I already mentioned my preference of a pure model format. Terrain or level data should be an entirely different beast, as they have nothing in common with your every day models.
f@dzhttp://festini.device-zero.de
Red Ghost
Red Ghost
@Trienco:
It looks like you are not looking for a mesh file loader but for a character model loader. It is a specialization of meshes. Since this is what you are willing, what is to your mind the target audience ?

Regarding the difference between one or many files, I think there is not much debate. If you share the same skeleton between many models it is just a matter of exporting or not the skeleton. You could have a basic file with only the character and animation keys and many model files with only the skin and links between the skin and the skeleton. the X file format allows that. However I don't know if modeling programs allow the selection of blocks to export (meaning export only the skin or export only the skeleton).
Concerning your argument on loading time, I do not think the loading time is much deprecated: if you don't want to reload the skeleton block, set up your loader to ignore it. It won't be as fast as having separate files but the time deprecation will still be very low.
In the end I believe it is just a matter of personal taste. My own is towards a simple system where I am sure I do not forget a file when packing my resources together.

Concerning terrain, I think there is a difference between terrain representation and terrain analysis for movement. Having a global mesh structure used to represent terrain or character models does not deter anybody to adapt it to his own needs. I am interested to hear about what others think about it.

Ghostly yours,
Red.
Ghostly yours,Red.
rick_appleton
rick_appleton
I'm with Red Ghost on the non-character meshes. Also, you seem to be focussing on animated character meshes, but many games have a lot of set pieces: static meshes. Obviously this would need to be supported. And what is a terrain other than a static mesh? Obviously the mesh for a terrain is often generated from a heightmap, but after that you'll have to store it somewhere. Which is where the buffers would come in.

I don't really care either way if animations and meshes are stored separately or in a single file. I would lean towards separate files, but if the format is right, there's nothing from keeping you from loading only the animation, or only the mesh.

Another thing that nobody has mentioned is the need for keyframed vertex animation. Not all games use skeletal animation.

Also, I guess we would also need helper functions to actually do the animation?

And a last point for now, to keep the library 'compatible' with OpenGL, it would have to have a C interface. For me this is very unfortunate, since I love using the STL. Although possibly we could use C++ inside the lib itself.
owl
owl
Quote:
Original post by Red Ghost
I did not see anything about the organization of faces in individual triangles or in strips (perhaps I missed that point).


Yeap, take a look a little closer. The vertices are defined and following that you have the triangles defined with indices to the vertices. Exactly the data you need to pass to stripifier app, for example.

Having 4 separated files is not important. Since merging them togheter is teh simplest thing. Besides, CAL3D has functions to load those files from a memory buffer, which is pretty convinient if you're planning to store them in a resource/encrypted file.

The most amazing thing about CAL3D is the way you can blend the animations. The transitions between them are teh smooth.
[size="2"]I like the Walrus best.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.