3D Studio 文件格式 (3ds)

3D Studio 文件格式 (3ds)

 

内容:

 

            1 介绍

            2 块的宏定义

            3 3D编辑块

            4 关键帧块

            5 源代码(参见SRTP档案袋光盘)

 

 

            1 介绍

 

3ds文件由块组成。这些块说明了紧跟其ID的内容和下一个块的地址。假如对某一个块不明白,可跳过。

下一个块的指针与当前块的首地址和长度有关,3ds文件以二进制形式存储。与许多文件格式一样,3ds二进制文件中的数据也是按低位在前、高位在后的方式组织的,例如,两个十六进制字节4A 5C 组成的整形数,表明5C是高位字节,4A是低位字节;对于长整形数,如:4A 5C 3B 8F表明5C4A是低位字,而8F3B是高位字。

起点

终点

长度

名称

0

1

2

Id

2

5

4

指向下一个块的指针

 

 

每个块实际上是一个层次结构,不同类型的块,其层次结构也不相同。每一个3ds文件首块ID4D4D

首块就是主块。

为了对快的层次结构有一个初步的认识,下面给出一个图标来说明不同类型(ID)的块及其各自在文件中的位置,如下图,这些块都赋予了一个名字,可以便于理解或者转换为源程序。

 

 

                  MAIN3DS  (0x4D4D)

                  |

                  +--EDIT3DS  (0x3D3D)

                  |  |

                  |  +--EDIT_MATERIAL (0xAFFF)

                  |  |  |

                  |  |  +--MAT_NAME01 (0xA000) (See mli Doc) 

                  |  |

                  |  +--EDIT_CONFIG1  (0x0100)

                  |  +--EDIT_CONFIG2  (0x3E3D) 

                  |  +--EDIT_VIEW_P1  (0x7012)

                  |  |  |

                  |  |  +--TOP            (0x0001)

                  |  |  +--BOTTOM         (0x0002)

                  |  |  +--LEFT           (0x0003)

                  |  |  +--RIGHT          (0x0004)

                  |  |  +--FRONT          (0x0005) 

                  |  |  +--BACK           (0x0006)

                  |  |  +--USER           (0x0007)

                  |  |  +--CAMERA         (0xFFFF)

                  |  |  +--LIGHT          (0x0009)

                  |  |  +--DISABLED       (0x0010)  

                  |  |  +--BOGUS          (0x0011)

                  |  |

                  |  +--EDIT_VIEW_P2  (0x7011)

                  |  |  |

                  |  |  +--TOP            (0x0001)

                  |  |  +--BOTTOM         (0x0002)

                  |  |  +--LEFT           (0x0003)

                  |  |  +--RIGHT          (0x0004)

                  |  |  +--FRONT          (0x0005) 

                  |  |  +--BACK           (0x0006)

                  |  |  +--USER           (0x0007)

                  |  |  +--CAMERA         (0xFFFF)

                  |  |  +--LIGHT          (0x0009)

                  |  |  +--DISABLED       (0x0010)  

                  |  |  +--BOGUS          (0x0011)

                  |  |

                  |  +--EDIT_VIEW_P3  (0x7020)

                  |  +--EDIT_VIEW1    (0x7001) 

                  |  +--EDIT_BACKGR   (0x1200) 

                  |  +--EDIT_AMBIENT  (0x2100)

                  |  +--EDIT_OBJECT   (0x4000)

                  |  |  |

                  |  |  +--OBJ_TRIMESH   (0x4100)      

                  |  |  |  |

                  |  |  |  +--TRI_VERTEXL          (0x4110) 

                  |  |  |  +--TRI_VERTEXOPTIONS    (0x4111)

                  |  |  |  +--TRI_MAPPINGCOORS     (0x4140) 

                  |  |  |  +--TRI_MAPPINGSTANDARD  (0x4170)

                  |  |  |  +--TRI_FACEL1           (0x4120)

                  |  |  |  |  |

                  |  |  |  |  +--TRI_SMOOTH            (0x4150)   

                  |  |  |  |  +--TRI_MATERIAL          (0x4130)

                  |  |  |  |

                  |  |  |  +--TRI_LOCAL            (0x4160)

                  |  |  |  +--TRI_VISIBLE          (0x4165)

                  |  |  |

                  |  |  +--OBJ_LIGHT    (0x4600)

                  |  |  |  |

                  |  |  |  +--LIT_OFF              (0x4620)

                  |  |  |  +--LIT_SPOT             (0x4610) 

                  |  |  |  +--LIT_UNKNWN01         (0x465A) 

                  |  |  | 

                  |  |  +--OBJ_CAMERA   (0x4700)

                  |  |  |  |

                  |  |  |  +--CAM_UNKNWN01         (0x4710)

                  |  |  |  +--CAM_UNKNWN02         (0x4720)  

                  |  |  |

                  |  |  +--OBJ_UNKNWN01 (0x4710)

                  |  |  +--OBJ_UNKNWN02 (0x4720)

                  |  |

                  |  +--EDIT_UNKNW01  (0x1100)

                  |  +--EDIT_UNKNW02  (0x1201) 

                  |  +--EDIT_UNKNW03  (0x1300)

                  |  +--EDIT_UNKNW04  (0x1400)

                  |  +--EDIT_UNKNW05  (0x1420)

                  |  +--EDIT_UNKNW06  (0x1450)

                  |  +--EDIT_UNKNW07  (0x1500)

                  |  +--EDIT_UNKNW08  (0x2200)

                  |  +--EDIT_UNKNW09  (0x2201)

                  |  +--EDIT_UNKNW10  (0x2210)

                  |  +--EDIT_UNKNW11  (0x2300)

                  |  +--EDIT_UNKNW12  (0x2302)

                  |  +--EDIT_UNKNW13  (0x2000)

                  |  +--EDIT_UNKNW14  (0xAFFF)

                  |

                  +--KEYF3DS (0xB000)

                     |

                     +--KEYF_UNKNWN01 (0xB00A)

                     +--............. (0x7001) ( viewport, same as editor )

                     +--KEYF_FRAMES   (0xB008)

                     +--KEYF_UNKNWN02 (0xB009)

                     +--KEYF_OBJDES   (0xB002)

                        |

                        +--KEYF_OBJHIERARCH  (0xB010)

                        +--KEYF_OBJDUMMYNAME (0xB011)

                        +--KEYF_OBJUNKNWN01  (0xB013)

                        +--KEYF_OBJUNKNWN02  (0xB014)

                        +--KEYF_OBJUNKNWN03  (0xB015)  

                        +--KEYF_OBJPIVOT     (0xB020)  

                        +--KEYF_OBJUNKNWN04  (0xB021)  

                        +--KEYF_OBJUNKNWN05  (0xB022)  

 

 

