解析3DS文件网上有好多代码,但我就只找到一个是C#写的,C#的太多资源仍然稀缺啊
http://www.nabble.com/3DS-File-loader-t1663534.html
它是用OpenGL显示的,我还得把它移植到MDX上来。
(C++写的解析显示3DS的代码,目前我只找到了几个opengl的,没找到directx的,如果你知道不要忘了告诉我啊)
还有许多细节上的问题…………
全部的源代码:http://bbs.gameres.com/showthread.asp?page=end&threadid=83967
代码仅Form1.cs是我写的,其他的是来自(http://www.nabble.com/3DS-File-loader-t1663534.html),仅有少许修改。
当前的显示还有一些问题,有一些三角形显示不出来,又有一些三角形是多余的,可是我的顶点和索引解析不会有问题呀,郁闷,期待大家一起帮忙完善。
Form1.cs
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace ThreeD
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
private Mesh mesh = null;
private Material[] meshMaterials;
private Texture[] meshTextures;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private float angle = 0.0f;
public Form1()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
}
/// <summary>
/// We will initialize our graphics device here
/// </summary>
public void InitializeGraphics()
{
// Set our presentation parameters
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
// Create our device
device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);
// Load our mesh
//LoadMesh(@"../../tiny.x");
//LoadD3S(@"E:/myprog/MeshFile/tpot.3ds");
LoadD3S(@"E:/myprog/box.3ds");
}
private void LoadMesh(string file)
{
ExtendedMaterial[] mtrl;
// Load our mesh
mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);
// If we have any materials, store them
if ((mtrl != null) && (mtrl.Length > 0))
{
meshMaterials = new Material[mtrl.Length];
meshTextures = new Texture[mtrl.Length];
// Store each material and texture
for (int i = 0; i < mtrl.Length; i++)
{
meshMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
{
// We have a texture, try to load it
meshTextures[i] = TextureLoader.FromFile(device, @"../../" + mtrl[i].TextureFilename);
}
}
}
}
private void LoadD3S(string file)
{
/*
* mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);
// If we have any materials, store them
if ((mtrl != null) && (mtrl.Length > 0))
{
meshMaterials = new Material[mtrl.Length];
meshTextures = new Texture[mtrl.Length];
// Store each material and texture
for (int i = 0; i < mtrl.Length; i++)
{
meshMaterials[i] = mtrl[i].Material3D;
if ((mtrl[i].TextureFilename != null) && (mtrl[i].TextureFilename != string.Empty))
{
// We have a texture, try to load it
meshTextures[i] = TextureLoader.FromFile(device, @"../../" + mtrl[i].TextureFilename);
}
}
}*/
ExtendedMaterial[] mtrl;
Model model = new ThreeDSFile(file).ThreeDSModel;
Entity e = model.Entities[0];
int numberVerts = e.vertices.Length;
mesh = new Mesh(numberVerts * 3, numberVerts, MeshFlags.Managed,
CustomVertex.PositionNormal.Format, device);
using (IndexBuffer ib = mesh.IndexBuffer)
{
ib.SetData(e.indices, 0, LockFlags.None);
}
using (VertexBuffer vb = mesh.VertexBuffer)
{
GraphicsStream data = vb.Lock(0, 0, LockFlags.None);
//for(int i2=0;i2<e.vertices.Length;i2++)
for(int i2=0;i2<numberVerts;i2++)
{
data.Write
(new CustomVertex.PositionNormal
(
(float)e.vertices[i2].X,(float)e.vertices[i2].Y, (float)e.vertices[i2].Z,
(float)e.normals[i2].X, (float)e.normals[i2].Y, (float)e.normals[i2].Z
)
);
}
vb.Unlock();
}
meshMaterials = new Material[1];
meshTextures = new Texture[1];
/*meshMaterials[0].Ambient = e.material.Ambient;
meshMaterials[0].Diffuse = e.material.Diffuse;
meshMaterials[0].Emissive = e.material.Shininess;
meshMaterials[0].Specular = e.material.Specular;
*/
meshMaterials[0].Ambient = Color.FromArgb((int)e.material.Ambient[0], (int)e.material.Ambient[1], (int)e.material.Ambient[2]);
meshMaterials[0].Diffuse = Color.FromArgb((int)e.material.Diffuse[0], (int)e.material.Diffuse[1], (int)e.material.Diffuse[2]);
//meshMaterials[0].Emissive = e.material.Shininess;
meshMaterials[0].Specular = Color.FromArgb((int)e.material.Specular[0], (int)e.material.Specular[1], (int)e.material.Specular[2]);
// Load our mesh
/*Model model = new ThreeDSFile(file).ThreeDSModel;
for (int i = 0; i < model.Entities.Count; i++)
{
Entity e = model.Entities[i];
for(int i2=0;i2<e.indices.Length;i2++)
{
e.indices[i2].vertex1;
}
};
model.Entities.
* */
}
private void SetupCamera()
{
device.RenderState.CullMode = Cull.None;
device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 10000.0f);
device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 580.0f), new Vector3(), new Vector3(0,1,0));
//device.RenderState.Ambient = Color.DarkBlue;
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Direction = new Vector3(0, -1, -1);
//device.Lights[0].Commit();
device.Lights[0].Enabled = true;
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);
SetupCamera();
device.BeginScene();
// Draw our Mesh
DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);
device.EndScene();
device.Present();
this.Invalidate();
}
private void DrawMesh(float yaw, float pitch, float roll, float x, float y, float z)
{
angle += 0.1f;
device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);
for (int i = 0; i < meshMaterials.Length; i++)
{
Material boxMaterial = new Material();
boxMaterial.Ambient = Color.White;
boxMaterial.Diffuse = Color.White;
device.Material = boxMaterial;
//device.Material = meshMaterials[i];
//device.SetTexture(0, meshTextures[i]);
mesh.DrawSubset(i);
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new Size(800,600);
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
using (Form1 frm = new Form1())
{
// Show our form and initialize our graphics engine
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
}
}