自制C#版3DS文件的解析器并用SharpGL显示3DS模型
来源:互联网 发布:怎样查看淘宝购买记录 编辑:程序博客网 时间:2024/05/30 04:24
自制C#版3DS文件的解析器并用SharpGL显示3DS模型
据说*.3ds格式的3D模型文件是很古老和过时的格式。本文参考了(http://www.spacesimulator.net/wiki/index.php?title=Tutorials:3ds_Loader)和(http://www.cnblogs.com/lookof/archive/2009/03/27/1423695.html),在此表示感谢。本文讲解如何从零开始用C#写一个3ds文件的解析器,然后用SharpGL(C#对opengl的封装)来显示3ds模型。有图有真相。
上图使用的3ds模型文件和贴图文件在此。(spaceship.zip)(spaceshiptexture.bmp)
3DS文件格式
3ds文件是二进制的。3ds格式的基本单元叫块(chunk)。我们就是读这样一块一块的信息。目录树如下,缩进风格体现了块的父子关系。可见3ds模型文件和XML文件类似,都是只有1个根结点的树状结构。
1 MAIN CHUNK 0x4D4D 2 3D EDITOR CHUNK 0x3D3D 3 OBJECT BLOCK 0x4000 4 TRIANGULAR MESH 0x4100 5 VERTICES LIST 0x4110 6 FACES DESCRIPTION 0x4120 7 FACES MATERIAL 0x4130 8 MAPPING COORDINATES LIST 0x4140 9 SMOOTHING GROUP LIST 0x415010 LOCAL COORDINATES SYSTEM 0x416011 LIGHT 0x460012 SPOTLIGHT 0x461013 CAMERA 0x470014 MATERIAL BLOCK 0xAFFF15 MATERIAL NAME 0xA00016 AMBIENT COLOR 0xA01017 DIFFUSE COLOR 0xA02018 SPECULAR COLOR 0xA03019 TEXTURE MAP 1 0xA20020 BUMP MAP 0xA23021 REFLECTION MAP 0xA22022 [SUB CHUNKS FOR EACH MAP]23 MAPPING FILENAME 0xA30024 MAPPING PARAMETERS 0xA35125 KEYFRAMER CHUNK 0xB00026 MESH INFORMATION BLOCK 0xB00227 SPOT LIGHT INFORMATION BLOCK 0xB00728 FRAMES (START AND END) 0xB00829 OBJECT NAME 0xB01030 OBJECT PIVOT POINT 0xB01331 POSITION TRACK 0xB02032 ROTATION TRACK 0xB02133 SCALE TRACK 0xB02234 HIERARCHY POSITION 0xB030
实际上完整的chunk列表有上千种类型,我们只需解析其中的顶点列表、面列表和纹理UV列表就行了。
以类型标识为0x4D4D的MAIN CHUNK为例,整个3ds文件的前两个byte必须是0x4D4D,否则就说明这个文件不是3ds模型文件。然后从第3到第6个byte是一个Uint32型的数值,表示整个MAIN CHUNK的长度。由于MAIN CHUNK是整个3ds文件的根结点,它的长度也即整个3ds文件的长度。
块(Chunk)的结构
每一个“chunk”的结构如下所示:
偏移量
长度
0
2
块标识符
2
4
块长: 块数据 + 子块内容
6
n
块数据
6+n
m
S子块
读取的思路是:首先根据偏移量和长度找到一个块的标识符,然后据此来判断它是什么块,遇到我们需要的块,就进一步读取,如果不需要,直接跳过这一块,读取下面的块。
我们的解析器需要顶点、面和贴图UV信息,根据3ds模型文件的树状结构,可以找到需要解析的Chunk如下。
MAIN CHUNK
Identifier
0x4d4d
Length
0 + sub-chunks length
Chunk father
None
Sub chunks
3D EDITOR CHUNK
Data
None
3D EDITOR CHUNK
Identifier
0x3D3D
Length
0 + sub-chunks length
Chunk father
MAIN CHUNK
Sub chunks
OBJECT BLOCK, MATERIAL BLOCK, KEYFRAMER CHUNK
Data
None
OBJECT BLOCK
Identifier
0x4000
Length
Object name length + sub-chunks length
Chunk father
3D EDITOR CHUNK
Sub chunks
TRIANGULAR MESH, LIGHT, CAMERA
Data
Object name
TRIANGULAR MESH
Identifier
0x4100
Length
0 + sub-chunks length
Chunk father
OBJECT BLOCK
Sub chunks
VERTICES LIST, FACES DESCRIPTION, MAPPING COORDINATES LIST
Data
None
VERTICES LIST(点数据在这)
Identifier
0x4110
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
None
Data
Vertices number (unsigned short)
Vertices list: x1,y1,z1,x2,y2,z2 etc. (for each vertex: 3*float)
FACES DESCRIPTION(面数据在这)
Identifier
0x4120
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
FACES MATERIAL
Data
Polygons number (unsigned short)
Polygons list: a1,b1,c1,a2,b2,c2 etc. (for each point: 3*unsigned short)
Face flag: face options, sides visibility etc. (unsigned short)
MAPPING COORDINATES LIST(贴图数据在这)
Identifier
0x4140
Length
varying + sub-chunks length
Chunk father
TRIANGULAR MESH
Sub chunks
SMOOTHING GROUP LIST
Data
Vertices number (unsigned short)
Mapping coordinates list: u1,v1,u2,v2 etc. (for each vertex: 2*float)
据此给出Chunk的枚举类型
1 enum ChunkType 2 { 3 MainChunk = 0x4D4D, 4 _3DEditorChunk = 0x3D3D, 5 CVersion = 0x0002, 6 KeyFramerChunk = 0xB000, 7 MaterialBlock = 0xAFFF, 8 MaterialName = 0xA000, 9 AmbientColor = 0xA010,10 DiffuseColor = 0xA020,11 SpecularColor = 0xA030,12 C_MATSHININESS = 0xA040,13 TextureMap = 0xA200,14 MappingFilename = 0xA300,15 ObjectBlock = 0x4000,16 TriangularMesh = 0x4100,17 VerticesList = 0x4110,18 FacesDescription = 0x4120,19 FacesMaterial = 0x4130,20 MappingCoordinatesList = 0x414021 }
解析结果
解析结果为一个3dsFile类型的实例,它包含若干模型(称为entity)。每个entity都含有描述三维模型的顶点、面和贴图UV信息,据此我们用SharpGL来将其显示出来。
1 foreach (var entity in _3dsFile.Entities) 2 { 3 gl.Enable(OpenGL.GL_TEXTURE_2D); 4 gl.BindTextue(OpenGL.GL_TEXTURE_2D, this.texture.TextureName); 5 gl.Begin(SharpGL.Enumerations.BeginMode.Triangles); 6 foreach (var triangle in entity.indices) 7 { 8 var point1 = entity.vertices[triangle.vertex1]; 9 var uv1 = entity.texcoords[triangle.vertex1];10 gl.TexCoord(uv1.U, uv1.V);11 gl.Vertex(point1.X, point1.Y, point1.Z);12 var point2 = entity.vertices[triangle.vertex2];13 var uv2 = entity.texcoords[triangle.vertex2];14 gl.TexCoord(uv2.U, uv2.V);15 gl.Vertex(point2.X, point2.Y, point2.Z);16 var point3 = entity.vertices[triangle.vertex3];17 var uv3 = entity.texcoords[triangle.vertex3];18 gl.TexCoord(uv3.U, uv3.V);19 gl.Vertex(point3.X, point3.Y, point3.Z);20 }21 gl.End();22 }23 24
需要注意的一点是,SharpGL加载的贴图是上下反向的,所以你必须把准备好的贴图上下翻转,才能在SharpGL里正常使用。
说起来容易做起来难,需要源码的同学麻烦支持一下,捐款100元并留下你的Email等联系方式。您也可以在公告栏找到我的联系方式,任何不直接索要源码的交流都是欢迎的!
Thank you for your kindly donation!支付宝捐赠二维码:
Donate by alipay:
微信捐赠二维码:
Donate by microMsg:
- 自制C#版3DS文件的解析器并用SharpGL显示3DS模型
- 在程序中加载解析3DS文件,显示三维模型(c# MDX),
- 3DS模型解析的问题
- OpenGL 3ds模型显示
- OpenGL 3ds模型显示
- OpenGL 3ds模型显示
- OpenGL: 3ds模型显示
- 3DS文件解析(C++版)
- 3DS文件解析(JAVA版)
- 3DS文件解析(C++版)
- 3DS文件的结构
- 加载并显示3ds文件
- 3DS文件在OpenGL的读入和显示
- Qt下实现3DS文件的读入和显示
- 导入3ds模型的注意事项
- Qt+OpenGL 3ds模型的导入
- 读取3ds文件
- 读取3DS文件
- Mesos Nvidia GPU Support 翻译
- nginx静态资源服务器简单配置
- View工作原理(measure、layout、draw)
- Linux Namespaces机制
- (Unity3d)Vuforia开发基础三-模型替换
- 自制C#版3DS文件的解析器并用SharpGL显示3DS模型
- android 第三方分享图片
- 批量插入
- C++ TinyXML解析器中文说明
- java序列化
- [Extjs6] 修改默认的日期月份格式
- (Unity3d)Vuforia开发基础四-模型选定与控制
- 231. Power of Two
- 对一个二维数组中的数据排序,方法如下: 将整个数组中值最小的元素所在行调整为数组第一行, 将除第一行外的行中最小元素所在行调整为第2行, 将除第1,2行外的行中最小值元素所在行调整为第3行,以此类推