颜色块是文件中自始至终都见到的一种块类型,颜色块共有三种类型,依次是COL_RGB COL_TRU  COL_UNK

 

 

                             2. 块的宏定义

                         =========================

 

现在,我将用宏定义定义这些块,这些宏定义取自源程序代码。然而,依然需要小心,因为很多新块未能得到及时的说明。

 

 //------ Primary chunk

 

 #define MAIN3DS       0x4D4D

 

 //------ Main Chunks

 

 #define EDIT3DS       0x3D3D  // this is the start of the editor config

 #define KEYF3DS       0xB000  // this is the start of the keyframer config

 

 //------ sub defines of EDIT3DS

 

 #define EDIT_MATERIAL 0xAFFF

 #define EDIT_CONFIG1  0x0100

 #define EDIT_CONFIG2  0x3E3D

 #define EDIT_VIEW_P1  0x7012

 #define EDIT_VIEW_P2  0x7011

 #define EDIT_VIEW_P3  0x7020

 #define EDIT_VIEW1    0x7001

 #define EDIT_BACKGR   0x1200

 #define EDIT_AMBIENT  0x2100

 #define EDIT_OBJECT   0x4000

 

 #define EDIT_UNKNW01  0x1100

 #define EDIT_UNKNW02  0x1201

 #define EDIT_UNKNW03  0x1300

 #define EDIT_UNKNW04  0x1400

 #define EDIT_UNKNW05  0x1420

 #define EDIT_UNKNW06  0x1450

 #define EDIT_UNKNW07  0x1500

 #define EDIT_UNKNW08  0x2200

 #define EDIT_UNKNW09  0x2201

 #define EDIT_UNKNW10  0x2210

 #define EDIT_UNKNW11  0x2300

 #define EDIT_UNKNW12  0x2302 

 #define EDIT_UNKNW13  0x3000

 #define EDIT_UNKNW14  0xAFFF

 

 //------ sub defines of EDIT_OBJECT

 #define OBJ_TRIMESH   0x4100

 #define OBJ_LIGHT     0x4600

 #define OBJ_CAMERA    0x4700

 

 #define OBJ_UNKNWN01  0x4010

 #define OBJ_UNKNWN02  0x4012 //---- Could be shadow

 

 //------ sub defines of OBJ_CAMERA

 #define CAM_UNKNWN01  0x4710 

 #define CAM_UNKNWN02  0x4720 

 

 //------ sub defines of OBJ_LIGHT

 #define LIT_OFF       0x4620

 #define LIT_SPOT      0x4610

 #define LIT_UNKNWN01  0x465A

 

 //------ sub defines of OBJ_TRIMESH

 #define TRI_VERTEXL   0x4110

 #define TRI_FACEL2    0x4111 

 #define TRI_FACEL1    0x4120

 #define TRI_SMOOTH    0x4150

 #define TRI_LOCAL     0x4160

 #define TRI_VISIBLE   0x4165

 

 //------ sub defs of KEYF3DS

 

 #define KEYF_UNKNWN01 0xB009

 #define KEYF_UNKNWN02 0xB00A

 #define KEYF_FRAMES   0xB008

 #define KEYF_OBJDES   0xB002

 

 //------  these define the different color chunk types

 #define COL_RGB  0x0010

 #define COL_TRU  0x0011

 #define COL_UNK  0x0013

 

 //------ defines for viewport chunks

 

 #define TOP           0x0001

 #define BOTTOM        0x0002

 #define LEFT          0x0003

 #define RIGHT         0x0004

 #define FRONT         0x0005

 #define BACK          0x0006

 #define USER          0x0007

 #define CAMERA        0x0008 // 0xFFFF is the actual code read from file

 #define LIGHT         0x0009

 #define DISABLED      0x0010

 #define BOGUS         0x0011

 

 

 

 

                                      33D编辑块

