SharpDx direct3d11如何开始渲染

时间:2017-02-20 11:02:24

标签: c# direct3d sharpdx direct3d11

我想在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
            }
}
}

1 个答案:

答案 0 :(得分:0)

一般来说,使用Direct3D之前,您需要大量的代码才能在屏幕上发生任何事情。

在SharpDX存储库中,您有MiniCube示例,其中包含足以让您真正开始使用的示例,因为它具有绘制3d场景所需的所有元素。

我建议特别寻找:

  • 深度缓冲区创建(DepthStencilView)
  • fx文件,因为你需要着色器在屏幕上有任何东西(没有更多的固定功能)
  • 如何创建顶点缓冲区,您需要以三角形分割几何体(通常情况下,还有其他可能性)。
  • 别忘了SetViewport(省略它很常见)
  • 引用输入汇编程序的调用是指定要绘制的几何
  • 常量缓冲区创建:这是传递矩阵和更改数据(如漫反射)
  • 还要确保将DeviceCreationFlags.None与Device.CreateWithSwapChain调用一起使用,并在visual studio调试选项中,使用&#34;启用本机代码调试&#34;。如果没有正确设置某些内容,这将给你错误和警告,加上一个有意义的理由,以防任何资源创建失败(而不是&#34;无效的Args&#34;,这是毫无意义的。)
  • 作为另一个建议,所有Direct3D11资源创建参数都非常容易出错且繁琐(许多选项彼此之间不兼容),因此将它们包装成一些更易于使用的辅助函数非常重要(并且要少量使用单元测试一次性验证它们。旧的Toolkit有很多这样的例子
  • SharpDX包装器与c ++对应物相对接近,因此c ++文档中的任何内容也适用于它。