用SharpDX9绘制立方体
acmilan2016/11/05软件综合 IP:四川

SharpDX是使用C#/XXXXXT编写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:

<code class="language-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(); // 响应事件
            }
        }
    }
}
</code>

Form1.cs:

<code class="language-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></code>

[修改于 7年5个月前 - 2016/11/06 20:04:20]

来自:计算机科学 / 软件综合
1
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan 作者
7年5个月前 修改于 7年5个月前 IP:陕西
827454
用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)(不再开发)
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
acmilan
进士 学者 笔友
文章
461
回复
2934
学术分
4
2009/05/30注册,5年2个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}