|
|
|
|
|
/*
|
|
|
|
|
|
* Spout4Unity
|
|
|
|
|
|
* Copyright © 2014-2015 Benjamin Kuperberg
|
|
|
|
|
|
* Copyright © 2015 Stefan Schlupek
|
|
|
|
|
|
* All rights reserved
|
|
|
|
|
|
*/
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Spout
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
[ExecuteInEditMode]
|
|
|
|
|
|
public class Spout : MonoBehaviour
|
|
|
|
|
|
{
|
|
|
|
|
|
#region public
|
|
|
|
|
|
public event EventHandler<TextureShareEventArgs> OnSenderStopped;
|
|
|
|
|
|
public event Action OnEnabled;
|
|
|
|
|
|
public event Action OnAllSendersStopped;
|
|
|
|
|
|
|
|
|
|
|
|
public delegate void TextureSharedDelegate(TextureInfo texInfo);
|
|
|
|
|
|
public TextureSharedDelegate texSharedDelegate;
|
|
|
|
|
|
public delegate void SenderStoppedDelegate(TextureInfo texInfo);
|
|
|
|
|
|
public SenderStoppedDelegate senderStoppedDelegate;
|
|
|
|
|
|
|
|
|
|
|
|
public List<TextureInfo> activeSenders;
|
|
|
|
|
|
public List<TextureInfo> activeLocalSenders;
|
|
|
|
|
|
public HashSet<string> localSenderNames;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static bool isInit
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _isInit; }
|
|
|
|
|
|
}
|
|
|
|
|
|
public static bool isEnabledInEditor
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
return _instance == null ? false : _instance._isEnabledInEditor;
|
|
|
|
|
|
//return _isEnabledInEditor;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//You can use a fakeName of your choice .It's just to force an update in the Spout Receiver at start even if the 'offical' sharingName doesn't change.
|
|
|
|
|
|
public static string fakeName = "SpoutIsSuperCoolAndMakesFun";
|
|
|
|
|
|
|
|
|
|
|
|
public enum TextureFormat { DXGI_FORMAT_R32G32B32A32_FLOAT = 2, DXGI_FORMAT_R10G10B10A2_UNORM = 24, DXGI_FORMAT_R8G8B8A8_UNORM = 28, DXGI_FORMAT_B8G8R8A8_UNORM = 87 }
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
#region private
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private IntPtr intptr_senderUpdate_delegate;
|
|
|
|
|
|
private IntPtr intptr_senderStarted_delegate;
|
|
|
|
|
|
private IntPtr intptr_senderStopped_delegate;
|
|
|
|
|
|
|
|
|
|
|
|
// Use GCHandle to hold the delegate object in memory.
|
|
|
|
|
|
private GCHandle handleSenderUpdate;
|
|
|
|
|
|
private GCHandle handleSenderStarted;
|
|
|
|
|
|
private GCHandle handleSenderStopped;
|
|
|
|
|
|
|
|
|
|
|
|
#pragma warning disable 414
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private static bool _isInit;
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private bool _isEnabledInEditor;
|
|
|
|
|
|
#pragma warning restore 414
|
|
|
|
|
|
private static bool isReceiving;
|
|
|
|
|
|
|
|
|
|
|
|
private List<TextureInfo> newSenders;
|
|
|
|
|
|
private List<TextureInfo> stoppedSenders;
|
|
|
|
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private static Spout _instance;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#pragma warning disable 414
|
|
|
|
|
|
//In EditMode we have to force the camera to render.But as this is called 100 times per second beware of your performance, so we only render at a special interval
|
|
|
|
|
|
private int _editorUpdateFrameInterval = 3;
|
|
|
|
|
|
#pragma warning restore 414
|
|
|
|
|
|
|
|
|
|
|
|
private int _frameCounter;
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
[SerializeField]
|
|
|
|
|
|
private static Texture2D _nullTexture;
|
|
|
|
|
|
public static Texture2D nullTexture
|
|
|
|
|
|
{
|
|
|
|
|
|
get { return _nullTexture; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static Spout instance
|
|
|
|
|
|
{
|
|
|
|
|
|
get
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_instance == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_instance = GameObject.FindObjectOfType<Spout>();
|
|
|
|
|
|
if (_instance == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
GameObject _go = new GameObject("Spout");
|
|
|
|
|
|
_instance = _go.AddComponent<Spout>();
|
|
|
|
|
|
}
|
|
|
|
|
|
//DontDestroyOnLoad(_instance.gameObject);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _instance;
|
|
|
|
|
|
}
|
|
|
|
|
|
private set { _instance = value; }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
public void Awake()
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("Spout.Awake");
|
|
|
|
|
|
|
|
|
|
|
|
if (_instance != null && _instance != this)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout.Awake.Destroy");
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
DestroyImmediate(this.gameObject);
|
|
|
|
|
|
#else
|
|
|
|
|
|
Destroy(this.gameObject);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
newSenders = new List<TextureInfo>();
|
|
|
|
|
|
stoppedSenders = new List<TextureInfo>();
|
|
|
|
|
|
activeSenders = new List<TextureInfo>();
|
|
|
|
|
|
activeLocalSenders = new List<TextureInfo>();
|
|
|
|
|
|
localSenderNames = new HashSet<string>();
|
|
|
|
|
|
|
|
|
|
|
|
_nullTexture = new Texture2D(32, 32);
|
|
|
|
|
|
_nullTexture.hideFlags = HideFlags.HideAndDontSave;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
public void OnEnable()
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout.OnEnable");
|
|
|
|
|
|
if (_instance != null && _instance != this)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout.OnEnable.Destroy");
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
DestroyImmediate(this.gameObject);
|
|
|
|
|
|
#else
|
|
|
|
|
|
Destroy(this.gameObject);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
newSenders = new List<TextureInfo>();
|
|
|
|
|
|
stoppedSenders = new List<TextureInfo>();
|
|
|
|
|
|
activeSenders = new List<TextureInfo>();
|
|
|
|
|
|
activeLocalSenders = new List<TextureInfo>();
|
|
|
|
|
|
localSenderNames = new HashSet<string>();
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
if (_isEnabledInEditor || Application.isPlaying)
|
|
|
|
|
|
{
|
|
|
|
|
|
_Enable();
|
|
|
|
|
|
}
|
|
|
|
|
|
#else
|
|
|
|
|
|
_Enable();
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _Enable()
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout._Enable");
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
|
|
|
|
|
|
if (!Application.isPlaying)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnityEditor.EditorApplication.update -= _Update;
|
|
|
|
|
|
UnityEditor.EditorApplication.update += _Update;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_Init();
|
|
|
|
|
|
//notify others so they can re-initialize
|
|
|
|
|
|
if (OnEnabled != null) OnEnabled();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _Disable()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _Init()
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout._Init");
|
|
|
|
|
|
|
|
|
|
|
|
initNative();
|
|
|
|
|
|
//Debug.Log("isReceiving:+"+isReceiving);
|
|
|
|
|
|
|
|
|
|
|
|
_startReceiving();
|
|
|
|
|
|
_isInit = true;
|
|
|
|
|
|
//if(debug) initDebugConsole();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Update()
|
|
|
|
|
|
{
|
|
|
|
|
|
//if(_instance == null || _instance != this ) return;
|
|
|
|
|
|
|
|
|
|
|
|
_Update();
|
|
|
|
|
|
}
|
|
|
|
|
|
private void _Update()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
_frameCounter++;
|
|
|
|
|
|
_frameCounter %= _editorUpdateFrameInterval;
|
|
|
|
|
|
if (_frameCounter == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
UnityEditor.SceneView.RepaintAll();
|
|
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (isReceiving)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("checkReceivers");
|
|
|
|
|
|
checkReceivers();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
lock (this)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (TextureInfo s in newSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("texSharedDelegate");
|
|
|
|
|
|
activeSenders.Add(s);
|
|
|
|
|
|
if (texSharedDelegate != null) texSharedDelegate(s);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
newSenders.Clear();
|
|
|
|
|
|
|
|
|
|
|
|
foreach (TextureInfo s in stoppedSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (TextureInfo t in activeSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (s.name == t.name)
|
|
|
|
|
|
{
|
|
|
|
|
|
activeSenders.Remove(t);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Debug.Log ("Stopped sender from Spout :"+s.name);
|
|
|
|
|
|
if (senderStoppedDelegate != null) senderStoppedDelegate(s);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stoppedSenders.Clear();
|
|
|
|
|
|
}//lock
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void OnDisable()
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout.OnDisable");
|
|
|
|
|
|
if (_instance != this) return;
|
|
|
|
|
|
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
UnityEditor.EditorApplication.update -= _Update;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
StopAllLocalSenders();
|
|
|
|
|
|
//Force the Plugin to check. Otherwise we don't get a SenderStopped delegate call
|
|
|
|
|
|
Update();
|
|
|
|
|
|
|
|
|
|
|
|
//Debug.Log("Spout.OnDisable.End");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnDestroy()
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Spout.OnDestroy");
|
|
|
|
|
|
if (_instance != this) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (_isInit)
|
|
|
|
|
|
{
|
|
|
|
|
|
_CleanUpResources();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
isReceiving = false;
|
|
|
|
|
|
_isInit = false;
|
|
|
|
|
|
newSenders = null;
|
|
|
|
|
|
stoppedSenders = null;
|
|
|
|
|
|
activeSenders = null;
|
|
|
|
|
|
activeLocalSenders = null;
|
|
|
|
|
|
localSenderNames = null;
|
|
|
|
|
|
|
|
|
|
|
|
OnEnabled = null;
|
|
|
|
|
|
OnSenderStopped = null;
|
|
|
|
|
|
|
|
|
|
|
|
_instance = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GC.Collect();//??
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void _CleanUpResources()
|
|
|
|
|
|
{
|
|
|
|
|
|
clean();
|
|
|
|
|
|
|
|
|
|
|
|
_instance.texSharedDelegate = null;
|
|
|
|
|
|
_instance.senderStoppedDelegate = null;
|
|
|
|
|
|
|
|
|
|
|
|
_instance.handleSenderUpdate.Free();
|
|
|
|
|
|
_instance.handleSenderStarted.Free();
|
|
|
|
|
|
_instance.handleSenderStopped.Free();
|
|
|
|
|
|
|
|
|
|
|
|
intptr_senderUpdate_delegate = IntPtr.Zero;
|
|
|
|
|
|
intptr_senderStarted_delegate = IntPtr.Zero;
|
|
|
|
|
|
intptr_senderStopped_delegate = IntPtr.Zero;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void addListener(TextureSharedDelegate sharedCallback, SenderStoppedDelegate stoppedCallback)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Debug.Log ("Spout.addListener");
|
|
|
|
|
|
if (_instance == null) return;
|
|
|
|
|
|
_instance.texSharedDelegate += sharedCallback;
|
|
|
|
|
|
_instance.senderStoppedDelegate += stoppedCallback;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void removeListener(TextureSharedDelegate sharedCallback, SenderStoppedDelegate stoppedCallback)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Debug.Log ("Spout.removeListener");
|
|
|
|
|
|
if (_instance == null) return;
|
|
|
|
|
|
_instance.texSharedDelegate -= sharedCallback;
|
|
|
|
|
|
_instance.senderStoppedDelegate -= stoppedCallback;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool CreateSender(string sharingName, Texture tex, int texFormat = 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!enabled) return false;
|
|
|
|
|
|
if (!_isInit) return false;
|
|
|
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
|
if (!Application.isPlaying && !_isEnabledInEditor) return false;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
IntPtr p_tex = tex.GetNativeTexturePtr();
|
|
|
|
|
|
if (p_tex == IntPtr.Zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("[WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING]");
|
|
|
|
|
|
Debug.Log("Spout.UpdateSender:" + sharingName + " NativeTexturePtr is NULL !!!");
|
|
|
|
|
|
Debug.Log("[WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING]");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Debug.Log("Spout.CreateSender:" + sharingName + "::" + p_tex.ToInt32());
|
|
|
|
|
|
bool result = createSenderNative(sharingName, p_tex, texFormat);
|
|
|
|
|
|
if (result)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log (String.Format("Spout sender creation with name {0} success !",sharingName));
|
|
|
|
|
|
localSenderNames.Add(sharingName);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.LogWarning(String.Format("createSenderNative(): Spout sender creation with name {0} failed !", sharingName));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public bool UpdateSender(string sharingName, Texture tex)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (enabled == false || gameObject.activeInHierarchy == false || _isInit == false) return false;
|
|
|
|
|
|
//Debug.Log("Spout.UpdateSender:"+sharingName+"::"+tex.GetNativeTexturePtr().ToInt32());
|
|
|
|
|
|
IntPtr p_tex = tex.GetNativeTexturePtr();
|
|
|
|
|
|
if (p_tex == IntPtr.Zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("[WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING]");
|
|
|
|
|
|
Debug.Log("Spout.UpdateSender:" + sharingName + " NativeTexturePtr is NULL !!!");
|
|
|
|
|
|
Debug.Log("[WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING]");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return updateSenderNative(sharingName, p_tex);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public TextureInfo getTextureInfo(string sharingName)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (activeSenders == null) return null;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (TextureInfo tex in activeSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (tex.name == sharingName) return tex;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (sharingName != Spout.fakeName) Debug.Log(String.Format("sharing name {0} not found", sharingName));
|
|
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private const string SpoutVersion = "2_006";
|
|
|
|
|
|
private const string SpoutLibNameBase = "NativeSpoutPlugin";
|
|
|
|
|
|
private const string SpoutLibName = SpoutLibNameBase + "_" + SpoutVersion;
|
|
|
|
|
|
#if DEVELOPMENT_BUILD
|
|
|
|
|
|
public const string SpoutLibImport = SpoutLibName + "_Debug";
|
|
|
|
|
|
#else
|
|
|
|
|
|
public const string SpoutLibImport = SpoutLibName;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//Imports
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "init")]
|
|
|
|
|
|
public static extern bool initNative();
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "initDebugConsole")]
|
|
|
|
|
|
private static extern void _initDebugConsole();
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport)]
|
|
|
|
|
|
private static extern void checkReceivers();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "createSender")]
|
|
|
|
|
|
private static extern bool createSenderNative(string sharingName, IntPtr texture, int texFormat);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "updateSender")]
|
|
|
|
|
|
private static extern bool updateSenderNative(string sharingName, IntPtr texture);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "closeSender")]
|
|
|
|
|
|
public static extern bool CloseSender(string sharingName);
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport)]
|
|
|
|
|
|
private static extern void clean();
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport(SpoutLibImport, EntryPoint = "startReceiving")]
|
|
|
|
|
|
private static extern bool startReceivingNative(IntPtr senderUpdateHandler, IntPtr senderStartedHandler, IntPtr senderStoppedHandler);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
|
|
public delegate void SpoutSenderUpdateDelegate(int numSenders);
|
|
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
|
|
public delegate void SpoutSenderStartedDelegate(string senderName, IntPtr resourceView, int textureWidth, int textureHeight);
|
|
|
|
|
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
|
|
|
|
public delegate void SpoutSenderStoppedDelegate(string senderName);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void initDebugConsole()
|
|
|
|
|
|
{
|
|
|
|
|
|
//check if multiple inits?
|
|
|
|
|
|
_initDebugConsole();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void _startReceiving()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isReceiving) return;
|
|
|
|
|
|
//Debug.Log("Spout.startReceiving");
|
|
|
|
|
|
SpoutSenderUpdateDelegate senderUpdate_delegate = new SpoutSenderUpdateDelegate(SenderUpdate);
|
|
|
|
|
|
handleSenderUpdate = GCHandle.Alloc(senderUpdate_delegate);
|
|
|
|
|
|
intptr_senderUpdate_delegate = Marshal.GetFunctionPointerForDelegate(senderUpdate_delegate);
|
|
|
|
|
|
|
|
|
|
|
|
SpoutSenderStartedDelegate senderStarted_delegate = new SpoutSenderStartedDelegate(SenderStarted);
|
|
|
|
|
|
handleSenderStarted = GCHandle.Alloc(senderStarted_delegate);
|
|
|
|
|
|
intptr_senderStarted_delegate = Marshal.GetFunctionPointerForDelegate(senderStarted_delegate);
|
|
|
|
|
|
|
|
|
|
|
|
SpoutSenderStoppedDelegate senderStopped_delegate = new SpoutSenderStoppedDelegate(SenderStopped);
|
|
|
|
|
|
handleSenderStopped = GCHandle.Alloc(senderStopped_delegate);
|
|
|
|
|
|
intptr_senderStopped_delegate = Marshal.GetFunctionPointerForDelegate(senderStopped_delegate);
|
|
|
|
|
|
|
|
|
|
|
|
isReceiving = startReceivingNative(intptr_senderUpdate_delegate, intptr_senderStarted_delegate, intptr_senderStopped_delegate);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SenderUpdate(int numSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
//Debug.Log("Sender update, numSenders : "+numSenders);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void SenderStarted(string senderName, IntPtr resourceView, int textureWidth, int textureHeight)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("Spout. Sender started, sender name : " + senderName);
|
|
|
|
|
|
if (_instance == null || _instance.activeLocalSenders == null || _instance.newSenders == null) return;
|
|
|
|
|
|
lock (this)
|
|
|
|
|
|
{
|
|
|
|
|
|
TextureInfo texInfo = new TextureInfo(senderName);
|
|
|
|
|
|
Debug.Log("resourceView:" + resourceView.ToInt32());
|
|
|
|
|
|
texInfo.setInfos(textureWidth, textureHeight, resourceView);
|
|
|
|
|
|
_instance.newSenders.Add(texInfo);
|
|
|
|
|
|
if (_instance.localSenderNames.Contains(texInfo.name))
|
|
|
|
|
|
{
|
|
|
|
|
|
_instance.activeLocalSenders.Add(texInfo);
|
|
|
|
|
|
//Debug.Log("activeLocalSenders.count:"+_instance.activeLocalSenders.Count);
|
|
|
|
|
|
}
|
|
|
|
|
|
Debug.Log("Spout.SenderStarted.End");
|
|
|
|
|
|
}//lock
|
|
|
|
|
|
}
|
|
|
|
|
|
private void SenderStopped(string senderName)
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("Sender stopped, sender name : " + senderName);
|
|
|
|
|
|
if (_instance == null || _instance.activeLocalSenders == null || _instance.stoppedSenders == null) return;
|
|
|
|
|
|
lock (this)
|
|
|
|
|
|
{
|
|
|
|
|
|
TextureInfo texInfo = new TextureInfo(senderName);
|
|
|
|
|
|
|
|
|
|
|
|
_instance.stoppedSenders.Add(texInfo);
|
|
|
|
|
|
|
|
|
|
|
|
_instance.localSenderNames.Remove(texInfo.name);
|
|
|
|
|
|
|
|
|
|
|
|
if (_instance.activeLocalSenders.Contains(texInfo))
|
|
|
|
|
|
{
|
|
|
|
|
|
_instance.activeLocalSenders.Remove(texInfo);
|
|
|
|
|
|
}
|
|
|
|
|
|
}//lock
|
|
|
|
|
|
//Debug.Log("localSenderNames.count:"+instance.localSenderNames.Count);
|
|
|
|
|
|
//Debug.Log("activeLocalSenders.count:"+instance.activeLocalSenders.Count);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void StopAllLocalSenders()
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
Debug.Log("Spout.StopAllLocalSenders()");
|
|
|
|
|
|
if (_instance == null) return;
|
|
|
|
|
|
foreach (TextureInfo t in _instance.activeLocalSenders)
|
|
|
|
|
|
{
|
|
|
|
|
|
CloseSender(t.name);
|
|
|
|
|
|
if (OnSenderStopped != null) OnSenderStopped(this, new TextureShareEventArgs(t.name));
|
|
|
|
|
|
/*
|
|
|
|
|
|
double i = 0;
|
|
|
|
|
|
while(i< 100000000){
|
|
|
|
|
|
i++;
|
|
|
|
|
|
}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (OnAllSendersStopped != null) OnAllSendersStopped();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public class TextureShareEventArgs : EventArgs
|
|
|
|
|
|
{
|
|
|
|
|
|
public string sharingName { get; set; }
|
|
|
|
|
|
|
|
|
|
|
|
public TextureShareEventArgs(string myString)
|
|
|
|
|
|
{
|
|
|
|
|
|
this.sharingName = myString;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|