《基于MFC的OpenGL编程》Part 18 Reading objects from the OBJ File Format


本文将介绍如何从Obj文件格式中创建3D对象,我们使用的是Nate Miller的obj格式加载类。

This would be very useful to create large Virtual Reality applications as we could make use of the readily available 3D model files or make use of modeling tools to create these models and load them instead of creating them programatically. The .obj format is a very simple and popular format and files of other types such 3D Studio (.3ds) can be exported to this format or converted using tools such as 3D Exploration. This .obj loading code cannot read textures, it can only also read .mtl files in addition to the .obj file and thus make use of material data too.

1, Nate Miller的obj文件加载类,其完整源代码可以从http://www.pobox.com/~ndr处下载。

Glm头文件

/*
* Wavefront .obj file format reader.
*
* author: Nate Robins
* email: ndr@pobox.com
* www: http://www.pobox.com/~ndr
*/
/* includes */
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif
/* defines */
#define GLM_NONE   (0)    /* render with only vertices */
#define GLM_FLAT   (1 << 0)    /* render with facet normals */
#define GLM_SMOOTH  (1 << 1)    /* render with vertex normals */
#define GLM_TEXTURE (1 << 2)    /* render with texture coords */
#define GLM_COLOR  (1 << 3)    /* render with colors */
#define GLM_MATERIAL (1 << 4)    /* render with materials */
/* structs */

/* GLMmaterial: Structure that defines a material in a model.
*/
typedef struct _GLMmaterial
{
 char* name;        /* name of material */
 GLfloat diffuse[4];      /* diffuse component */
 GLfloat ambient[4];      /* ambient component */
 GLfloat specular[4];      /* specular component */
 GLfloat emmissive[4];      /* emmissive component */
 GLfloat shininess;      /* specular exponent */
} GLMmaterial;

/* GLMtriangle: Structure that defines a triangle in a model.
*/
typedef struct {
 GLuint vindices[3];      /* array of triangle vertex indices */
 GLuint nindices[3];      /* array of triangle normal indices */
 GLuint tindices[3];      /* array of triangle texcoord indices*/
 GLuint findex;      /* index of triangle facet normal */
} GLMtriangle;

/* GLMgroup: Structure that defines a group in a model.
*/
typedef struct _GLMgroup {
 char*       name;    /* name of this group */
 GLuint      numtriangles;  /* number of triangles in this group */
 GLuint*      triangles;    /* array of triangle indices */
 GLuint      material;      /* index to material for group */
 struct _GLMgroup* next;    /* pointer to next group in model */
} GLMgroup;

/* GLMmodel: Structure that defines a model.
*/
typedef struct {
 char*  pathname;      /* path to this model */
 char*  mtllibname;      /* name of the material library */
 GLuint  numvertices;      /* number of vertices in model */
 GLfloat* vertices;      /* array of vertices */
 GLuint  numnormals;      /* number of normals in model */
 GLfloat* normals;      /* array of normals */
 GLuint  numtexcoords;    /* number of texcoords in model */
 GLfloat* texcoords;      /* array of texture coordinates */
 GLuint  numfacetnorms;    /* number of facetnorms in model */
 GLfloat* facetnorms;      /* array of facetnorms */
 GLuint    numtriangles;    /* number of triangles in model */
 GLMtriangle* triangles;    /* array of triangles */
 GLuint    nummaterials;    /* number of materials in model */
 GLMmaterial* materials;    /* array of materials */
 GLuint    numgroups;    /* number of groups in model */
 GLMgroup*  groups;      /* linked list of groups */
 GLfloat position[3];      /* position of the model */
} GLMmodel;

/* public functions */

/* glmUnitize: "unitize" a model by translating it to the origin and
* scaling it to fit in a unit cube around the origin. Returns the
* scalefactor used.
*
* model - properly initialized GLMmodel structure
*/
GLfloat
glmUnitize(GLMmodel* model);

