3ds文件本身就有好几种格式,这主要是3ds这个软件发展的过程当中产生,现在3dmax导出的3ds格式应该是3ds 4.0对应的格式(大概在是95年左右时候) 关于3ds的格式,虽然没有官方的文档,但是 网络 上流传的关于它的描述文件还是很多的,而且 自从有了3dmax之后,3ds的格式已经没有再发生变化了,3dmax自己的格式就是max格式,opengl本身没有直接导入3ds格式的功能,需要自己写代码来转换这个东西 ,3ds文件当中有一个位置表明它的版本号的 官方3ds文件格式介绍 -------------------------------------------------------------------------------------------------------------- 介绍 3ds文件由块组成。这些块说明了紧跟其ID的内容和下一个块的地址。假如对某一个块不明白,可跳过。 下一个块的指针与当前块的首地址和长度有关,3ds文件以 二进制形式存储。与许多文件格式一样,3ds二进制文件中的数据也是按低位在前、高位在后的方式组织的,例如,两个十六进制字节4A 5C 组成的整形数,表明5C是高位字节,4A是低位字节;对于长整形数,如:4A 5C 3B 8F表明5C4A是低位字,而8F3B是高位字。 每个块实际上是一个层次结构,不同类型的块,其层次结构也不相同。 每一个3ds文件 首块ID是4D4D。首块就是 主块。包含了整个文件。 ----------------------------------------------------------------------------------------------------------------------------------------------------------- 块的宏定义 现在,我将用宏定义定义这些块,这些宏定义取自源程序代码。然而,依然需要小心,因为很多新块未能得到及时的说明。 //------ 基本块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 定义数据结构 //保存块信息的结构 struct CLscChunk { unsigned short int ID; //块的ID unsigned int length; //块的长度 unsigned int bytesRead; //需要读的块数据的字节数 }; 读取块的ID和长度 // 读入块的ID号和它的字节长度(并没有读取块的内容) void C3DLoader::ReadChunk(CLscChunk *pChunk) { //读入块的ID号,每次读一个BYTE,占用2个字节 pChunk->bytesRead=fread(&pChunk->ID,1,2,m_pFile); pChunk->bytesRead += fread((&pChunk->length,1,4,m_pFile); } Import3DS 打开3DS文件,按照块的顺序将其中的内容读取出来,最后释放占用的内存空间。