C# 使用DirectX中的Device类实现3D渲染
1.Device类进行简单介绍
Device类把真实的图形卡从具体的硬件中抽象出来,在类中定义一组通用函数,这些函数将直接操作图形卡硬件。
函数原型:
(1)public Device(IntPtr unmanagedObject);
(2)public Device(int adapter, DeviceType deviceType, Control renderWindow, CreateFlags behaviorFlags, params PresentParameters[] presentationParameters);
(3)public Device(int adapter, DeviceType deviceType, IntPtr renderWindowHandle, CreateFlags behaviorFlags, params PresentParameters[] presentationParameters);
2.对第2个构造函数进行参数说明
public Device(int adapter, DeviceType deviceType, Control renderWindow, CreateFlags behaviorFlags, params PresentParameters[] presentationParameters)
参数简析:
adapter:表示要使用哪个图形卡,默认的图形卡为0。
deviceType:表示要创建的设备类型。
- DeviceType.Hardware,创建直接控制图形卡硬件的设备(要求图形卡支持DirectX)
- DeviceType.Reference,设备类型为参考光栅器,软件模拟,运行速度慢
- DeviceType.Software,自定义软件光栅器
renderWindow:表示在图形显示的窗口
behaviorFlags
- CreateFlags.SoftwareVertexProcessing,3D图形所有顶点计算用软件处理
- CreateFlags.HardwareVertexProcessing,所有顶点计算用GPU处理
- CreateFlags.MixedVertexProcessing,根据最佳效果原则,进行选择
以上互斥,只能选其一,可以与以下参数组合- FPU_Preserve,使用双精度浮点数计算,速度减慢
- MultiThreaded,使用多线程
- PureDevice,要求所有计算尽可能使用GPU,只能和CreateFlags.HardwareVertexProcessing
PresentParameters类常用属性:
- Windowed,false为全屏模式,true为窗口模式,使用Form类创建的Direct 3D程序,只能工作于窗口模式;
- SwapEffect,用于控制后备缓存区和屏幕显示区交换的方式;
- SwapEffect.Flip:在图形卡的显存中建立多个和屏幕显示区同样大小的后备缓存区,修改了后备缓存区的数据后,指定其为屏幕显示区,就可以显示,只使用全屏模式;
- SwapEffect.Copy:只有一个后备缓存区,为了显示,需要复制后备缓存区数据到屏幕显示区;
- SwapEffect.Discard:与SwapEffect.Copy基本相同,但新帧到来后,后备缓存区中未处理完的数据将被丢弃;
- BackBufferCount,后备缓存的数量(1到3) ;
- BackBufferFormat,记录颜色的格式;
- BackBufferWidth,每行单元数 BackBufferHeight,总行数 ;
- AutoDepthStencilFormat,指定深度缓存区单元的位数及格式,如DepthFormat.D16;
- EnableAutoDepthStencil,设置是否允许自动使用深度测试;
- DeviceWindowHandle,使用的窗口句柄,取值为null表示使用当前激活窗口。
C#窗体程序中使用DirectX进行3D渲染的示例程序:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace Demo_3D
{
public partial class MainFrm : Form
{
Device device = null;//定义绘图设备
public MainFrm()
{
InitializeComponent();
this.ClientSize = new Size(300, 300);//指定窗体尺寸
this.Text = "DirectX示例程序"; //指定窗体标题
}
public bool InitializeDirect3D()
{
try
{
PresentParameters presentParams = new PresentParameters();//定义对象
presentParams.Windowed = true; //指定以Windows窗体形式显示,使用Form类创建的Direct 3D程序,只能工作于窗口模式
presentParams.SwapEffect = SwapEffect.Discard; //当前屏幕绘制后它将自动从内存中删除
device = new Device(0, DeviceType.Hardware, this, CreateFlags.HardwareVertexProcessing, presentParams); //实例化device对象
return true;
}
catch (DirectXException e)
{
MessageBox.Show(e.ToString(), "Error"); //处理异常
return false;
}
}
public void Render()
{
if (device == null) //如果device为空则不渲染
{
return;
}
device.Clear(ClearFlags.Target, Color.DarkGreen, 1.0f, 0); //清除windows界面为深绿色
device.BeginScene();
//在此添加渲染图形代码
CustomVertex.TransformedColored[] vertices = new CustomVertex.TransformedColored[3]; //定义顶点
vertices[0].Position = new Vector4(10f, 300f, 1f, 1f);
vertices[0].Color = Color.Red.ToArgb();
vertices[1].Position = new Vector4(this.Width / 2, 50f, 0f, 1f);
vertices[1].Color = Color.Green.ToArgb();
vertices[2].Position = new Vector4(this.Width - 150f, 100f, 10f, 1f);
vertices[2].Color = Color.Blue.ToArgb();
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, vertices);
device.EndScene();
device.Present();
}
static void Main()
{
MainFrm basicForm = new MainFrm(); //创建窗体对象
if (basicForm.InitializeDirect3D() == false) //检查Direct3D是否启动
{
MessageBox.Show("无法启动Direct3D!", "Error");
return;
}
basicForm.Show(); //如果一切都初始化成功,则显示窗体
while (basicForm.Created) //设置一个循环用于实时更新渲染状态
{
basicForm.Render(); //保持device渲染,直到程序结束
Application.DoEvents(); //处理键盘鼠标等输入事件
}
}
}
}
参考Demo链接https://download.csdn.net/download/CXYLVCHF/14022457