# Creating a custom binary format for 3D meshes

I've seen people saying it's better and faster to use a custom binary format for your 3D models, based on your needs, instead of using exchange formats. But, I'd like to know how to create a basic format, that contains just vertex and index data, how to write this data into a binary file and read it. Much obliged.

What you ultimately end up using at runtime is going to be processed version of your exchange formats whether you do it offline or at runtime. The main differences are:

1. If you do it at runtime then you're going to end up paying the processing cost repeatedly and
2. You probably want to spend as little time processing and optimizing as possible so your load times are reasonable

I'm not sure what your use case is but I assume you'll be putting the data into either a D3D or OpenGL set of index/vertex buffers. It sounds like you're already familiar with what an index/vertex buffer is, so I think the part you might be missing is what D3D calls the vertex declaration.

OpenGL does the same thing but I find it less well defined conceptually. You'll want to take a look at the OpenGL wiki for Vertex Specification paying particular attention to glVertexAttribPointer.

Anyway, the vertex declaration specifies in the type of each component and where it occurs in a vertex. For example, a vertex declaration could look something like:

• [Offset 0] - Position - 3 32-bit floats (xyz)
• [Offset 12] - Texture Coords - 2 32-bit floats (uv)
• [Offset 20] - Colour - 1 normalized packed ARGB value (or RGBA, or BGRA, or... depends on the system)

Given this vertex declaration, you would then proceed to write out your vertex buffer using this description. I generally tend to just match it with a straight C structure:

struct MyVertex
{
Vector3F Position;
Vector2F UV;
int32_t mColour;
};


Create an array for all the vertices, populate them as appropriate and dump that and the vertex description to a file.

On the runtime side, you'll then load your data into memory, and then make the appropriate calls to D3D/OpenGL to say "my vertex format is this" and construct your vertex buffer by passing a pointer to your data array.

Index buffers are basically identical except you just specify the size of each index (8 bit, 16 bit, etc.).

It gets slightly more complicated if you want to have different vertex buffers supplying different streams of data, but I hope that's good enough to help you understand the general idea.

• Are there any formats that store data like this? – Panda Pajama Jan 27 '13 at 5:21
• Not sure what you mean Panda. A vertex declaration is the specification of a format. If you mean are there libraries that do the dirty work, basically any rendering engine will do this. For example, Ogre has a mesh preprocessor that outputs to an Ogre mesh format. – Julian Jan 27 '13 at 7:08
• Sure, I've used several engines that do this for you, and you can certainly use the FBX SDK to read FBX files and convert them to whatever you want, or read the XML in Collada to do the same thing. However, I don't completely understand why this additional conversion step is unavoidable. Most of the time your vertex format will fall into a set of few common formats, and having a standard file format that you can directly blit into memory as a vertex buffer could be useful. This is of course only relevant when you're not using a full game engine. – Panda Pajama Jan 27 '13 at 7:13

I've implemented such offline format near month ago for my engine. The basic algorithm is:

1. Write formal specification for output binary file in word processor. Header + data blocks. Data types, offsets, descriptions of each element of each block table.
2. Write offline exporter from your 3D editor into C++ code text headers using embedded scripting language. Then coding this try to export everything there. verts xyz, color verts, all UVw texture channels, indicies, faces, edges, face normals, vertex normals, binormals, tangents, materials, objects names, quaternions and matricies for each keyframe, bone weights, bone lists, animation metadata(fps, frame quatity) e.t.c.

3. Include headers with data to C++ offline converter project using a pre-build script. Run project and compile headers text data files to binary. Use specification from step 1 to code converter correctly. Here you should care about attributes data types. i.e. you can store vertex XYZ as float, short or just char. It's important to add support to each reasonable data type here and at step 5.