《基于MFC的OpenGL编程》Part 18 Reading objects from the OBJ File Format
Posted on 2011-12-27 09:32 阿Fai 阅读(358) 评论(0) 编辑 收藏 举报本文将介绍如何从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处下载。
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
2, 在第17篇的基础上,CCY457OpenGLView类中加入下述变量,用来表示不同物体类型
GLuint m_ChairList; //椅子
GLuint m_PotList; //花瓶
GLuint m_ComputerList; //计算机
int m_nObjectNo;
2, 在InitializeOpenGL函数中加入对LoadModelsFromFiles的调用
3, 绘制函数修改如下:
{//绘制函数
//Position Camera
gluLookAt(m_PosX,m_PosY,m_PosZ,m_DirX,m_DirY,m_DirZ,0.0f,1.0f,0.0f);
//Draw the Scene
//Draw the floor
// Draw the ground, we do manual shading to a darker green
// in the background to give the illusion of depth
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_Texture[3]);
glBegin(GL_POLYGON);
glColor3ub(0,255,0);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-2.0f, 0.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(2.0f,0.0f, 0.0f);
glColor3ub(0,100,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(2.0f, 0.0f, -2.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-2.0f,0.0f, -2.0f);
glEnd();
glDisable(GL_TEXTURE_2D);
//Draw the Cube
// Save the matrix state and do the rotations
glPushMatrix();
glTranslatef(-1.0f,0.6f,-1.0f);
// Draw jet at new orientation, put light in correct position
// before rotating the jet
glRotatef(m_xRot,1.0f,0.0f,0.0f);
glRotatef(m_yRot,0.0f,1.0f,0.0f);
DrawCube(FALSE);
// Restore original matrix state
glPopMatrix();
// Get ready to draw the shadow and the ground
// First disable lighting and save the projection state
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
glPushMatrix();
// Multiply by shadow projection matrix
glMultMatrixf((GLfloat *)m_ShadowMat);
glTranslatef(-1.0f,0.6f,-1.0f);
glRotatef(m_xRot,1.0f,0.0f,0.0f);
glRotatef(m_yRot,0.0f,1.0f,0.0f);
// Pass true to indicate drawing shadow
DrawCube(TRUE);
// Restore the projection to normal
glPopMatrix();
// Restore lighting state variables
glEnable(GL_DEPTH_TEST);
// Draw the light source
glPushMatrix();
glTranslatef(1.5f,1.5f,-1.0f);
glColor3ub(255,255,0);
glutSolidSphere(0.01f,10,10);
glPopMatrix();
glEnable(GL_LIGHTING);
}
void CCY457OpenGLView::DrawCube (BOOL bShadow)
{
// Set material color, note we only have to set to black
// for the shadow once
if(!bShadow)
{
switch (m_nObjectNo)
{
case 0: glCallList(m_ChairList);
break;
case 1: glCallList(m_PotList);
break;
case 2: glCallList(m_ComputerList);
break;
case 3: glCallList(m_MonitorList);
break;
case 4: DrawCubeTex();
break;
}
}
else
{
glColor3ub(0,0,0);
switch (m_nObjectNo)
{
case 0: glCallList(m_ChairList);
break;
case 1: glCallList(m_PotList);
break;
case 2: glCallList(m_ComputerList);
break;
case 3: glCallList(m_MonitorList);
break;
case 4: DrawCubeNoTex();
break;
}
}
}
4, 加载Obj文件的具体实现代码:
void CCY457OpenGLView::LoadModelsFromFiles()
{
GLfloat scalefactor = 0.0;
//Load Computer from file
GLMmodel *object1;
object1 = glmReadOBJ("models/computer.obj");
if(!scalefactor)
{
scalefactor = glmUnitize(object1);
}
else
{
glmScale(object1, scalefactor);
}
glmScale(object1, 2.5);
/* build a display list */
m_ComputerList = glmList(object1, GLM_SMOOTH);
/* nuke it, we don't need it anymore */
glmDelete(object1);
//Load Chair From File
GLMmodel *object2;
scalefactor = 0.0;
object2 = glmReadOBJ("models/chair04.obj");
if(!scalefactor)
{
scalefactor = glmUnitize(object2);
}
else
{
glmScale(object2, scalefactor);
}
glmScale(object2, 5.0);
/* build a display list */
m_ChairList = glmList(object2, GLM_SMOOTH);
/* nuke it, we don't need it anymore */
glmDelete(object2);
//Load Monitor from file
GLMmodel *object5;
scalefactor = 0.0;
object5 = glmReadOBJ("models/samsung.obj");
if(!scalefactor)
{
scalefactor = glmUnitize(object5);
}
else
{
glmScale(object5, scalefactor);
}
glmScale(object5, 0.5);
/* build a display list */
m_MonitorList = glmList(object5, GLM_SMOOTH);
/* nuke it, we don't need it anymore */
glmDelete(object5);
//Load Phone Object from file
GLMmodel *object6;
scalefactor = 0.0;
object6 = glmReadOBJ("models/plant2.obj");
if(!scalefactor)
{
scalefactor = glmUnitize(object6);
}
else
{
glmScale(object6, scalefactor);
}
glmScale(object6, 0.5);
/* build a display list */
m_PotList = glmList(object6, GLM_SMOOTH);
/* nuke it, we don't need it anymore */
glmDelete(object6);
}
作者:洞庭散人
出处:http://phinecos.cnblogs.com/