SharpDx direct3d11如何开始渲染
SharpDx direct3d11 how to start rendering
我想在 C# 上使用 directx,我正在使用 SharpDX 包装器。我有一本名为 Direct3D 渲染指南的书,我从中获得了基本代码。我想创建一个 3d 世界视图。为此,我将需要一个相机视图和一个网格来帮助识别世界位置,就像在 Autodesk Maya 中一样,但我不知道该怎么做。我的想法很复杂,我应该怎么做才能开始?
这里我有代码可以渲染我认为的东西:
using System;
using SharpDX.Windows;
using SharpDX.DXGI;
using SharpDX.Direct3D11;
using Device = SharpDX.Direct3D11.Device;
using Device1 = SharpDX.Direct3D11.Device1;
namespace CurrencyConverter
{
static class Program
{[STAThread]
static void Main()
{
// Enable object tracking
SharpDX.Configuration.EnableObjectTracking = true;
SharpDX.Animation.Timer timer = new SharpDX.Animation.Timer();
#region Direct3D Initialization
// Create the window to render to
Form1 form = new Form1();
form.Text = "D3DRendering - EmptyProject";
form.Width = 640;
form.Height = 480;
// Declare the device and swapChain vars
Device device;
SwapChain swapChain;
// Create the device and swapchain
// First create a regular D3D11 device
using (var device11 = new Device(
SharpDX.Direct3D.DriverType.Hardware,
DeviceCreationFlags.None,
new[] {
SharpDX.Direct3D.FeatureLevel.Level_11_1,
SharpDX.Direct3D.FeatureLevel.Level_11_0,
}))
{
// Query device for the Device1 interface (ID3D11Device1)
device = device11.QueryInterfaceOrNull<Device1>();
if (device == null)
throw new NotSupportedException(
"SharpDX.Direct3D11.Device1 is not supported");
}// Rather than create a new DXGI Factory we reuse the
// one that has been used internally to create the device
using (var dxgi = device.QueryInterface<SharpDX.DXGI.Device2>())
using (var adapter = dxgi.Adapter)
using (var factory = adapter.GetParent<Factory2>())
{
var desc1 = new SwapChainDescription1()
{
Width = form.ClientSize.Width,
Height = form.ClientSize.Height,
Format = Format.R8G8B8A8_UNorm,
Stereo = false,
SampleDescription = new SampleDescription(1, 0),
Usage = Usage.BackBuffer | Usage.RenderTargetOutput,
BufferCount = 1,
Scaling = Scaling.Stretch,
SwapEffect = SwapEffect.Discard,
};
swapChain = new SwapChain1(factory,
device,
form.Handle,
ref desc1,
new SwapChainFullScreenDescription()
{
RefreshRate = new Rational(60, 1),
Scaling = DisplayModeScaling.Centered,
Windowed = true
},
// Restrict output to specific Output (monitor)
adapter.Outputs[0]);
}
// Create references for backBuffer and renderTargetView
var backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain,
0);
var renderTargetView = new RenderTargetView(device,
backBuffer);
#endregion
// Setup object debug names
device.DebugName = "The Device";
swapChain.DebugName = "The SwapChain";
backBuffer.DebugName = "The Backbuffer";
renderTargetView.DebugName = "The RenderTargetView";
#region Render loop
// Create and run the render loop
RenderLoop.Run(form, () =>
{
// Clear the render target with...
var lerpColor = SharpDX.Color.Lerp(SharpDX.Color.White,
SharpDX.Color.DarkBlue,
(float)((timer.Time) / 10.0 % 1.0));
device.ImmediateContext.ClearRenderTargetView(
renderTargetView,
lerpColor);
// Execute rendering commands here...
//...
//I DO NOT HAVE ANY IDEA
//...
// Present the frame
swapChain.Present(0, PresentFlags.RestrictToOutput);
});
#endregion
#region Direct3D Cleanup
// Release the device and any other resources created
renderTargetView.Dispose();
backBuffer.Dispose();
device.Dispose();
swapChain.Dispose();
#endregion
}
}
}
一般来说,对于 Direct3D,您需要大量代码才能在屏幕上显示任何内容。
在 SharpDX 存储库中,您有 MiniCube 示例,其中包含足以让您真正入门的示例,因为它包含绘制 3d 场景所需的所有元素。
我建议特别寻找:
- 深度缓冲区创建(DepthStencilView)
- fx 文件,因为你需要着色器在屏幕上显示任何内容(不再是固定功能)
- Vertex Buffer的创建方式,需要将几何图形分割成三角形(一般情况下还有其他可能)。
- 不要忘记 SetViewport(省略它很常见)
- 引用输入汇编器的调用正在分配要绘制的几何图形
- 常量缓冲区创建:这是为了传递矩阵和更改数据(如漫反射)
- 同时确保在 Device.CreateWithSwapChain 调用中使用 DeviceCreationFlags.None,并在 visual studio 调试选项中使用 "Enable Native Code Debugging"。如果某些设置不正确,这会给你错误和警告,加上一个有意义的原因,以防任何资源创建失败(而不是 "Invalid Args",这是毫无意义的)。
- 作为另一项建议,所有 Direct3D11 资源创建参数都非常容易出错且乏味(许多选项彼此之间不兼容),因此将它们包装到一些更易于使用的辅助函数中非常重要(并制作一个少量的单元测试来一劳永逸地验证它们)。旧的 Toolkit 有很多这样的例子
- SharpDX 包装器与 c++ 包装器相对接近,因此 c++ 文档中的任何内容也适用于它。
我想在 C# 上使用 directx,我正在使用 SharpDX 包装器。我有一本名为 Direct3D 渲染指南的书,我从中获得了基本代码。我想创建一个 3d 世界视图。为此,我将需要一个相机视图和一个网格来帮助识别世界位置,就像在 Autodesk Maya 中一样,但我不知道该怎么做。我的想法很复杂,我应该怎么做才能开始?
这里我有代码可以渲染我认为的东西:
using System;
using SharpDX.Windows;
using SharpDX.DXGI;
using SharpDX.Direct3D11;
using Device = SharpDX.Direct3D11.Device;
using Device1 = SharpDX.Direct3D11.Device1;
namespace CurrencyConverter
{
static class Program
{[STAThread]
static void Main()
{
// Enable object tracking
SharpDX.Configuration.EnableObjectTracking = true;
SharpDX.Animation.Timer timer = new SharpDX.Animation.Timer();
#region Direct3D Initialization
// Create the window to render to
Form1 form = new Form1();
form.Text = "D3DRendering - EmptyProject";
form.Width = 640;
form.Height = 480;
// Declare the device and swapChain vars
Device device;
SwapChain swapChain;
// Create the device and swapchain
// First create a regular D3D11 device
using (var device11 = new Device(
SharpDX.Direct3D.DriverType.Hardware,
DeviceCreationFlags.None,
new[] {
SharpDX.Direct3D.FeatureLevel.Level_11_1,
SharpDX.Direct3D.FeatureLevel.Level_11_0,
}))
{
// Query device for the Device1 interface (ID3D11Device1)
device = device11.QueryInterfaceOrNull<Device1>();
if (device == null)
throw new NotSupportedException(
"SharpDX.Direct3D11.Device1 is not supported");
}// Rather than create a new DXGI Factory we reuse the
// one that has been used internally to create the device
using (var dxgi = device.QueryInterface<SharpDX.DXGI.Device2>())
using (var adapter = dxgi.Adapter)
using (var factory = adapter.GetParent<Factory2>())
{
var desc1 = new SwapChainDescription1()
{
Width = form.ClientSize.Width,
Height = form.ClientSize.Height,
Format = Format.R8G8B8A8_UNorm,
Stereo = false,
SampleDescription = new SampleDescription(1, 0),
Usage = Usage.BackBuffer | Usage.RenderTargetOutput,
BufferCount = 1,
Scaling = Scaling.Stretch,
SwapEffect = SwapEffect.Discard,
};
swapChain = new SwapChain1(factory,
device,
form.Handle,
ref desc1,
new SwapChainFullScreenDescription()
{
RefreshRate = new Rational(60, 1),
Scaling = DisplayModeScaling.Centered,
Windowed = true
},
// Restrict output to specific Output (monitor)
adapter.Outputs[0]);
}
// Create references for backBuffer and renderTargetView
var backBuffer = Texture2D.FromSwapChain<Texture2D>(swapChain,
0);
var renderTargetView = new RenderTargetView(device,
backBuffer);
#endregion
// Setup object debug names
device.DebugName = "The Device";
swapChain.DebugName = "The SwapChain";
backBuffer.DebugName = "The Backbuffer";
renderTargetView.DebugName = "The RenderTargetView";
#region Render loop
// Create and run the render loop
RenderLoop.Run(form, () =>
{
// Clear the render target with...
var lerpColor = SharpDX.Color.Lerp(SharpDX.Color.White,
SharpDX.Color.DarkBlue,
(float)((timer.Time) / 10.0 % 1.0));
device.ImmediateContext.ClearRenderTargetView(
renderTargetView,
lerpColor);
// Execute rendering commands here...
//...
//I DO NOT HAVE ANY IDEA
//...
// Present the frame
swapChain.Present(0, PresentFlags.RestrictToOutput);
});
#endregion
#region Direct3D Cleanup
// Release the device and any other resources created
renderTargetView.Dispose();
backBuffer.Dispose();
device.Dispose();
swapChain.Dispose();
#endregion
}
}
}
一般来说,对于 Direct3D,您需要大量代码才能在屏幕上显示任何内容。
在 SharpDX 存储库中,您有 MiniCube 示例,其中包含足以让您真正入门的示例,因为它包含绘制 3d 场景所需的所有元素。
我建议特别寻找:
- 深度缓冲区创建(DepthStencilView)
- fx 文件,因为你需要着色器在屏幕上显示任何内容(不再是固定功能)
- Vertex Buffer的创建方式,需要将几何图形分割成三角形(一般情况下还有其他可能)。
- 不要忘记 SetViewport(省略它很常见)
- 引用输入汇编器的调用正在分配要绘制的几何图形
- 常量缓冲区创建:这是为了传递矩阵和更改数据(如漫反射)
- 同时确保在 Device.CreateWithSwapChain 调用中使用 DeviceCreationFlags.None,并在 visual studio 调试选项中使用 "Enable Native Code Debugging"。如果某些设置不正确,这会给你错误和警告,加上一个有意义的原因,以防任何资源创建失败(而不是 "Invalid Args",这是毫无意义的)。
- 作为另一项建议,所有 Direct3D11 资源创建参数都非常容易出错且乏味(许多选项彼此之间不兼容),因此将它们包装到一些更易于使用的辅助函数中非常重要(并制作一个少量的单元测试来一劳永逸地验证它们)。旧的 Toolkit 有很多这样的例子
- SharpDX 包装器与 c++ 包装器相对接近,因此 c++ 文档中的任何内容也适用于它。