【问题标题】:Simultaneous GraphicsDevice's in different threads不同线程中的同时 GraphicsDevice
【发布时间】:2010-02-09 10:24:42
【问题描述】:

我有一个 XNA 应用程序,它呈现到第二个监视器(适配器 1)上,它会定期截取自身的屏幕截图并将其存储为 Texture2D。

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

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

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

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

我怀疑这是因为我的 XNA 课程同时使用了硬件,而我认为这是错误的方式。但我找不到任何关于我应该如何正确执行此操作的文档。

任何帮助将不胜感激。

【问题讨论】:

    标签: c# xna


    【解决方案1】:

    如果我没记错的话,您是在尝试使用两个不同的应用程序(或者,更好地说,两个不同的 GraphicsDevice 对象)同时在两个不同的显示器上绘图。

    让我们先正确看待事物。

    实际上,您有一个视频卡和一个监视器。当然,大多数视频交互平台,如 DirectX、OpenGL、XNA 等,主要是在显卡上执行的,而不是处理器,对吧?

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

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

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

    GraphicsAdapter 与监视器的关系更接近一点,因此我们将其视为类比中的画布。

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

    以编程方式,我们可以为画家及其画布实例化任意数量的 GraphicsDevice。每个教师都可以告诉画家在不同的画布上画不同的东西。但是如果两位老师告诉他在同一张画布上画不同的东西,画家会不会有点糊涂?

    当然会。画家一次只能在画布上执行绘画指令(当然,看起来很肤浅,但足以理解这个概念)。这就是为什么您不能在同一个适配器上实例化和访问两个图形设备的原因。每当适配器更改其图形设备(讲师)时,其他讲师就会“丢失”。意思是,在其他教练完成之前,他有一段时间没有受到关注,并且教练告诉画家的任何内容(例如,使用什么画笔,或者要画什么颜色)都会被遗忘。

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

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

    正如 Jeff 所说,在创建另一个 GraphicsDevice 时使用另一个适配器(监视器)。如果您希望在同一台显示器上绘图,另一种选择是协调两个应用程序的操作。另一个选项是您将所有内容都设置为窗口,因为当事物“窗口化”时,操作系统拥有设备,这意味着它将由操作系统负责组合应用程序的绘图。 (它的问题,不是你的)

    【讨论】:

      【解决方案2】:

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

      如果您不打算在设备上增加太多负载,或者其中一个不需要大量硬件加速,您可以创建一个软件设备。功能可能相似,但速度会慢很多。

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

      【讨论】:

        【解决方案3】:

        我希望我是错的,因为它会很酷。但我不相信 XNA API 允许您使用双图形设备一次在两个单独的显示器上进行渲染。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多