You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

161 lines
4.8 KiB

// KlakSpout - Spout realtime video sharing plugin for Unity
// https://github.com/keijiro/KlakSpout
using UnityEngine;
namespace Klak.Spout
{
/// Spout receiver class
[AddComponentMenu("Klak/Spout/Spout Receiver")]
public class SpoutReceiver : MonoBehaviour
{
#region Editable properties
[SerializeField] string _nameFilter;
public string nameFilter {
get { return _nameFilter; }
set { _nameFilter = value; }
}
[SerializeField] RenderTexture _targetTexture;
public RenderTexture targetTexture {
get { return _targetTexture; }
set { _targetTexture = value; }
}
[SerializeField] Renderer _targetRenderer;
public Renderer targetRenderer {
get { return _targetRenderer; }
set { _targetRenderer = value; }
}
[SerializeField] string _targetMaterialProperty;
public string targetMaterialProperty {
get { return _targetMaterialProperty; }
set { targetMaterialProperty = value; }
}
#endregion
#region Public property
Texture2D _sharedTexture;
RenderTexture _fixedTexture;
public Texture receivedTexture {
get { return _targetTexture != null ? _targetTexture : _fixedTexture; }
}
#endregion
#region Private variables
System.IntPtr _receiver;
Material _fixupMaterial;
MaterialPropertyBlock _propertyBlock;
// Search the texture list and create a receiver when found one.
void SearchAndCreateTexture()
{
var name = PluginEntry.SearchSharedObjectNameString(_nameFilter);
if (name != null) _receiver = PluginEntry.CreateReceiver(name);
}
#endregion
#region MonoBehaviour functions
void Start()
{
_fixupMaterial = new Material(Shader.Find("Hidden/Spout/Fixup"));
_propertyBlock = new MaterialPropertyBlock();
// Initial search.
SearchAndCreateTexture();
}
void OnDestroy()
{
if (_receiver != System.IntPtr.Zero)
{
PluginEntry.DestroySharedObject(_receiver);
_receiver = System.IntPtr.Zero;
}
if (_sharedTexture != null)
{
Destroy(_sharedTexture);
_sharedTexture = null;
}
if (_fixedTexture != null)
{
Destroy(_fixedTexture);
_fixedTexture = null;
}
}
void Update()
{
PluginEntry.Poll();
if (_receiver == System.IntPtr.Zero)
{
// The receiver hasn't been set up yet; try to get one.
SearchAndCreateTexture();
}
else
{
// We've received textures via this receiver
// but now it's disconnected from the sender -> Destroy it.
if (PluginEntry.GetTexturePointer(_receiver) != System.IntPtr.Zero &&
PluginEntry.DetectDisconnection(_receiver))
{
OnDestroy();
}
}
if (_receiver != System.IntPtr.Zero)
{
if (_sharedTexture == null)
{
// Try to initialize the shared texture.
var ptr = PluginEntry.GetTexturePointer(_receiver);
if (ptr != System.IntPtr.Zero)
{
_sharedTexture = Texture2D.CreateExternalTexture(
PluginEntry.GetTextureWidth(_receiver),
PluginEntry.GetTextureHeight(_receiver),
TextureFormat.ARGB32, false, false, ptr
);
}
}
else
{
// Update external objects.
if (_targetTexture != null)
{
Graphics.Blit(_sharedTexture, _targetTexture, _fixupMaterial, 1);
}
else
{
if (_fixedTexture == null)
_fixedTexture = new RenderTexture(_sharedTexture.width, _sharedTexture.height, 0);
Graphics.Blit(_sharedTexture, _fixedTexture, _fixupMaterial, 1);
}
if (_targetRenderer != null)
{
_propertyBlock.SetTexture(_targetMaterialProperty, receivedTexture);
_targetRenderer.SetPropertyBlock(_propertyBlock);
}
}
}
}
#endregion
}
}