最开始出现的主块是基本块,它包含了整个文件。因此这个块的大小就是文件的大小减去主块的大小。还有两种主块:3D编辑程序块和关键帧块,前者的ID3D3D,后者的IDB000 3D编辑程序块表明编辑程序数据开始,也就是说物体的形体数据定义从此处开始。关键帧块表明下面开始定义关键帧信息。

 

 * 3D3D的子块

  id   描述

 0100  配置的一部分

 1100  未知

 1200  背景颜色

 1201  未知

 1300  未知

 1400  未知

 1420  未知

 1450  未知

 1500  未知

 2100  环境颜色块

 2200 

 2201 

 2210 

 2300  未知

 3000  未知

 3D3E  编辑程序配置主块

 4000  物体定义

 AFFF  材质列表开始

 

  id   描述

 7001  视口指示器

 7011  视口定义 ( 类型2 )

 7012  视口定义 ( 类型 1 )

 7020  视口定义 ( 类型 3 )

 

3D3E块中包含了许多冗余数据,其中较重要的块石7020块,这个块定义编辑程序中4个活动的视口。假设在编辑程序布局中使用了4个视口,编辑程序配置中包含57020视口定义块和五个7011视口定义块。但事实上只有开始的四个7020块对用户的视口的外观有影响,其它的视口中只包含一些附加信息。该块的第67字节表明视图的类型,合法的ID及其对应视图如下所示:

 

  id    Description

 0001   顶视图

 0002   底视图

 0003   左视图

 0004   右视图

 0005   前视图

 0006   后视图

 0007   用户视图

 FFFF   相机视图

 0009   光源视图

 0010   无效

 

 

 4000(物体描述块)的子块

    第一项是物体名称.它是一个零结尾串,这里所指物体可以是一个相机或一个光源.也可

以是物体的形体。

    ID               含义

    4010          未知

    4012          阴影块

    4100           三角形列表块

    4600           光源块

    4700           相机块

 4100(三角形列表)的子块

    ID               含义

    4110          顶点列表

    4111           顶点选项

    4120          面列表

    4130          面材质

    4140          纹理映射坐标

    4150          面平滑组

    4160          平移矩阵

    4165          物体可见性

    4170          标准映射

 

            4110 – 定点列表

 

起始点

终点

大小

类型

名字

0

1

2

unsigned int

物体顶点数目

2

5

4

float

X坐标值

6

9

4

float

Y坐标值

10

13

4

float

Z坐标值

 

 

 

    从第2个字节到第13个字节定义了一个顶点的坐标,重复这项定义VerteNum次,便得

到了所有顶点的坐标。

 

4111(顶点选项块)的子块

    该子块由一些整型数组成,第一个整型数表明顶点个数,然后对每个顶点用一个整型数表

示一些位信息。其中,071112位影响物体的可见性,810位是随机信息,1315

