Search code examples
unity-game-engineoculus

How to capture current desktop efficiently and cross-platform in Unity3D?


I have a simple Unity3D-scene for Oculus Rift and want to add ability to show his own desktop to a user(from main monitor). I've found that I can render it to a Texture2D, but how to efficiently capture a desktop?

Actually, I need to provide something like http://www.vrdesktop.net/, which allows to the user see his monitor's content inside VR. But I need to implement this as a library for Unity3D. So what is the best way to do that?

P.S. It would be nice to have a cross-platform solution, at least Windows and Linux/Mac.


Solution

  • This one works (at least for 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;
    

    But efficiency is questionable here - every frame is converted to PNG, on the other hand capturing with CopyFromScreen works fine.

    (Limitations) As it said in the Mono documentation: "Works on Win32 and on X11 (but not on Cocoa and Quartz)"