rlk / obj

Wavefront OBJ library in C with an OpenGL Core Profile renderer
MIT License
94 stars 19 forks source link

obj

obj loads, manipulates, optimizes, renders, and stores 3D geometry using the Wavefront OBJ file format. The renderer uses the OpenGL 3.2 Core Profile, making it compatible with OpenGL versions 3 and 4, OpenGL ES 2.0, and also commonly-available extended implementations of OpenGL 2.1.

An OBJ file consists of sets of materials, vertices, and surfaces. A surface consists of sets of polygons and lines with a reference to a material to be used when rendering them. A polygon is a triplet of references to vertices in the file, and a line is a pair of references to vertices.

OBJ files are referenced using pointers to type obj. The elements within the OBJ are referenced by integer index. These indices work much like a file or socket descriptor. The internal geometry representation is not accessible to the application. All operations on geometry are performed using the API documented here.

Compilation

To use this module, simply link it with your own code. The renderer requires OpenGL. Linux and Windows compilation also requires GLEW...

cc -o program program.c obj.c -lGLEW -lGL -lm

Though OSX's native OpenGL support suffices...

cc -o program program.c obj.c -framework OpenGL -lm

If used only to process OBJ files and not to render them, the OpenGL dependency may be eliminated by defining CONF_NO_GL.

cc -o program program.c obj.c -DCONF_NO_GL -lm

Quickstart

These code fragments implement the common case of loading and displaying a model stored in an OBJ file. First, an OBJ pointer is declared.

obj *O;

During initialization, an obj structure is allocated, the OBJ file and all of its MTL files and texture images are read, and the obj pointer is returned.

O = obj_create("teapot.obj");

During rendering:

obj_render(O);

When no longer needed, all resources held by the obj data structure are released:

obj_delete(O);

The OBJ API

Top level

As we've just seen, the top level API for manipulation OBJ files is as follows:

Rendering

Element Creation

Element Counters

Element deletion

Note: The element deletion API goes to great lengths to ensure that all geometry blocks are free of gaps, and that all internal references are consistent. If an application removes an element from the middle of a block then all higher-index elements are shifted down, and any references to these elements are decremented. Be aware: if an application caches element indices elsewhere, then these indices may be invalidated by a deletion operation.

Entity Manipulators

The opt argument gives a bitmap of options to be enabled. The following options are defined. Yeah, there's only one right now.

OBJ_OPT_CLAMPClamp the property map. Default is to repeat.

Entity Query

OBJ I/O

Processing

Proper selection of qc is crucial. Overestimating the cache size will result in bad performance. It is safe to assume a cache size of 16. Recent video hardware provides cache sizes up to 32. Average-case analysis indicates that future video hardware is unlikely to increase cache size far beyond 32.

Optimal sorting is NP-complete. This implementation is fast (linear in the number of triangles) but not optimal. There is no guarantee that a sorted model will have a lower ACMR than the original unsorted model. Paranoid applications should confirm that sorting reduces the ACMR and reload the model if it does not.

Exporting

Note: if geometry is read from one file and written to another then there is no guarantee that the source and destination files are identical. Shared normals and texture coordinates are duplicated per vertex. The number of position, normal, and texture coordinate specifications equal the number of vertices in the file.

All face specifications are of the form "f i/i/i j/j/j k/k/k" for some vertex indices i, j, k. All line specifications are of the form "l i/i j/j" for some vertex indices i, j. All vertex indices are positive, counting from the beginning of the file.

Any groups specified in the source OBJ are discarded, and the output OBJ is organized by material. Unused specifications in OBJ and MTL files (curves, merging groups, etc) are omitted. Smoothing groups are omitted, and the smoothed normals for each vertex are inserted instead. All comments are stripped.