表明该顶点是否在某个选择集中被选中。顶点选项块不是很重要,即使将其删除, 3DS也能

正确地将物体装入。

 

4120面列表块

起始点

终点

大小

类型

名称

0

1

2

unsigned int

物体中三角形个数

2

3

2

unsigned int

顶点A序号

4

5

2

unsigned int

顶点B序号

6

7

2

unsigned int

顶点C序号

8

9

2

unsigned int

面信息

 

 

 

    重复29定义PolyNum次,就给出了所有的三角形。27所给出的3个整型数是三角

形面的的3个顶点序号,序号为0的顶点表示顶点列表中定义的第一个顶点。顶点的顺序影响

着面的法向量方向。一般情况下三角形应按逆时针方向定义,但有些3DS文件使用顺时针方

向,这时就需要在程序中将其调整过来。面信息是一个整型数,其中前三个二进制位给出了三

角形每条边的顺序,可以根据它们判别三角形是以逆时针还是顺时针顺序给出的。这三个数宇

要么全是0要么全是1,若这三位全为1,其二进制方式为111,意味着三角形的三顶点的正

确顺序应是A->C->B,即A->C->B给出的是顺时针方向:反之,这三位全是0,则意味着A

->B->C给出的就是逆时针方向。

 

 

下面给出面信息中每一位的具体含义;

bito      AC边顺序,1C->A 0A->C

bit1      BC边顺序,1B->C 0C->B

bit2      AB边顺序,1A->B 0B->A

bit3纹理映射(如果有)

