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

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

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 Millerobj文件加载类,其完整源代码可以从http://www.pobox.com/~ndr处下载。

Glm头文件

2, 在第17篇的基础上,CCY457OpenGLView类中加入下述变量,用来表示不同物体类型

    GLuint m_MonitorList; //显示器
    GLuint m_ChairList; //椅子
    GLuint m_PotList; //花瓶
    GLuint m_ComputerList; //计算机
    int m_nObjectNo;

2, InitializeOpenGL函数中加入对LoadModelsFromFiles的调用

3, 绘制函数修改如下:

void CCY457OpenGLView::RenderScene ()
{
//绘制函数
    
//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.0f0.0f);
    glVertex3f(
-2.0f0.0f0.0f);
    glTexCoord2f(
1.0f0.0f);
    glVertex3f(
2.0f,0.0f0.0f);
    glColor3ub(
0,100,0);    
    glTexCoord2f(
1.0f1.0f);
    glVertex3f(
2.0f0.0f-2.0f);
    glTexCoord2f(
0.0f1.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文件的具体实现代码:

//Load all the Models from the Files of type .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);        
}

 

posted on 2008-11-07 16:06  Phinecos(洞庭散人)  阅读(5031)  评论(9编辑  收藏  举报

导航