分享
 
 
 

DirectX9 3D 快速上手 4

王朝other·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

DirectX9 3D 快速上手 4

By sssa2000

4/17/2005

接下来我们要使用Mesh读入.X文件,关于.X文件,其实可以说很多,我们可以用外部的工具例如3DS MAX来建立.3ds文件,然后利用微软提供给我们的工具转换成.X文件,如果你同时会用3DS你也许会问,那材质怎么办? 你不用担心,.X文件能自动的包含材质,和动画,所以利用Mesh我们可以方便的八我们在3DS MAX的做品用在游戏中。

.X文件允许自定义的扩展,当然这个我们在以后的内容也会讲到,我们先看怎么使用,顺便提一句,还有一种用得比较多的文件格式.Md3格式的文件,也就是Quake3使用的文件,如果有机会我也会讲到。

关于3DS文件和.X转换可以参看GameRes网站的文章http://www.gameres.com/Articles/Program/Visual/3D/3DinApp.htm

接下来的过程简单的让你无法相信,请看:

private Mesh mesh = null; //建立Mesh对象

private Material[] meshMaterials; //用于保存材质

private Texture[] meshTextures; //用于保存纹理

private void LoadMesh(string file)

{

ExtendedMaterial[] mtrl; //保存Mesh子集信息,保存Material信息

// 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);

}

}

}

}

如果你觉得这里代码比较混乱,没有关系,我们来理一理,首先要说的是Mesh类还有两个主要的静态方法可以加载外部模型。这两个方法分别是Mesh.FormFile和Mesh.FromStream。两个方法本质上来说都是一样的,stream方法有更多的重载以适应不同大小的流。Mesh.FormFile最简单,我们就先只介绍这个,这个方法有很多重载的版本,我们用的是参数最多的一个,这样其他的也都好理解了:

public static Mesh FromFile(

string filename, //文件名

MeshFlags options,// 控制着去哪里以及如何加载数据

Device device,// 渲染mesh的device

out GraphicsStream adjacency,//保存每个面相邻的3个面

out ExtendedMaterial materials,// 保存了普通的Direct3D材质和一个加载为纹理的字符串,常是使用的纹理或资源文件名

out EffectInstance effects //描述了用于mesh的HLSL材质文件和值。

);

我们使用的是一个有4参数的方法:

public static Mesh FromFile(

string filename,

MeshFlags options,

Device device,

out ExtendedMaterial materials

);

接下来,如果读入的这个.X文件有材质或者纹理,就根据材质和纹理的大小建立数组以保存这些纹理和材质。因为mesh中可能有许多不同的子集,所以需要分别创建一个材质和纹理的数组以满足每一个子集的需要。Mesh会自动地把每一个子集和这些子集的材质纹理一一对座。

这样我们就完成了一个LoadMesh函数,这个函数我们可以用在以后任何需要读入.X文件的地方,十分的方便。

下面我们来看看我们的成果,当然我们还需要在绘图的地方加几句:

for (int i = 0; i < meshMaterials.Length; i++)

{

device.Material = meshMaterials[i];// 把保存的材质赋予device;

device.SetTexture(0, meshTextures[i]);// 把纹理赋予device,如果没有就为Null

mesh.DrawSubset(i);// 根据子集的ID调用DrawSubset方法

}

好了,现在我们可以在以往的框架的基础上编译一下了,我们可以看到已经读入了一个.X文件,不管怎么样 都是值得庆贺的。我们再看看SDK Tutorial6的例子后,发现这个程序的结果可以旋转,其实也很好实现,我们只需要设置一下旋转矩阵就可以了,就像上一张我们讲的那样,在上面那段for前面加上一句就可以了:

device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);

好了这样我们也就达到目的了,你也可以随自己的意思设置变换矩阵,很COOL吧?

好了,下面是完整的代码,如果大家有什么意见,发到我的blog上吧。大家一起进步。

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 Chapter5Code

{

/// <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");

}

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 SetupCamera()

{

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].Update();

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.01f;

device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);

for (int i = 0; i < meshMaterials.Length; i++)

{

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);

}

}

}

}

其实我们都已经发现,到目前为止我们的程序都是遵循一个固定的框架,有时候你发现程序很长,其实从框架角度来看,就没那么长了,怕看长代码的人可以注意一下,同时很多代码都是通用的。下次学习怎么操控Mesh。

By sssa2000

4/17/2005

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有