/* glmDimensions: Calculates the dimensions (width, height, depth) of
* a model.
*
* model   - initialized GLMmodel structure
* dimensions - array of 3 GLfloats (GLfloat dimensions[3])
*/
GLvoid
glmDimensions(GLMmodel* model, GLfloat* dimensions);

/* glmScale: Scales a model by a given amount.
*
* model - properly initialized GLMmodel structure
* scale - scalefactor (0.5 = half as large, 2.0 = twice as large)
*/
GLvoid
glmScale(GLMmodel* model, GLfloat scale);

/* glmReverseWinding: Reverse the polygon winding for all polygons in
* this model. Default winding is counter-clockwise. Also changes
* the direction of the normals.
*
* model - properly initialized GLMmodel structure
*/
GLvoid
glmReverseWinding(GLMmodel* model);

/* glmFacetNormals: Generates facet normals for a model (by taking the
* cross product of the two vectors derived from the sides of each
* triangle). Assumes a counter-clockwise winding.
*
* model - initialized GLMmodel structure
*/
GLvoid
glmFacetNormals(GLMmodel* model);

/* glmVertexNormals: Generates smooth vertex normals for a model.
* First builds a list of all the triangles each vertex is in. Then
* loops through each vertex in the the list averaging all the facet
* normals of the triangles each vertex is in. Finally, sets the
* normal index in the triangle for the vertex to the generated smooth
* normal. If the dot product of a facet normal and the facet normal
* associated with the first triangle in the list of triangles the
* current vertex is in is greater than the cosine of the angle
* parameter to the function, that facet normal is not added into the
* average normal calculation and the corresponding vertex is given
* the facet normal. This tends to preserve hard edges. The angle to
* use depends on the model, but 90 degrees is usually a good start.
*
* model - initialized GLMmodel structure
* angle - maximum angle (in degrees) to smooth across
*/
GLvoid
glmVertexNormals(GLMmodel* model, GLfloat angle);

/* glmLinearTexture: Generates texture coordinates according to a
* linear projection of the texture map. It generates these by
* linearly mapping the vertices onto a square.
*
* model - pointer to initialized GLMmodel structure
*/
GLvoid
glmLinearTexture(GLMmodel* model);

/* glmSpheremapTexture: Generates texture coordinates according to a
* spherical projection of the texture map. Sometimes referred to as
* spheremap, or reflection map texture coordinates. It generates
* these by using the normal to calculate where that vertex would map
* onto a sphere. Since it is impossible to map something flat
* perfectly onto something spherical, there is distortion at the
* poles. This particular implementation causes the poles along the X
* axis to be distorted.
*
* model - pointer to initialized GLMmodel structure
*/
GLvoid
glmSpheremapTexture(GLMmodel* model);

/* glmDelete: Deletes a GLMmodel structure.
*
* model - initialized GLMmodel structure
*/
GLvoid
glmDelete(GLMmodel* model);

/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file.
* Returns a pointer to the created object which should be free'd with
* glmDelete().
*
* filename - name of the file containing the Wavefront .OBJ format data.
*/
GLMmodel*
glmReadOBJ(char* filename);

/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to
* a file.
*
* model  - initialized GLMmodel structure
* filename - name of the file to write the Wavefront .OBJ format data to
* mode   - a bitwise or of values describing what is written to the file
*      GLM_NONE  - write only vertices
*      GLM_FLAT  - write facet normals
*      GLM_SMOOTH - write vertex normals
*      GLM_TEXTURE - write texture coords
*      GLM_FLAT and GLM_SMOOTH should not both be specified.
*/
GLvoid
glmWriteOBJ(GLMmodel* model, char* filename, GLuint mode);

/* glmDraw: Renders the model to the current OpenGL context using the
* mode specified.
*
* model  - initialized GLMmodel structure
* mode   - a bitwise OR of values describing what is to be rendered.
*      GLM_NONE  - render with only vertices
*      GLM_FLAT  - render with facet normals
*      GLM_SMOOTH - render with vertex normals
*      GLM_TEXTURE - render with texture coords
*      GLM_FLAT and GLM_SMOOTH should not both be specified.
*/
GLvoid
glmDraw(GLMmodel* model, GLuint mode);

