文号
827424
阅读
7544
回复
1
收藏
1
用SharpDX9绘制立方体
2016/11/05
IP:四川

SharpDX是使用C#/XXXXXX编写DirectX应用程序的第三方库。

编写DirectX 9.0程序一般使用SharpDX 2.6.3(更高版本只兼容.NET 4.5),建议配合VS2010+和DirectX SDK June 2010(或DirectX Redist June 2010)使用。

一个典型的示例——绘制一个立方体。

注意一个地方,DirectX是COM组件,用完别忘了Dispose()清理,否则程序结束时可能会报错。

sharpdx.png

Program.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace mysharpdx1
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            // 这里我们不使用Application.Run(new Form1());
            // 因为我们要实时渲染
            Form1 frm = new Form1(); // 创建主窗体
            frm.Show(); // 显示主窗体
            while (frm.Created) // 主窗体有效时
            {
                frm.Render(); // 实时渲染
                Application.DoEvents(); // 响应事件
            }
        }
    }
}

Form1.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpDX;
using SharpDX.Direct3D9;
using System.Runtime.InteropServices;
// 引用:
// SharpDX.dll
// SharpDX.Direct3D9.dll
// 附加:
// d3dx9_43.dll(DirectX Redist June 2010)

namespace mysharpdx1
{
    // 顶点缓冲区
    [StructLayout(LayoutKind.Sequential)]
    struct CubeVertex
    {
        public Vector3 Position;
        public ColorBGRA Color;
    }

    public partial class Form1 : Form
    {
        Direct3D d3d;
        Device device;
        VertexBuffer cube;
        IndexBuffer cubeindex;

        public Form1()
        {
            InitializeComponent();
        }

        // 创建需要使用的资源
        private void Form1_Load(object sender, EventArgs e)
        {
            // 修改客户区大小
            this.ClientSize = new Size(640, 480);

            // 创建Direct3D对象和Device对象
            d3d = new Direct3D();
            PresentParameters pp = new PresentParameters(this.ClientSize.Width, this.ClientSize.Height);
            pp.EnableAutoDepthStencil = true;
            device = new Device(d3d, 0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, pp);

            // 创建并填充顶点缓冲区
            cube = new VertexBuffer(device, 8 * 16, Usage.WriteOnly, VertexFormat.Position | VertexFormat.Diffuse, Pool.Default);
            cube.Lock(0, 0, LockFlags.None).WriteRange(new[] {
                new CubeVertex() { Position = new Vector3(0.5f, 0.5f, 0.5f), Color = SharpDX.Color.White },
                new CubeVertex() { Position = new Vector3(-0.5f, 0.5f, 0.5f), Color = SharpDX.Color.Magenta },
                new CubeVertex() { Position = new Vector3(-0.5f, -0.5f, 0.5f), Color = SharpDX.Color.White },
                new CubeVertex() { Position = new Vector3(0.5f, -0.5f, 0.5f), Color = SharpDX.Color.Blue },
                new CubeVertex() { Position = new Vector3(0.5f, 0.5f, -0.5f), Color = SharpDX.Color.Yellow },
                new CubeVertex() { Position = new Vector3(-0.5f, 0.5f, -0.5f), Color = SharpDX.Color.White },
                new CubeVertex() { Position = new Vector3(-0.5f, -0.5f, -0.5f), Color = SharpDX.Color.Cyan },
                new CubeVertex() { Position = new Vector3(0.5f, -0.5f, -0.5f), Color = SharpDX.Color.White },
            });
            cube.Unlock();
            
            // 创建并填充索引缓冲区,注意默认只显示顺时针绕行的三角面,剔除逆时针绕行的三角面
            cubeindex = new IndexBuffer(device, 12 * 3 * 2, Usage.WriteOnly, Pool.Default, true);
            cubeindex.Lock(0, 0, LockFlags.None).WriteRange(new short[] {
                0, 1, 2,
                0, 2, 3,
                0, 4, 5,
                0, 5, 1,
                0, 3, 7,
                0, 7, 4,
                4, 6, 5,
                4, 7, 6,
                1, 6, 2,
                1, 5, 6,
                3, 2, 6,
                3, 6, 7,
            });
            cubeindex.Unlock();

            // 关闭光照、设置背面剔除选项
            device.SetRenderState(RenderState.Lighting, false);
            //device.SetRenderState<cull>(RenderState.CullMode, Cull.Counterclockwise); // 默认值
        }

        // 实时渲染
        // 修改Main函数,消息循环:while (frm.Created) { frm.Render(); Application.DoEvents(); }
        public void Render()
        {
            // 清除后台缓冲区和深度缓冲区,开始场景
            device.Clear(ClearFlags.Target|ClearFlags.ZBuffer, new ColorBGRA(0x0000007F), 1.0f, 0);
            device.BeginScene();

            // 设置世界变换矩阵:沿着y轴旋转
            float angle = (float)(Environment.TickCount % 5000 / 5000.0f * Math.PI * 2);
            Matrix matWorld = Matrix.RotationY(angle);
            device.SetTransform(TransformState.World, matWorld);
            
            // 设置观察变换矩阵:基于左手系的,从(0,1,-2)点看(0,0,0)点且(0,1,0)为向上方向
            Matrix matView = Matrix.LookAtLH(
                new Vector3(0.0f, 1.0f, -2.0f),
                new Vector3(0.0f, 0.0f, 0.0f),
                new Vector3(0.0f, 1.0f, 0.0f)
                );
            device.SetTransform(TransformState.View, matView);
            
            // 设置投影变换矩阵:基于左手系的,y方向视角25度,宽高比640.0f/480.0f,近截面1.0f,远截面100.0f
            Matrix matProj;
            Matrix.PerspectiveFovLH(
                (float)Math.PI / 4.0f,
                640.0f / 480.0f,
                1.0f,
                100.0f,
                out matProj);
            device.SetTransform(TransformState.Projection, matProj);

            // 绘制立方体
            device.SetStreamSource(0, cube, 0, 16);
            device.Indices = cubeindex;
            device.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse;
            device.DrawIndexedPrimitive(PrimitiveType.TriangleList, 0, 0, 8, 0, 12);

            // 结束场景,将后台缓冲区提交到前台显示
            device.EndScene();
            device.Present();
        }

        // 清理资源
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (cubeindex != null) cubeindex.Dispose();
            if (cube != null) cube.Dispose();
            if (device != null) device.Dispose();
            if (d3d != null) d3d.Dispose();
        }
        
    }
}
</cull>
[ 修改于10年1个月前 - 2016/11/06 20:04:20 ]
acmilan作者
10年1个月前修改于 10年1个月前IP:陕西
827454
1楼
用C#编写DirectX有以下几种方案:
1、SharpDX(2.6.3或更早版本,源代码可自由使用)
2、SlimDX(2012版,源代码可自由使用)
3、C++/CLI & DirectX SDK June 2010(可以但是比较麻烦,注意新版编译器最低只能编译.NET4.0)

另外有一些方案,但它们已不再被支持
4、WindowsAPICodePack(共享源代码,不再开发)
5、Managed DirectX (DirectX SDK October 2006)(不再开发)
引用
评论
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的