Skip to content

Instantly share code, notes, and snippets.

@NegishiTakumi
Last active June 23, 2016 03:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NegishiTakumi/69b165587fd71f4ab8a3 to your computer and use it in GitHub Desktop.
Save NegishiTakumi/69b165587fd71f4ab8a3 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.IO;
using System.Drawing;
using System.Runtime.InteropServices;
using ChangeDataToBytesFromImage;
using System.Threading;
using System.Threading.Tasks;
using SpicyPixel;
using SpicyPixel.Threading;
using SpicyPixel.Threading.Tasks;
using System.Windows.Forms;
public class DesktopDisplay : ConcurrentBehaviour
{
[DllImport("System.Drawing.dll")]
private static extern void Func();
public int ClipWidth = 1920;
public int ClipHeight = 1080;
public int TextureWidth = 1920;
public int TextureHeight = 1080;
private Material targetMaterial;
private Texture2D tex;
private Thread thread;
bool isThreadEnd = false;
public virtual void Awake()
{
base.Awake();
targetMaterial = GetComponent<Renderer>().material;
thread = new Thread(Thread1);
thread.Start();
}
void Thread1()
{
while (true)
{
Image img = GetCaptureImage(new Rectangle(0 ,0 , ClipWidth, ClipHeight));
var imageBytes = ChangeDataToBytesFromImage.ConvertImageData.ConvertImageToBytes(img);
img.Dispose();
taskFactory.StartNew(() => UpdateTexture(imageBytes));
if (isThreadEnd) break;
}
}
void UpdateTexture(byte[] imageBytes)
{
if (tex == null)
{
tex = new Texture2D(TextureWidth, TextureHeight);
}
tex.LoadImage(imageBytes);
targetMaterial.mainTexture = tex;
}
private Image GetCaptureImage(Rectangle rect)
{
// 指定された範囲と同サイズのBitmapを作成する
Image img = new Bitmap(
rect.Width,
rect.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
// Bitmapにデスクトップのイメージを描画する
using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img))
{
g.CopyFromScreen(
rect.X,
rect.Y,
0,
0,
rect.Size,
CopyPixelOperation.SourceCopy);
}
return img;
}
void OnApplicationQuit()
{
//Thread.Abortで何故かThreadが止まらないのでBool値によって無限ループを止める
isThreadEnd = true;
thread.Abort();
}
}
@NegishiTakumi
Copy link
Author

以下のURLの処理を軽量化
http://2vr.jp/2014/03/02/unity%E3%81%A7%E3%83%87%E3%82%B9%E3%82%AF%E3%83%88%E3%83%83%E3%83%971%E3%81%AE%E4%B8%80%E9%83%A8%E5%88%86%E3%82%92%E3%82%AF%E3%83%AA%E3%83%83%E3%83%94%E3%83%B3%E3%82%B0%E8%A1%A8%E7%A4%BA%E3%81%99/

変更点:
Image img = GetCaptureImage(new Rectangle(0, 0, ClipWidth, ClipHeight));
var imageBytes = ChangeDataToBytesFromImage.ConvertImageData.ConvertImageToBytes(img);
が重かったのでスレッド化。

ImageのByte列を生成してそこからTextureを生成するが、この処理はMainThread以外では扱えない。

そのため
別スレッドからUnity APIが呼べるアセット、Spicy Pixel Concurrency Kitを用いた。
(参考:http://posposi.blog.fc2.com/blog-entry-232.html)

解決!

@NegishiTakumi
Copy link
Author

従来の処理で1920*1080だとかなりカクカクしましたが、この処理にしてから現実的な速度になりました。
ただVR玄人が少し気になる程度にはカクつきます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment