Load a Wavefront OBJ file (*.obj).
Loads vertex, normals, and texture coordinates from the provided *.obj file into arrays. These arrays can be processed then loaded into vertex buffer objects (VBOs) for rendering. The *.obj file must at least specify vertex position data to be loaded successfully. Normals and texture coordinates are optional.
Faces can be either triangles or quads, but not both. Faces are grouped by their materials. Index arrays are generated for each material present in the file.
Data from the returned ObjMeshInfo object can be used to create vertex buffer objects and arrays for rendering. See Examples below for details on how to do this.
objFile (str
) – Path to the *.OBJ file to load.
Mesh data.
See also
loadMtlFile
Load a *.mtl file.
Notes
This importer should work fine for most sanely generated files. Export your model with Blender for best results, even if you used some other package to create it.
The mesh cannot contain both triangles and quads.
Examples
Loading a *.obj mode from file:
objModel = loadObjFile('/path/to/file.obj')
# load the material (*.mtl) file, textures are also loaded
mtllib = loadMtl('/path/to/' + objModel.mtlFile)
Creating separate vertex buffer objects (VBOs) for each vertex attribute:
vertexPosVBO = createVBO(objModel.vertexPos)
texCoordVBO = createVBO(objModel.texCoords)
normalsVBO = createVBO(objModel.normals)
Create vertex array objects (VAOs) to draw the mesh. We create VAOs for each face material:
objVAOs = {} # dictionary for VAOs
# for each material create a VAO
# keys are material names, values are index buffers
for material, faces in objModel.faces.items():
# convert index buffer to VAO
indexBuffer = gltools.createVBO(
faces.flatten(), # flatten face index for element array
target=GL.GL_ELEMENT_ARRAY_BUFFER,
dataType=GL.GL_UNSIGNED_INT)
# see `setVertexAttribPointer` for more information about attribute
# pointer indices
objVAOs[material] = gltools.createVAO(
{0: vertexPosVBO, # 0 = gl_Vertex
8: texCoordVBO, # 8 = gl_MultiTexCoord0
2: normalsVBO}, # 2 = gl_Normal
indexBuffer=indexBuffer)
# if using legacy attribute pointers, do this instead ...
# objVAOs[key] = createVAO({GL_VERTEX_ARRAY: vertexPosVBO,
# GL_TEXTURE_COORD_ARRAY: texCoordVBO,
# GL_NORMAL_ARRAY: normalsVBO},
# indexBuffer=indexBuffer,
# legacy=True) # this needs to be `True`
To render the VAOs using objVAOs created above, do the following:
for material, vao in objVAOs.items():
useMaterial(mtllib[material])
drawVAO(vao)
useMaterial(None) # disable materials when done
Optionally, you can create a single-storage, interleaved VBO by using numpy.hstack. On some GL implementations, using single-storage buffers offers better performance:
interleavedData = numpy.hstack(
(objModel.vertexPos, objModel.texCoords, objModel.normals))
vertexData = createVBO(interleavedData)
Creating VAOs with interleaved, single-storage buffers require specifying additional information, such as size and offset:
objVAOs = {}
for key, val in objModel.faces.items():
indexBuffer = gltools.createVBO(
faces.flatten(),
target=GL.GL_ELEMENT_ARRAY_BUFFER,
dataType=GL.GL_UNSIGNED_INT)
objVAOs[key] = createVAO({0: (vertexData, 3, 0), # size=3, offset=0
8: (vertexData, 2, 3), # size=2, offset=3
2: (vertexData, 3, 5), # size=3, offset=5
indexBuffer=val)
Drawing VAOs with interleaved buffers is exactly the same as shown before with separate buffers.