C#使用DirectX SDK 加载.x三维模型

最近因为项目要做显示一个三维模型,所以研究了下如何在Winform中加载并显示三维模型。在Windows平台巨硬公司提供了DirectX SDK用于渲染图形,参考了几篇文章做了个demo记录下,以便日后温习只用。这个SDK涉及到了计算机图形学的一些基础知识,需要掌握一点基础,推荐可以看看OpenGL初学手册。

创建项目

我们开始返回正题,首先使用Visual Studio 2019创建一个Winform项目,然后添加DirectX 三个dll库的引用,路径是:C:\Windows\Microsoft.NET\DirectX for Managed Code\1.0.2902.0, 主要是前3个dll,后面的可用可不用。

添加控件

通过工具箱添加timer和panel控件,panel用于显示三位模型(也可不添加这个,直接用form显示),timer用于实时渲染。

 代码实现
/*--------成员变量声明-----------*/
//设备
private Device device;
//显示参数
private PresentParameters pres;
//保存3D文件
private Mesh mesh;
//渲染材质
private Material[] materials;
private Texture[] textures;


/*--------方法实现-----------*/
public bool InitializeGraphics()
{
    pres = new PresentParameters();
    pres.Windowed = true;
    pres.SwapEffect = SwapEffect.Discard;
    pres.EnableAutoDepthStencil = true;
    pres.AutoDepthStencilFormat = DepthFormat.D16;
    device = new Device(0, DeviceType.Hardware, panel1, CreateFlags.SoftwareVertexProcessing,
      pres);
    device.RenderState.CullMode = Cull.None;
    CreateMesh(@"airplane 2.x");
    //CreateMesh(@"lobby_skybox.x");
    return true;
}
public void CreateMesh(string path)
{
    ExtendedMaterial[] exMaterials;
    mesh = Mesh.FromFile(path, MeshFlags.SystemMemory, device, out exMaterials);
    if (textures != null)
    {
        DisposeTextures();
    }
    textures = new Texture[exMaterials.Length];
    materials = new Material[exMaterials.Length];
    for (int i = 0; i< exMaterials.Length; ++i)
    {
        if (exMaterials[i].TextureFilename != null)
        {
            string texturePath = Path.Combine(Path.GetDirectoryName(path), exMaterials[i].TextureFilename);
            textures[i] = TextureLoader.FromFile(device, texturePath);
        }
        materials[i] = exMaterials[i].Material3D;
        materials[i].Ambient = materials[i].Diffuse;
    }
}
public void DisposeTextures()
{
    if (textures == null)
    {
        return;
    }
    foreach (Texture t in textures)
    {
        if (t != null)
        {
            t.Dispose();
        }
    }
}

public void SetupMatrices()
{
    float yaw = Environment.TickCount / 500.0F;
    float pitch = Environment.TickCount / 500.0F;
    device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, 0);
    device.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, -6), new Vector3(0, 0, 0), new Vector3(0, 1, 0));
    device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 2.0F, 1.0F, 1.0F, 10.0F);
}

public void SetupLights()
{
    device.RenderState.Lighting = true;
    device.Lights[0].Diffuse = Color.White;
    device.Lights[0].Specular = Color.White;
    device.Lights[0].Type = LightType.Directional;
    device.Lights[0].Direction = new Vector3(-1, -1, 3);
    device.Lights[0].Enabled = true;
    device.RenderState.Ambient = Color.FromArgb(0x00, 0x00, 0x00);
}

public void RenderMesh()
{
    for (int i = 0; i< materials.Length; ++i)
    {
        if (textures[i] != null)
        {
            device.SetTexture(0, textures[i]);
        }
        device.Material = materials[i];
        mesh.DrawSubset(i);
    }
}

public void Render()
{
    device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.SkyBlue, 1.0F, 0);
    device.BeginScene();
    SetupMatrices();
    SetupLights();
    RenderMesh();
    device.EndScene();
    device.Present();
}

public void DisposeGraphics()
{
    DisposeTextures();
    device.Dispose();
}
渲染实现

在Form1_Load事件中调用初始化函数,然后在timer的timer1_Tick事件中调用Render函数实时渲染

private void Form1_Load(object sender, EventArgs e)
{
    InitializeGraphics();
}

private void timer1_Tick(object sender, EventArgs e)
{
    Render();
}

 编译程序,编译之前设置32位模式,需要自己新建一个32位的编译模式

准备素材

需要安装为微软的DirectX SDK,链接: https://www.microsoft.com/zh-cn/download/details.aspx?id=6812

到这个路径下C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Samples\Media\Airplane复制三个资源文件到本地的的exe文件目录 RobotSimulator\DirectX3D\bin\x86\Debug

运行程序

PS:

 如遇“托管调试助手 “LoaderLock”报错“Message=托管调试助手 “LoaderLock”:“正尝试在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。””,可以快捷键Ctrl+Alt+E,改动Managed Debuggin Assistants->LoaderLock 的选中状态去掉。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值