【问题标题】:How to capture current desktop efficiently and cross-platform in Unity3D?如何在 Unity3D 中高效跨平台捕获当前桌面?
【发布时间】:2014-11-24 06:51:21
【问题描述】:

我有一个用于 Oculus Rift 的简单 Unity3D 场景,并且想要添加向用户显示他自己的桌面的功能(从主显示器)。我发现我可以将它渲染到Texture2D,但是如何有效地捕获桌面?

实际上,我需要提供http://www.vrdesktop.net/ 之类的东西,它可以让用户在 VR 中看到他的显示器的内容。但我需要将它实现为 Unity3D 的库。那么最好的方法是什么?

附:最好有一个跨平台的解决方案,至少是 Windows 和 Linux/Mac。

【问题讨论】:

  • 桌面站是什么意思?您想要统一编辑器(或其他应用程序)的屏幕截图吗?你想要一个单眼版本的视图吗?另外:什么操作系统?

标签: unity3d oculus


【解决方案1】:

这个工作(至少适用于 Windows):

Texture2D tex = new Texture2D (200, 300, TextureFormat.RGB24, false);
Rectangle screenSize = System.Windows.Forms.Screen.PrimaryScreen.Bounds;
Bitmap target = new Bitmap (screenSize.Width, screenSize.Height);
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(target)) {
  g.CopyFromScreen (0, 0, 0, 0, new Size (screenSize.Width, screenSize.Height));
}
MemoryStream ms = new MemoryStream ();
target.Save (ms, ImageFormat.Png);
ms.Seek (0, SeekOrigin.Begin);

tex.LoadImage (ms.ToArray ());

renderer.material.mainTexture = tex;

但这里的效率值得怀疑 - 每一帧都转换为 PNG,另一方面,使用 CopyFromScreen 进行捕获工作正常。

(限制)正如 Mono 文档中所说:“适用于 Win32 和 X11(但不适用于 Cocoa 和 Quartz)”

【讨论】:

  • 可以尝试使用ImageFormat.MemoryBMPTextureFormat.RGB24
  • 已经尝试过了,但还是有点慢(对于大多数任务来说都很好,但对于视频来说不太好);也许有一种方法可以将实际指针传递给 tex,例如 Texture2d.UpdateExternalTexture (甚至可以获取 someSystem.Drawing.Graphics 对象的纹理)。
  • 有一个LoadRawTextureData,我知道将新像素数据放入纹理的最快方法。过去用它来加载DXT和PVR数据,应该也适用于RBG24。也可以使用GetNativeTexturePtr with a native plugin 将纹理复制到 GPU 上。
  • 嗯。我收到“UnityException:LoadRawTextureData:提供的数据不足(将导致过度读取)。”错误 - 即使 mipmap = false 和 MemoryBMP+RGB24
  • 快速清单: 1. 你设置了统一纹理的宽度/高度吗? 2. 检索到的纹理数据的字节大小是多少,是宽*高*3?如果是其他东西,那么它可能是 32 位 RGBA 或 16 位 RGB565。这可能取决于系统设置。
【解决方案2】:

我相信 Unity3D 没有这种功能。如果您希望能够与桌面交互,您将使用远程桌面软件。如果要获取桌面视图,可以使用屏幕捕获/录制软件。否则,您将不得不使用极其复杂或花哨的方法将其集成到 Unity 中。其中一位 cmets here 提供了很多信息。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
  • 2014-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多