同时在不同线程中使用GraphicsDevice

时间:2010-02-09 10:24:43

标签: c# xna

我有一个XNA应用程序渲染到第二个监视器(适配器1)上,它会定期自动截取并将其存储为Texture2D。

当此应用程序启动时,它还会显示带有面板的Windows窗体。该面板应该由单独的GraphicsDevice绘制,并显示Texture2D。

我遇到的问题是,当我在Windows窗体中运行此代码来创建GraphicsDevice时:

mainDevice = new GraphicsDevice(GraphicsAdapter.DefaultAdapter, DeviceType.Hardware, panel1.Handle, pp);

我收到DeviceLostException。在这种情况下的标准建议是捕获异常,让线程休眠几秒钟并重试,但这只会让我陷入无限循环。

我怀疑这是因为我的XNA类同时使用硬件而且我正在考虑错误的方法。但我找不到任何关于如何正确执行此操作的文档。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

如果我没有错,你试图同时使用两个不同的应用程序绘制两个不同的应用程序(或者更好的放置两个不同的GraphicsDevice对象)。

让我们先看看事情。

物理上你有一个Videocard和一个监视器。当然,大多数视频交互平台,如DirectX,OpenGL,XNA等主要在视频卡上执行,而不是处理器,对吗?

现在,在基于编程的概念中,我们有GraphicsDevice类和GraphicsAdapter类。敲响了铃声?

虽然GraphicsDevice与Videocart,GraphicsAdapter和监视器之间没有确切的关联,但这些对象之间存在非常密切的关系。

GraphicsDevice实际上并不代表Videocard(尽管Jeff以一种非常简单的方式表达它,使其易于理解)。 GraphicsDevice对象是Videocard的INTERACTOR。类似地,我们可以认为GraphicsDevice对象是一个绘画教师,它指示paintor(videocard)在哪里以及绘制什么。它旨在指导如何完成这些任务。

GraphicsAdapter与显示器的关系更近一些,因此我们将在类比中将其视为画布。

现在让我们看看。想象一下,我们的画家拥有与Videocard支持的GraphicsAdapter一样多的武器。这意味着它可以同时绘制尽可能多的画布。

以编程方式,我们可以为paintor及其画布实例化尽可能多的GraphicsDevice。每个教师都可以告诉画家在不同的画布上绘制不同的东西。但如果两位导师告诉他在同一幅画布上画出不同的东西,画家难道不会有点困惑吗?

当然会。画家一次只能在画布上执行绘画教学(当然,非常表面地看它,但足以理解这个概念)。这就是为什么你不能在同一个适配器上实例化和访问两个图形设备的原因。每当适配器更改其图形设备(讲师)时,另一个讲师就“丢失”。意思是,直到另一位教练完成,他没有注意到一段时间,无论教练告诉画家(比如,使用什么画笔,或画什么颜色)都被遗忘了。

因此,GraphicsDevice是一个“LostDevice”。因此,当您在适配器上绘制其他应用程序时,该视频卡和适配器的任何设备(最近创建或未创建)都将丢失,直到另一个应用程序释放实际设备(视频卡)。

只有一个GraphicsDevice可以同时在适配器上执行。

正如杰夫所说,在创建其他GraphicsDevice时使用另一个适配器(监视器)。另一个选项是如果您期望在同一台显示器上绘制,则协调两个应用程序的操作。 OTHER选项,是你把所有东西都放在窗口,因为当事情被“窗口化”时,操作系统拥有设备,这意味着它将是操作系统负责组合应用程序的绘图。 (问题,不是你的问题)

答案 1 :(得分:1)

GraphicsDevice是一个物理设备,而不是附加到窗口的东西。如果您有两个物理设备,则可以使用不同的GraphicsAdapter(意味着不是默认设置)来实例化另一个GraphicsDevice。

如果您不打算对设备施加太大负担,或者其中一个不需要大量硬件加速,则可以改为创建软件设备。功能可能类似,但速度会慢得多。

除此之外,我唯一能想到的就是看XNA是否支持命令缓冲区(我不确定它是什么)并自己管理锁定/解锁设备。

答案 2 :(得分:0)

我希望我错了,因为它会非常酷。但我不相信XNA API允许您使用双图形设备一次渲染到两个单独的监视器上。