标签:
上次开发结束,开发到在窗体中天剑一个Panel控件,使得3d的效果图像在Panel中显示,今天我们继续向后面开发。
完成功能:简单载入3d模型
1.添加初始化图形设备
PresentParameters presentParams = new PresentParameters();//设置变量
设置其在窗口模式下运行,并将交换效果为Discard;创建设备。
2.导入3d模型函数
private void LoadMesh(string file) { ExtendedMaterial[] mtrl = null; //载入 try { mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl); //有材质的话,则载入 if ((mtrl != null) && (mtrl.Length > 0)) { //这两个就是前面定义的全局变量,保存材质和纹理 meshMaterials = new Material[mtrl.Length]; meshTextures = new Texture[mtrl.Length]; for (int i = 0; i < mtrl.Length; ++i) { /*当前的temp是Debug下的Model文件, *Model文件中有保存纹理和材质的文件 */ string temp = path + "\\Model\\"; meshMaterials[i] = mtrl[i].Material3D; if ((mtrl[i].TextureFilename != null) && mtrl[i].TextureFilename != string.Empty) { meshTextures[i] = TextureLoader.FromFile(device, temp + mtrl[i].TextureFilename); } } } } catch (Direct3DXException ex) { MessageBox.Show(ex.ToString()); return; } }
设置摄像头
private void SetupCamera() { //(float)Math.PI/12设置对象大小 device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 12, this.Width / this.Height, 0.80f, 10000.0f); device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 630.0f), new Vector3(), new Vector3(0, 1, 0)); device.RenderState.Ambient = Color.Black; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = Color.AntiqueWhite; device.Lights[0].Direction = new Vector3(0, 1, 0); device.Lights[0].Update(); device.Lights[0].Enabled = true; }
绘制mesh的材质和纹理
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); } }
最后在窗体界面中双击panel控件,加载private void panel1Paint(object sender, PaintEventArgs e)函数
private void panelPaint(object sender, PaintEventArgs e) { InitializeGraphics(); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0f, 1); SetupCamera(); device.Present(); 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(); //Render(); device.Present(); // this.Invalidate(); }
付上源代码及程序:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using Microsoft.DirectX; using Microsoft.DirectX.Direct3D; namespace _3dmodel { public partial class Form1 : Form { #region 全局变量 //保存3D文件 private Mesh mesh = null; //设备 private Device device = null; //材质 private Material[] meshMaterials; //纹理 private Texture[] meshTextures; //获取当前程序的Debug路径 string path = System.Windows.Forms.Application.StartupPath; //角度 private float angle = 0.0f; #endregion public Form1() { InitializeComponent();//asp.net自带且自动执行的初始化工作 } //初始化图形设备 public void InitializeGraphics() { //设置变量 PresentParameters presentParams = new PresentParameters(); //设置在窗口模式下运行 presentParams.Windowed = true; //设置交换效果为Discard presentParams.SwapEffect = SwapEffect.Discard; presentParams.AutoDepthStencilFormat = DepthFormat.D16; presentParams.EnableAutoDepthStencil = true; //创建设备 device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing, presentParams); //我的3D文件在Debug中的Model文件中,因此temp获取了3D模型的地址 string temp = path; temp = temp + "\\Model\\Model.X"; //这个函数用于载入3D模型并且保存在mesh中 LoadMesh(temp); } private void LoadMesh(string file) { ExtendedMaterial[] mtrl = null; //载入 try { mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl); //有材质的话,则载入 if ((mtrl != null) && (mtrl.Length > 0)) { //这两个就是前面定义的全局变量,保存材质和纹理 meshMaterials = new Material[mtrl.Length]; meshTextures = new Texture[mtrl.Length]; for (int i = 0; i < mtrl.Length; ++i) { /*当前的temp是Debug下的Model文件, *Model文件中有保存纹理和材质的文件 */ string temp = path + "\\Model\\"; meshMaterials[i] = mtrl[i].Material3D; if ((mtrl[i].TextureFilename != null) && mtrl[i].TextureFilename != string.Empty) { meshTextures[i] = TextureLoader.FromFile(device, temp + mtrl[i].TextureFilename); } } } } catch (Direct3DXException ex) { MessageBox.Show(ex.ToString()); return; } } //设置摄像头 private void SetupCamera() { //(float)Math.PI/12设置对象大小 device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 12, this.Width / this.Height, 0.80f, 10000.0f); device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 630.0f), new Vector3(), new Vector3(0, 1, 0)); device.RenderState.Ambient = Color.Black; device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = Color.AntiqueWhite; device.Lights[0].Direction = new Vector3(0, 1, 0); device.Lights[0].Update(); device.Lights[0].Enabled = true; } //绘制mesh的材质和纹理 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); } } private void Render() { if (device == null) return; device.Clear(ClearFlags.Target, System.Drawing.Color.Black, 1.0f, 0); SetupCamera(); device.BeginScene(); Material boxMaterial = new Material(); boxMaterial.Ambient = Color.Pink; boxMaterial.Diffuse = Color.White; device.Material = boxMaterial; device.Transform.World = Matrix.Translation(0, 50, 0); device.Transform.World = Matrix.Identity; mesh.DrawSubset(0); device.EndScene(); device.Present(); } private void Form1_Load(object sender, EventArgs e) { } private void panel1_Paint(object sender, PaintEventArgs e) { InitializeGraphics(); device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0f, 1); SetupCamera(); device.Present(); 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(); //Render(); device.Present(); // this.Invalidate(); } } }
程序编译过程中或许会遇到一个问题:
混合模式程序集是针对“v1.1.4322”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
这个问题解决办法就是打开文件中的app.config文件,注释掉原来的内容,改成以下内容:
<?xml version="1.0"?> <configuration> <startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v4.0"/> </startup> </configuration>
标签:
原文地址:http://www.cnblogs.com/licongzhuo/p/5841324.html