/* glmList: Generates and returns a display list for the model using
* the mode specified.
*
* model  - initialized GLMmodel structure
* mode   - a bitwise OR of values describing what is to be rendered.
*      GLM_NONE  - render with only vertices
*      GLM_FLAT  - render with facet normals
*      GLM_SMOOTH - render with vertex normals
*      GLM_TEXTURE - render with texture coords
*      GLM_FLAT and GLM_SMOOTH should not both be specified.
*/
GLuint
glmList(GLMmodel* model, GLuint mode);

/* glmWeld: eliminate (weld) vectors that are within an epsilon of
* each other.
*
* model   - initialized GLMmodel structure
* epsilon  - maximum difference between vertices
*       ( 0.00001 is a good start for a unitized model)
*
*/
GLvoid
glmWeld(GLMmodel* model, GLfloat epsilon);

时间: 2024-12-01 05:27:16

《基于MFC的OpenGL编程》Part 18 Reading objects from the OBJ File Format的相关文章

《基于MFC的OpenGL编程》Part 19 Creating a Virtual Reality Walkthrough…

<基于MFC的OpenGL编程>Part 19 Creating a Virtual Reality Walkthrough Application 本文是整个系列文章的最后一篇,将创建一个完整的虚拟office应用程序(如图所示)来做为ending. 1,在CCY457OpenGLView类中加入下述变量,用来保存office内各个物体的显示列表 //Display List Names GLuint m_SceneList; GLuint m_ComputerList; GLuint m_

《基于MFC的OpenGL编程》Part 5 Transformations

<基于MFC的OpenGL编程>Part 5 Transformations - Rotations,Translations and Scaling Transformations - Translation, Rotation and Scaling Translation is nothing but moving along an arbitrary axis. Rotation is spinning about an arbitrary axis. Scaling is incre

《基于MFC的OpenGL编程》Part 2 Setting up OpenGL on Windows

WGL – Windows的 OpenGL扩展层 The WGL extension consists of a set of functions (wglCreateContext, wglDeleteContext etc.) and structures (such as PIXELFORMATDESCRIPTOR, GLYPHMETRICSFLOAT) etc. Thus every OpenGL implementation has a platform-specific portio

《基于MFC的OpenGL编程》Part 17 Shadows

Shadows Conceptually drawing a shadow is quite simple. A shadow is produced when an object keeps light from a source from striking some object or surface behind the object, casting the shadow. The area on the shadowed object's surface outlined by the

《基于MFC的OpenGL编程》Part 15 Selection

Selection Selection is a powerful feature of OpenGL that allows you click at some position of the OpenGL window using the mouse and determine which of your objects lie beneath it. The act of selecting a specific object is called Picking. With OpenGL'

《基于MFC的OpenGL编程》Part 14 Quadrics

本文在第11篇文章的基础上,为其加入显示各种二次曲面的代码: Quadrics Every quadric has a few settings associated with it. We have to create a quadric first and then customize its settings to render the shape we want. The gluNewQuadric function creates a state variable that descr

《基于MFC的OpenGL编程》Part 13 Creating 2D and 3D Text

wglUseFontBitmaps函数 The wglUseFontBitmaps() function creates a set of bitmap display lists based on the glyphs in the currently selected font in the current DC for use in the current OpenGL RC. It basically creates a series of sequential display list

《基于MFC的OpenGL编程》Part 12 Creating and Using Display Lists

本文对第11篇文章进行修改,使用显示列表来存储渲染命令. 显示列表 OpenGL provides a facility to create a preprocessed set of OpenGL commands called a display list. Creating a display list is a straight forward process. We just have to delimit the display list code with glNewList an

《基于MFC的OpenGL编程》Part 11 Blending, Antialiasing and Fog

Blending and Transparency Blending in OpenGL provides pixel-level control of RGBA color storage in the color buffer. To enable blending we must first call glEnable(GL_BLEND). We have to set up the blending function glBlendFunc with two arguments: the