《基于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   Phinecos(洞庭散人)  阅读(5127)  评论(9编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述

导航

统计

点击右上角即可分享
微信分享提示