Ingemar’s Little OBJ Loader

Little OBJ Loader is a very small loader of OBJ files. It can load as well as render most OBJ models. It supports loading of .mtl files as well as multi-part OBJ models. This page holds multiple demos to show how to use it.

It has only one external dependency: My VectorUtils3/4 vector utilities, mainly for the vec3 type. It should be easy to adapt to other math libraries.

History and motivation

LittleOBJLoader is a major revision of our old OBJ loaded, LoadOBJ/loadobj. In 2005, I wrote the first version of a unit called LoadOBJ, to load OBJ models. It was very small, a 10k file that loaded OBJ in a rather clumsy way to a straight memory version of the same data.

A few years later, Mikael Kalms extended it significantly, with a linearizer to make it fit into modern the OpenGL model. This I think was when the capitalization was changed to loadobj. (Now it was 22k.) Jens Ogniewski made some more additions, and so did I. Now this little loader was 37k. However, it was not very capable and also not very readable. It failed on some files, and it did not support .mtl files for material definitions nor the multi-part splitting that is needed to handle them.

So, should I improve it or just switch to something better? Assimp? Too big for course material! The “tinyobjloader” sounds pretty right and it sure can do more than loadobj could. “Tiny” means a 70k file. But… it doesn’t quite do all I wanted, so I found myself sending the data it loads to loadobj!

In 2019, I decided to make the much needed overhaul of loadobj. The duck below (source unknown, I thought it was from TurboSquid but I can’t find it) was my primary target, as a file that loadobj had a lot of problems with. The model is not textured, all colors are from a .mtl file specifying colors for each part; body, beak and eyes.

Skärmavbild 2019-11-06 kl. 21.35.26

This did take some work. I had already written the code to load a model split to several parts, but that code was buggy, and there were plenty of possible pitfalls in the OBJ format that I needed to address. Thus, this overhaul became pretty big! Not only did I find several weaknesses (now making it possible to load models with other problems than the duck) and added a .mtl parser, I also rewrote large parts, taking advantage of VectorUtils3 to simplify the OBJ loader and making it easier to understand.

The new version, including MTL support, is now renamed to LittleOBJLoader, LOL for short :). And it is down to a honorable 33k! (A bit bigger if you include vital parts of VectorUtils in order to make it stand-alone, quite a bit smaller if you cut comments.) This should be compared to 70k for tinyobjloader and 52k for the experimental “opt” version! With all respect to TOL, I hope LOL will be a useful OBJ loader in its own way.

The image above is rendered with LOL using its parsed material data for coloring each part separately. I have tested with a fairly extensive set of models, and most render correctly, including popular models like the dragon, Buddha, Sponza and the Sibenik Cathedral!

Important design choice: The loader splits over usemtl statements only. (There are a few other statements like “g” but I ignore those.) LoadModelSet will return a NULL-terminated array of Model structs, each containing a pointer to a material struct if that information was available. This means that drawing the array requires a for loop, in which you are expected to take whatever action appropriate to apply materials to shader variables.

Another design choice is that it is now dependent of VectorUtils, which makes much code more brief and easy to read. However, the dependencies are minor, so if you wish to adapt to another vector library, there are not that many changes to make as long as the library you use can speak C. You can also copy the few calls you need over to make the whole thing stand-alone.

The mteapot demo

How about a multi-part Utah Teapot? And being able to lift the lid procedurally? :) (This was done by adding a few usemtl lines in the teapot OBJ.) (2021: Now available as demo below!)

During the path getting here, I saved some pictures of memorable buggy versions:

Frustrating intermediate results.

Downloads and demos

At this time, my demos ready for release are only using the kD part of the .mat files. I hope to provide a demo with textures at some time.

Download (First release 2019)

After this first release, I have updated LOL so it can load even more models. It is now found in the “common” files.

Download (LittleObjLoader february 2021)

March 2022: New version of LittleOBJLoader, not yet in the common package.

The teapot demo above is available here:

Download mteapot demo

In 2021, I have made another demo, “Tinkercar”, based on a model I made in TinkerCAD. The good part is that TinkerCAD can output files with material colors for each part! The not so good part is that it doesn’t generate normal vectors, which is why they will be not so good for model parts with sharp corners.

Skärmavbild 2021-02-25 kl. 08.50.53

The Tinkercar demo, with each part colorized using the material file

The demo includes some functions and teaser information for playing around with the demo, like turning wheels and opening the doors. Can you do this? See below.

Skärmavbild 2021-02-25 kl. 08.51.30

Tinkercar with rotating and spinning wheels plus doors opening and closing.

Updated 2021-02-25 with modifications that make the area around the wheels look better.

Download tinkercar demo

This page is maintained by Ingemar Ragnemalm.