160 likes | 331 Views
1 、 3ds 文件结构:. 3ds 文件结构是由“块”组成的。它们描述了接在它们后面的数据的信息,即这些数据是如何组成的。 “块”是由两部分组成的: 1.ID ; 2. 下一个数据块的位置. 3ds 文件结构. 二进制的 3ds 文件是用一种特殊的方法写成的:也就是低字节在前,高字节在后(二进制文件都是这样的)。 举例 :4A 5C (十六进制, 2 个字节)实际上是数字: 5C 4A , 4A 是低字节, 5C 是高字节。对于 4 字节整数: 4A 5C 3B 8F 实际上是 8F 3B 5C 4A , 3B 8F 是高字节, 4A 5C 是低字节。.
E N D
1、3ds文件结构: • 3ds文件结构是由“块”组成的。它们描述了接在它们后面的数据的信息,即这些数据是如何组成的。 • “块”是由两部分组成的: 1.ID; 2.下一个数据块的位置
3ds文件结构 • 二进制的3ds文件是用一种特殊的方法写成的:也就是低字节在前,高字节在后(二进制文件都是这样的)。 • 举例:4A 5C(十六进制,2个字节)实际上是数字:5C 4A,4A 是低字节,5C是高字节。对于4字节整数:4A 5C 3B 8F实际上是8F 3B 5C 4A,3B 8F是高字节,4A 5C是低字节。
2、“块”被定义如下: • unsigned short ID;//2个字节,无符号的,块的ID • unsigned long Length;//4个字节,无符号的,描述了下一个数据区对于当前数据区的位置,实际上就是本数据区的大小。
3、块结构:(表) • 每个块是一个层次结构,由ID表示。3ds文件有一个主块,ID是0x4D4D。这个块是3ds文件的开始,可以用它来鉴定本文件是否为一个3ds文件 • 参考块的结构表:
4、数字块在程序中的定义: 一般使用define来定义这些数字: 如:// 基本块(Primary Chunk),位于文件的开始 • #define PRIMARY 0x4D4D • // 主块(Main Chunks) • #define OBJECTINFO 0x3D3D // 网格对象的版本号 • #define VERSION 0x0002 // .3ds文件的版本 • #define EDITKEYFRAME 0xB000 // 所有关键帧信息的头部 • // 对象的次级定义(包括对象的材质和对象) • #define MATERIAL 0xAFFF // 保存纹理信息 • #define OBJECT 0x4000 // 保存对象的面、顶点等信息 • // 材质的次级定义 • #define MATNAME 0xA000 // 保存材质名称 • #define MATDIFFUSE 0xA020 // 对象/材质的颜色 • #define MATMAP 0xA200 // 新材质的头部 • #define MATMAPFILE 0xA300 // 保存纹理的文件名 • #define OBJ_MESH 0x4100 // 新的网格对象 • #define MAX_TEXTURES 100 // 最大的纹理数目 • // OBJ_MESH的次级定义 • #define OBJ_VERTICES 0x4110 // 对象顶点 • #define OBJ_FACES 0x4120 // 对象的面 • #define OBJ_MATERIAL 0x4130 // 对象的材质 • #define OBJ_UV 0x4140 // 对象的UV纹理坐标
5、各类信息结构的定义1: • class CVector3 //定义3D点的类,用于保存模型中的顶点 • {public: float x, y, z; • }; • class CVector2 //定义2D点类,用于保存模型的UV纹理坐标 • {public: float x, y; • }; • struct tFace //面的结构定义 • { int vertIndex[3]; // 顶点索引 • int coordIndex[3]; // 纹理坐标索引 • };
5、各类信息结构的定义2: • struct tMatInfo//材质信息结构体 • { char strName[255]; // 纹理名称 • char strFile[255]; // 如果存在纹理映射,则表示纹理文件名称 • BYTE color[3]; // 对象的RGB颜色 • int texureId; // 纹理ID • float uTile; // u 重复 • float vTile; // v 重复 • float uOffset; // u 纹理偏移 • float vOffset; // v 纹理偏移 • } ; • struct t3DObject //对象信息结构体 • { int numOfVerts; // 模型中顶点的数目 • int numOfFaces; // 模型中面的数目 • int numTexVertex; // 模型中纹理坐标的数目 • int materialID; // 纹理ID • bool bHasTexture; // 是否具有纹理映射 • char strName[255]; // 对象的名称 • CVector3 *pVerts; // 对象的顶点 • CVector3 *pNormals; // 对象的法向量 • CVector2 *pTexVerts; // 纹理UV坐标 • tFace *pFaces; // 对象的面信息 • };
5、各类信息结构的定义3: • struct t3DModel //模型信息结构体 • { int numOfObjects; // 模型中对象的数目 • int numOfMaterials; // 模型中材质的数目 • vector<tMatInfo>pMaterials; // 材质链表信息 • vector<t3DObject> pObject; // 模型中对象链表信息 • }; • struct tChunk //保存块信息的结构 • { unsigned short int ID; // 块的ID • unsigned int length; // 块的长度 • unsigned int bytesRead; // 需要读的块数据的字节数 • };
5、各类信息结构的定义4: • class CLoad3DS// CLoad3DS类处理所有的装入代码 • { • public: • CLoad3DS(); // 初始化数据成员 • virtual ~CLoad3DS(); • void show3ds(int j0,float tx,float ty,float tz,float size);//显示3ds模型 • void Init(char *filename,int j); • private: • bool Import3DS(t3DModel *pModel, char *strFileName);// 装入3ds文件到模型结构中 • void CreateTexture(UINT textureArray[], LPSTR strFileName, int textureID);// 从文件中创建纹理 • int GetString(char *); // 读一个字符串 • void ReadChunk(tChunk *); // 读下一个块 • void ReadNextChunk(t3DModel *pModel, tChunk *); // 读下一个块 • void ReadNextObjChunk(t3DModel *pModel,t3DObject *pObject,tChunk *);// 读下一个对象块 • void ReadNextMatChunk(t3DModel *pModel, tChunk *); // 读下一个材质块 • void ReadColor(tMatInfo *pMaterial, tChunk *pChunk);// 读对象颜色的RGB值 • void ReadVertices(t3DObject *pObject, tChunk *); // 读对象的顶点 • void ReadVertexIndices(t3DObject *pObject,tChunk *);// 读对象的面信息 • void ReadUVCoordinates(t3DObject *pObject,tChunk *);// 读对象的纹理坐标 • void ReadObjMat(t3DModel *pModel,t3DObject *pObject,tChunk *pPreChunk);// 读赋予对象的材质名称 • void ComputeNormals(t3DModel *pModel); // 计算对象顶点的法向量 • void CleanUp(); // 关闭文件,释放内存空间 • FILE *m_FilePointer; // 文件指针 • tChunk *m_CurrentChunk; • tChunk *m_TempChunk; • };
LoadT8中的函数解释: • auxDIBImageLoad(Filename) 读取图象数据并将其返回。 • glGenTextures(1, &texture[0]) 告诉OpenGL想生成一个纹理名字 。 • glBindTexture(GL_TEXTURE_2D, texture[0]) 告诉OpenGL将纹理名字texture[0] 绑定到纹理目标上。 • 2D纹理只有高度(在 Y 轴上)和宽度(在 X 轴上)。主函数将纹理名字指派给纹理数据。本例中告知OpenGL,&texture[0] 处的内存已经可用。创建的纹理将存储在&texture[0] 的 指向的内存区域。
纹理映射的步骤 • 1) 创建纹理对象并为其指定纹理.2) 指出如何将纹理应用于每个像素3) 启用纹理映射4) 使用纹理坐标和几何坐标来绘制场景.只能RGBA模式下使用纹理映射
步骤: • 1), 创建纹理对象并为其指定纹理 纹理不但是二维的,也可以是一维或三维的.2. 指定如何将纹理应用于每个像素 根据片元的颜色和纹理图像数据计算最终的RGBA值的方法: 1) 将纹理颜色作为最终的颜色, 就像贴花(替换模式), 将纹理绘制到片元2) 使用纹理来调整(缩放)片元的颜色3) 根据纹理数据, 将一种常量颜色和片元混合起来.3. 启用纹理映射 使用符号常量 GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP作为参数调用函数glEnable()或glDisable();分别对应于一维, 二维, 三维和立方图纹理映射模式4. 使用纹理坐标和几何坐标绘制场景
int gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLint width, GLint height, GLenum format, GLenum type, const void *texels);
飞机模型构成 • 用一些基本图形来构造一架飞机,并让飞机在场景中盘旋 .