Tuesday, December 5, 2017

Simple Wavefront .OBJ Model Loader in JOGL

Wavefront .OBJ files are the most simplest of models that can be loaded into OpenGL. I have loaded some simple files and it has worked well. Im still working on other files containing negative vertex indexes.

This is an image of an elephant and a college visualized in a model mentioned in this site=> http://netization.blogspot.in/2014/10/loading-obj-files-in-opengl.html

On request I have texture mapped a custom texture to the elephant body(Chess board pattern)





If you are interested in the .OBJ model file format it is a simple text based model. It does not use any compression in storing the vertices or their relations. Hence this file format is human readable to some extent and editable to a fair degree of control. I am reproducing some text describing the format from an E-Book by David J Eck(without permission of course).
Wavefront .OBJ file format:
For complex shapes that are not described by any simple mathematical formula, it’s not feasible to generate the shape using Java code. We need a way to import shape data into our programs from other sources. The data might be generated by physical measurement, for example, or by an interactive 3D modeling program such as Blender (http://www.blender.org). To make this possible, one program must write data in a format that can be read by another program. The two programs need to use the same graphics file format. One of the most common file formats for the exchange of polygonal mesh data is the Wavefront OBJ file format. Although the official file format can store other types of geometric data, such as Bezier curves, it is mostly used for polygons, and that’s the only use that we will consider here.
An OBJ file (with file extension “.obj”) can store the data for an indexed face set, plus normal vectors and texture coordinates for each vertex. The data is stored as plain, human-readable text, using a simple format. Lines that begin with “v”, “vn”, “vt”, or “f”, followed by a space, contain data for one vertex, one normal vector, one set of texture coordinates, or one face, respectively. For our purposes here, other lines can be ignored. A line that specifies a vertex has the form
v x y z
where x, y, and z are numeric constants giving the coordinates of the vertex. For example:
v 0.707 -0.707 1
Four numbers, specifying homogeneous coordinates, are also legal but, I believe, rarely used. All the “v” lines in the file are considered to be part of one big list of vertices, and the vertices are assigned indices based on their position in the list. The indices start at one not zero, so vertex 1 is the vertex specified by the first “v” line in the file, vertex 2 is specified by the second “v” line, and so on. Note that there can be other types of lines interspersed among the “v” lines—those extra lines are not counted when computing the index of a vertex.
Lines starting with “vn” or “vt” work very similarly. Each “vn” line specifies a normal vector, given by three numbers. Normal vectors are not required to be unit vectors. All the “vn” lines in the file are considered to be part of one list of normal vectors, and normal vectors are assigned indices based on their order in the list. A “vt” line defines texture coordinates with one, two, or three numbers. (Two numbers would be used for 2D image textures.) All the “vt” lines in the file create a list of texture coordinates, which can be referenced by their indices in the list.
Faces are more complicated. Each “f” line defines one face, that is, one polygon. The data on the “f” line must give the list of vertices for the face. The data can also assign a normal vector and texture coordinates to each vertex. Vertices, texture coordinates, and normals are referred to by giving their indices in the respective lists. (Remember that the numbering starts from one, not from zero; if you’ve stored the data in Java arrays, you have to subtract 1 from the numbers given in the “f” line to get the correct array indices. There reference numbers can be negative. A negative index in an “f” line means to count backwards from the position of the “f” line in the file. For example, a vertex index of −1 refers to the “v” line that was seen most recently in the file, before encountering the “f” line; a vertex index of −2 refers the “v” line that precedes that one, an so on. If you are reading the file sequentially and storing data in arrays as you go, then −1 simply refers to the last item that is currently in the array, −2 refers to the next-to-last item, and so on.)
In the simple case, where there are no normals or texture coordinates, an “f” line can simply list the vertex indices in order. For example, an OBJ file for the pyramid example from the previous subsection could look like this:
v 1 0 1
v 1 0 -1
v -1 0 -1
v -1 0 1
v 0 1 0
f 5 4 1
f 5 1 2
f 5 2 3
f 5 3 4
f 1 4 3 2
When texture coordinate or normal data is included, a single vertex index such as “5” is replaced by a data element in the format v/t /n, where v is a vertex index, t is a texture coordinates index, and n is a normal coordinate index. The texture coordinates index can be left out, but the two slash characters must still be there. For example, “5/3/7” specifies vertex number 5, with texture coordinates number 3, and normal vector number 7. And “2//1” specifies vertex 2 with normal vector 7. As an example, here is complete OBJ file representing a cube, with its normal vectors, exactly as exported from Blender. Note that it contains additional data lines, which we want to ignore:
# Blender3D v248 OBJ File:
# www.blender3d.org
mtllib stage.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vn -0.000000 -1.000000 0.000000
vn 0.000000 1.000000 -0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material
s off
f 1//1 2//1 3//1 4//1
f 5//2 8//2 7//2 6//2
f 1//3 5//3 6//3 2//3
f 2//4 6//4 7//4 3//4
f 3//5 7//5 8//5 4//5
f 5//6 1//6 4//6 8//6

Once you have read a geometric object from an OBJ file and stored the data in arrays, it is easy enough to use the arrays to draw the object with OpenGL.

Monday, December 4, 2017

Object Model Loader in OpenGL

The example provided here at this site was the most simplest of all loaders that I could find on the Internet. I am now trying to load Wavefront .obj files created in Blender in C++ OpenGL.

Here are the snaps of the few objects loaded...
In reverse order
Elephant
College
Porsche
Radar
Teddy


You can download the source and obj files from the site mentioned.
Things that you can do with these files is you can group vertices into faces and faces into components which you can transform and animate in 3D. For example you can load the model created in Blender exported as OBJ file into OpenGL and then display them the way you want.

I have implemented some of the tasks mentioned above a post in this next post: >>>>>> Click Here <<<<<< to visit.