标签:
上次开发结束,开发到在窗体中天剑一个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