通过 D3DImage 的 SlimDX 和 WPF

发布于 2024-10-12 01:17:18 字数 3085 浏览 1 评论 0原文

我使用 SlimDX 和 WPF 编写了一些代码,我希望最终结果是红屏。

不幸的是我得到的只是黑屏。

这是在 Windows 7 上。

任何人都可以看到我缺少的任何主要内容吗?

我使用单独的表面作为 D3DImage 的后缓冲区的原因是我将需要多个视口。我认为渲染到单独的表面而不是设备初始后缓冲区将是实现这一目标的最佳方法。

无论如何,继续使用代码..

免责声明:请忽略错误的代码,这完全是作为一次性代码编写的,这样我就可以弄清楚如何实现我想要的目标。

这是我的窗口类:

namespace SlimDXWithWpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SlimDXRenderer controller;

        public MainWindow()
        {
            InitializeComponent();
            controller = new SlimDXRenderer();
            controller.Initialize();

            D3DImage image = new D3DImage();

            image.Lock();
            controller.RenderToSurface();
            image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, controller.SurfacePointer);
            image.AddDirtyRect(new Int32Rect(0, 0, image.PixelWidth, image.PixelHeight));            
            image.Unlock();

            Background = new ImageBrush(image);
        }
    }
}

这是我的“渲染器”类

namespace SlimDXWithWpf
{
    public class SlimDXRenderer : IDisposable
    {
        Direct3DEx directX;
        DeviceEx device;
        Surface surface;
        Surface backBuffer;
        IntPtr surfacePointer;

        public IntPtr SurfacePointer
        {
            get
            {
                return surfacePointer;
            }
        }

        public void Initialize()
        {
            directX = new Direct3DEx();

            HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, 640, 480, "SlimDXControl", IntPtr.Zero);

            PresentParameters pp = new PresentParameters()
            {
                BackBufferCount = 1,
                BackBufferFormat = Format.A8R8G8B8,
                BackBufferWidth = 640,
                BackBufferHeight = 480,
                DeviceWindowHandle = hwnd.Handle,
                PresentationInterval = PresentInterval.Immediate,
                Windowed = true,
                SwapEffect = SwapEffect.Discard              
            };



            device = new DeviceEx(directX, 0, DeviceType.Hardware, hwnd.Handle, CreateFlags.HardwareVertexProcessing, pp);
            backBuffer = device.GetRenderTarget(0); 

            surface = Surface.CreateRenderTarget(device, 1024, 768, Format.A8R8G8B8, MultisampleType.None, 1, false);
            surfacePointer = surface.ComPointer;            
        }

        public void RenderToSurface()
        {
            device.SetRenderTarget(0, surface);
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, new Color4(Color.Red), 0f, 0);
            device.BeginScene();            
            device.EndScene();                        
        }

        public void Dispose()
        {
            surface.Dispose();
            device.Dispose();
            directX.Dispose();
        }
    }
}

- 编辑:有一秒钟我以为我已经解决了它,但它似乎只有在我的第二个渲染目标(我试图清除红色的目标)时才起作用) 为 640x480。有什么想法吗?

I've written some code using SlimDX and WPF where I would expect the end result to be a red screen.

Unfortunately all I get is a black screen.

This is on windows 7.

Can anyone see anything major I'm missing?

The reason I'm using a separate surface as the backbuffer for the D3DImage is that I am going to be needing multiple viewports. I thought that rendering to seperate surfaces instead of the devices initial backbuffer would be the best way to achieve that.

anyway, on with the code..

Disclaimer: Please ignore the bad code, this is written entirely as throw-away code just so I can figure out how to do achieve what I'm after.

Here's my window class:

namespace SlimDXWithWpf
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        SlimDXRenderer controller;

        public MainWindow()
        {
            InitializeComponent();
            controller = new SlimDXRenderer();
            controller.Initialize();

            D3DImage image = new D3DImage();

            image.Lock();
            controller.RenderToSurface();
            image.SetBackBuffer(D3DResourceType.IDirect3DSurface9, controller.SurfacePointer);
            image.AddDirtyRect(new Int32Rect(0, 0, image.PixelWidth, image.PixelHeight));            
            image.Unlock();

            Background = new ImageBrush(image);
        }
    }
}

And heres my "renderer" class

namespace SlimDXWithWpf
{
    public class SlimDXRenderer : IDisposable
    {
        Direct3DEx directX;
        DeviceEx device;
        Surface surface;
        Surface backBuffer;
        IntPtr surfacePointer;

        public IntPtr SurfacePointer
        {
            get
            {
                return surfacePointer;
            }
        }

        public void Initialize()
        {
            directX = new Direct3DEx();

            HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, 640, 480, "SlimDXControl", IntPtr.Zero);

            PresentParameters pp = new PresentParameters()
            {
                BackBufferCount = 1,
                BackBufferFormat = Format.A8R8G8B8,
                BackBufferWidth = 640,
                BackBufferHeight = 480,
                DeviceWindowHandle = hwnd.Handle,
                PresentationInterval = PresentInterval.Immediate,
                Windowed = true,
                SwapEffect = SwapEffect.Discard              
            };



            device = new DeviceEx(directX, 0, DeviceType.Hardware, hwnd.Handle, CreateFlags.HardwareVertexProcessing, pp);
            backBuffer = device.GetRenderTarget(0); 

            surface = Surface.CreateRenderTarget(device, 1024, 768, Format.A8R8G8B8, MultisampleType.None, 1, false);
            surfacePointer = surface.ComPointer;            
        }

        public void RenderToSurface()
        {
            device.SetRenderTarget(0, surface);
            device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, new Color4(Color.Red), 0f, 0);
            device.BeginScene();            
            device.EndScene();                        
        }

        public void Dispose()
        {
            surface.Dispose();
            device.Dispose();
            directX.Dispose();
        }
    }
}

-- Edit: For a second I had thought I'd solved it, but it seems it will only work when my second render target (the one I'm trying to clear red) is 640x480. Any thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

荒岛晴空 2024-10-19 01:17:18

您的部分代码是否基于 SlimDX WPF 示例?看起来您可能有,这就是为什么您的 Clear() 调用使用 0.0f 作为 Z 清除值...这是我们示例中的一个错误。应该是1.0f。

除此之外,我看到的唯一潜在问题是表面渲染目标的大小与后台缓冲区的大小不同,但这实际上不会导致问题。您是否尝试过渲染到设备的后台缓冲区 (Device.GetBackBuffer()) 而不是新的表面,看看会产生什么影响?

Did you base some of this code on the SlimDX WPF sample? It looks like you might have, which is why your Clear() call is using 0.0f for the Z clear value... which is a bug in our sample. It should be 1.0f.

Beyond that, the only potential issue I see is that your surface render target is a different size than your back buffer, but that should not actually cause problems. Have you tried rendering to the device's backbuffer (Device.GetBackBuffer()) instead of a new surface to see what impact that has?

卖梦商人 2024-10-19 01:17:18

在 device.Clear 调用中,将第一个数字参数从 0f 更改为 1f。这是范围从 0 到 1 的 z 深度。指定 z 深度为 0 实际上不会执行任何操作。

In your device.Clear call, change the first numeric argument from 0f to 1f. That's the z-depth which ranges from 0 to 1. Specifying a z-depth of 0 effectively does nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文