bit48保留(0

bit910随机数

bit1112保留(0

bit13面在第3迷择集中被选中

bit14面在秦3选择集中波选中

bit15面在第3选择集中彼选中4130画村质块

 

 

 

4130 – 面材质 

    材质块给出了物体中使用的每一种材质,但并不是每个物体都有材质块,只使用默认材质

的物体就没有材质块。每一个4130面材质块以一个0结尾的材质名称字符串开始,接着跟一

个由数字表示的与该材质相关的面的数目,然后就是一个一个的面。0000表示4120面列表中

的第一个面。

 

4140纹理映射坐标

    2个字节表示定义的顶点数,然后为每个顶点定义2个浮点型的纹理映射坐标。也就是

说,如果一个顶点的纹理映射在纹理平面的中心,那么其映射坐标即为(0.50.5)。

 

4150面平滑组块

    块的大小为面的个数*4个字节,即每个基本数据是一个长整型数字,第n个数字表示该

面是否属千第n个平滑组。

 

4160局部坐标轴块

局部坐标系轴信息,开始的三个厚点数定义了物体的局部坐标轴在绝对坐标系内的XY

Z坐标、最后的3个浮点数是物体的局部中心。

 

4170标准映射

    2个字节表明映射的类型,其中,0表明平面映肘或指定映射,当指定映射时,与这个

块中的信息就无关了,1表明圆柱映射,2表明球映射.接着用21个浮点数宋描述这个映射.

   

 

 

光源块

 

    ID                含义

    0010           RGB 颜色块

    0011            24位颜色

    4610            点光源

    4620            光源被关闭

 

起始点

终点

长度

类型

名称

0

3

4

浮点

光源位置x坐标

4

7

4

浮点

光源位置y坐标

8

11

4

浮点

光源位置z坐标

12

15

4

浮点

热点

16

19

4

浮点

发散

 

 

0010 - RGB 颜色块

起点

终点

长度

类型

名字

0

3

4

浮点

4

7

4

浮点

绿

8

11

4

浮点

 

 

0011 - RGB 24位颜色块 

起点

终点

长度

类型

名字

0

1

1

字节

1

1

1

字节

绿

2

2

1

字节

 

 

4700 – 相机块

描述场景中相机块信息

 

起始点

终点

长度

类型

名称

0

3

4

浮点

相机位置x坐标

4

7

4

浮点

相机位置y坐标

8

11

4

浮点

相机位置z坐标

12

15

4

浮点

相机目标x坐标

16

19

4

浮点

相机目标y坐标

20

23

4

浮点

相机目标z坐标

24

27

4

浮点

相机倾斜(旋转角)

26

31

4

浮点

相机镜头

 

 

 

 

 

                           4. 关键帧块

                       ==========================

 

 

关键帧块

 

  id         描述

 B00A        未知

 7001        块首要描述

 B008        帧信息块

 B009        未知

 B002        信息开始块

 

 * B008 – 帧信息块

 

 simple structure describing frame info

描述帧块信息结构

起始点

终点

长度

类型

名称

0

3

4

unsigned long

首帧

4

7

4

unsigned long

尾帧

 

 

B002 – 物体信息开始块

 

子块

 

  id     描述

 B010    名称与结构层次

 B011*   亚元物体命名

 B013    未知

 B014*   未知

 B015    未知

 B020    物体中心点

 B021    未知

 B022    未知

 

B010 - Name & Hierarchy descriptor

 

起始点

终点

长度

类型

名称

0

未确定

未确定

ASCII

物体名

未确定

未确定

2

unsigned int

未知

未确定

未确定

2

unsigned int

未知

未确定

未确定

2

unsigned int

物体层次结构

 

 

    物体的层次结构井不复杂,场景中给于每个物体一个数字以标识其在场景树中的顺序。相

应地。3DS文件中也用相同的方法标识了物体在场景树中的位置。作为根物体给予数字-1

FFFF)作为其数字标识。当读取文件的时候.就会得到一系列的物体数字标识。如果当前

数字标识比前一个大,那么当前物体是前一个物体的子物体:反之,当数宇标识比前一个数字

标识小.则又回到上一层结构。

 

例如:

    object   hierarchy

    name

 

        A      -1

        B       0                 This example is taken

        C       1                 from 50pman.3ds

        D       2

        E       1                 I would really reccomend

        F       4                 having a look at one of the

        G       5                 examples with the hierarchy

        H       1                 numbers to help work it out.

        I       7

        J       8

        K       0

        L      10

        M      11

        N       0

        O      13

        P      14

 

 

                           A

         +-----------------+----------------+

         B                    K                    N

    +----+----+             |                    |

    C    E    H              L                    O

    |    |    |               |                   |

    D    F    I               M                   P

         |    |

         G    J

 

这个块尚未结束,假如这个块名为$$$DUMMY,这是一个亚元物体,还需加入一些其它块。

B011 - 亚元物体名

    

B020 – 轴点

前五个浮点数的作用尚不清楚。

起始点

终点

长度

类型

名称

0

3

4

浮点

未知

4

7

4

浮点

未知

8

11

4

浮点

未知

12

16

4

浮点

未知

16

19

4

浮点

未知

20

23

4

浮点

未知

24

27

4

浮点

Y轴坐标

28

32

4

浮点

X轴坐标

 

 

 

 

 

 

 

 

 

 

12.(附录3程序读入文件源代码简介

运行程序,选择[文件/打开],发出ID_FILE_OPEN消息,触发函数

BOOL CMy3DSLoaderDoc::OnOpenDocument(LPCTSTR lpszPathName) 

{

 if (!CDocument::OnOpenDocument(lpszPathName))

  return FALSE;

 if( ((CMy3DSLoaderApp*)AfxGetApp())->OpenFile(lpszPathName) ) return TRUE;

 return TRUE;

}

                调用

BOOL CMy3DSLoaderApp::OpenFile(LPCTSTR lpszPathName)

{

 return ((CMy3DSLoaderView*)((CFrameWnd*)m_pMainWnd)->GetActiveView())->OpenFile(lpszPathName);

}                  

((CFrameWnd*)m_pMainWnd)->GetActiveView()获得一个指向CMy3DSLoaderView类指针,由于OpenFile函数在CMy3DSLoaderView中被重载,所以调用

CMy3DSLoaderView::OpenFile

BOOL CMy3DSLoaderView::OpenFile(LPCTSTR lpszPathName)

{

 char* file = new char[strlen(lpszPathName)];

 strcpy(file, lpszPathName); 

 C3dsReader Loader;

 BOOL result;

 if( m_triList.getNumObjects() > 0 ) m_triList.removeAllObjects();//清空数组

 result = Loader.Reader(file, &m_triList);

 if( result) 

 {

  m_3dsLoaded = TRUE;

  m_triList.doAfterMath();

 } 

 return result;

}

 

调用Loader.Reader读入3ds文件

BOOL C3dsReader::Reader( char* filename, CTriList* _list)

{

 FILE*  fp;

 long  fileSize;

 Chunk3DS chunk;

 DaList = _list;

 // 二进制的方式打开一个3DS文件

 if ((fp = fopen(filename, "rb")) != NULL) 

 {

  long chunkStart = ftell(fp);

 

  // 获得文件大小

  fseek(fp, 0, SEEK_END);

  fileSize = ftell(fp);

  fseek(fp, 0, SEEK_SET);

 

  // 验证文件类型

  if (!Is3DSFile(fp)) 

  {

    return FALSE;

  }

 

  // 循环所有的块

  while (chunkStart < fileSize &&

   Read3DSChunk(fp, chunk)) 

  {

   switch (chunk.id) 

   {

   case M3DMAGIC:

    if (!Read3DSFile(fileSize, chunkStart, chunk.len, fp)) 

    {

     fclose(fp);

     return FALSE;

    }

    break;

   default:

    // 忽略一些不需要的块

    fseek(fp, chunkStart + chunk.len, SEEK_SET);

   }

   chunkStart = ftell(fp);

  }

 

  fclose(fp);

 }

 else 

  return FALSE;

 

 return TRUE;

}

 

读入文件后 ,触发CMy3DSLoaderView::OnDraw函数

void CMy3DSLoaderView::OnDraw(CDC* pDC)

{

 CMy3DSLoaderDoc* pDoc = GetDocument();

 ASSERT_VALID(pDoc);

//////////////////////////////////////////////////////////////////

 RenderScene(); //渲染场景

//////////////////////////////////////////////////////////////////

}

调用CMy3DSLoaderView::RenderScene

BOOL CMy3DSLoaderView::RenderScene() 

{

 ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

 ::glMatrixMode(GL_MODELVIEW);

 ::glLoadIdentity();

 

 ::glTranslatef( camPos[0], camPos[1], camPos[2] );

 ::glRotatef( camRot[0], 1.0F, 0.0F, 0.0F );

 ::glRotatef( camRot[1], 0.0F, 1.0F, 0.0F );

 ::glRotatef( camRot[2], 0.0F, 0.0F, 1.0F );

 

 ::glPushMatrix();

 ::glTranslatef(scenePos[0], scenePos[1], scenePos[2]);

 ::glRotatef( sceneRot[0], 1.0F, 0.0F, 0.0F );

 ::glRotatef( sceneRot[1], 0.0F, 1.0F, 0.0F );

 ::glRotatef( sceneRot[2], 0.0F, 0.0F, 1.0F );

 

 DrawAxis();  //画坐标系

 Draw3ds();

 

 ::glPopMatrix();

 

 ::SwapBuffers(m_pDC->GetSafeHdc());  //交互缓冲区

 return TRUE;

}

 

调用 Draw3ds();

void CMy3DSLoaderView::Draw3ds()

{

 if (m_3dsLoaded) 

 {

   m_triList.drawGL();

 }

}

调用CTriList::drawGL()函数

void CTriList::drawGL()

{

 for (int i=0; i <numobjects; i++)

 {

  objects[i]->drawGL();

 } 

}

 

转而调用CTriObject::drawGL()建模

void CTriObject::drawGL()

{

 

 if (normalapplied)

 {

  int j;

  glBegin(GL_TRIANGLES);

   for (i=0; i <numfaces/3; i++)

   {

    j = 3*i;

    if(materialsapplied) 

glColor4f(materials[matfaces[i]].diffuseColor[0],

materials[matfaces[i]].diffuseColor[1],

materials[matfaces[i]].diffuseColor[2], 

1/materials[matfaces[i]].transparency );

    else   glColor3f( 0.0f, 0.0f, 1.0f );

    ::glNormal3f( nx[i], ny[i], nz[i]);

    ::glVertex3f( x[faces[j]]  ,  y[faces[j]]  ,  z[faces[j]]);

    ::glVertex3f( x[faces[j+1]],  y[faces[j+1]],  z[faces[j+1]]);

    ::glVertex3f( x[faces[j+2]],  y[faces[j+2]],  z[faces[j+2]]);

   }

  glEnd();

 }

 else

 {

  glBegin(GL_TRIANGLES);

   for (i=0; i <numfaces; i+=3)

   {

    if(materialsapplied) 

glColor3f(materials[matfaces[i/3]].diffuseColor[0], materials[matfaces[i/3]].diffuseColor[1], materials[matfaces[i/3]].diffuseColor[2] );

    else glColor3f( 0.0f, 0.0f, 1.0f );

    glVertex3f( x[faces[i]]  ,  y[faces[i]]  ,  z[faces[i]]);

    glVertex3f( x[faces[i+1]],  y[faces[i+1]],  z[faces[i+1]]);

    glVertex3f( x[faces[i+2]],  y[faces[i+2]],  z[faces[i+2]]);

   }

  glEnd();

 }

 

 glPopMatrix();

}

 

至此,程序读入3ds文件过程基本清晰。

 

 

你可能感兴趣的:(object,File,float,FP,hierarchy,Descriptor)