This program turns your 3D models into C header files! You can use them as-is and write your own loader, or also use the header-only loader compatible with OpenGL and OpenGL ES. Texture data is not written to the headers; only mesh data. Texture file names, however, are provided in the material information.
The generator part is written using C++17.
Assimp is the only mandatory dependency. It is needed for the header generator.
To build the project using the Meson build system, run the following commands:
meson build
ninja -C build
The resulting executable is build/modelheader
.
modelheader model_file
This writes the output header to stdout, which you can then forward to where you want it. Example:
modelheader model_file > my_model.h
By default, all primitives are pre-transformed by their transform matrices. If
you don't want this, use the -p
flag. If node, mesh & material info is
unneeded, -m
can be used to discard them. If some vertex attributes aren't
needed, they can be discarded using -dnt
, where n
removes normals and t
texture coordinates. If you want a different prefix than the one automatically
deduced from the file name, use -n my_name_prefix
.
Extensive example, where vertices aren't pre-transformed, prefix is changed to "spaceship" and normals are discarded:
modelheader -p -n spaceship -dn apollo11.obj > spaceship.h
If you wish to use the generated header manually, here's an example:
#include "my_model.h"
/* In this example, the model data is now readable in the following variables.
*
* float my_model_vertices[my_model_vertex_stride*my_model_vertex_count];
* unsigned my_model_indices[my_model_index_count];
* struct modelheader_material my_model_materials[my_model_material_count];
* struct modelheader_mesh my_model_meshes[my_model_mesh_count];
* struct modelheader_node my_model_nodes[my_model_node_count];
*
* Offsets of the vertex attributes inside a vertex are available as follows:
*
* my_model_position_offset
* my_model_normal_offset
* my_model_uv0_offset
*
* See the generated header for the definitions of modelheader_material,
* modelheader_mesh and modelheader_node. Note that those are unneeded for
* simple untextured models, and do not exist at all if `-m` was defined
* when generating the header.
*/
In any case, never include generated model headers from a header in your
project! This causes unnecessary duplication of data (every variable is marked
as static in model headers), and pollutes your namespace with modelheader_*
things along with prefixed model data. Always include the model headers from a
.c file directly.
The loader library is written using C99 inline functions. It is entirely
contained in modelheader_gl.h
.
The only dependency is whichever OpenGL version you wish to use, as long as it's newer than OpenGL 2.1 (VBOs are used at minimum).
Include the OpenGL headers you need before including modelheader_gl.h
. This
is because the header attempts to stay as portable as possible.
Vertex array objects are generated by default. This requires OpenGL 3.0 or
newer. If you wish to use older versions, define MODELHEADER_DISABLE_VAO
before including the header.
Example:
// Include your OpenGL headers. If you use GLEW, this is how you do it.
#include <GL/glew.h>
// Uncomment the below line if you are using older than OpenGL 3.0
// #define MODELHEADER_DISABLE_VAO
#include "modelheader_gl.h"
// You can also include your model before modelheader_gl.h, it doesn't matter.
#include "my_model.h"
...
/* VBO - Vertex Buffer Object
* IBO - Index Buffer Object
* VAO - Vertex Attribute Object
*/
GLuint my_vbo, my_ibo, my_vao;
// Define the attribute locations used in your shader
GLuint locations[] = {
MODELHEADER_POS, 0,
MODELHEADER_NORMAL, 1,
MODELHEADER_UV0, 2,
0 // Or MODELHEADER_ATTRIB_END, whichever you deem more readable.
};
// To load the model with VAOs enabled: (note lack of quotes around my_model)
modelheader_gl_load_vao(my_model, &my_vbo, &my_ibo, &my_vao, locations);
/* You can also leave the locations array as NULL. Then the locations will be
* as follows:
*
* Position - 0
* Normals - 1
* UV0 - 2
*/
// To load the model without a VAO:
modelheader_gl_load(my_model, &my_vbo, &my_ibo);
// To set vertex attribs without a VAO: (locations can be NULL here, see above)
modelheader_gl_set_vertex_attribs(my_model, locations);
/* Similar to manual handling, additional information is found through
* my_model_nodes, my_model_materials and my_model_meshes. This information is
* only useful if the original model file contained materials or multiple
* objects. They won't exist if the flag `-m` was given when generating the
* header.
*/