134 lines
3.5 KiB
C#

using UnityEngine;
using UnityEngine.Rendering;
namespace Klak.Spout {
//
// Spout sender class (main implementation)
//
[ExecuteInEditMode]
[AddComponentMenu("Klak/Spout/Spout Sender")]
public sealed partial class SpoutSender : MonoBehaviour
{
#region Sender plugin object
Sender _sender;
void ReleaseSender()
{
_sender?.Dispose();
_sender = null;
}
#endregion
#region Buffer texture object
RenderTexture _buffer;
void PrepareBuffer(int width, int height)
{
// If the buffer exists but has wrong dimensions, destroy it first.
if (_buffer != null &&
(_buffer.width != width || _buffer.height != height))
{
ReleaseSender();
Utility.Destroy(_buffer);
_buffer = null;
}
// Create a buffer if it hasn't been allocated yet.
if (_buffer == null && width > 0 && height > 0)
{
_buffer = new RenderTexture(width, height, 0);
_buffer.hideFlags = HideFlags.DontSave;
_buffer.Create();
}
}
#endregion
#region Camera capture (SRP)
Camera _attachedCamera;
void OnCameraCapture(RenderTargetIdentifier source, CommandBuffer cb)
{
if (_attachedCamera == null) return;
Blitter.Blit(_resources, cb, source, _buffer, _keepAlpha);
}
void PrepareCameraCapture(Camera target)
{
// If it has been attached to another camera, detach it first.
if (_attachedCamera != null && _attachedCamera != target)
{
#if KLAK_SPOUT_HAS_SRP
CameraCaptureBridge
.RemoveCaptureAction(_attachedCamera, OnCameraCapture);
#endif
_attachedCamera = null;
}
// Attach to the target if it hasn't been attached yet.
if (_attachedCamera == null && target != null)
{
#if KLAK_SPOUT_HAS_SRP
CameraCaptureBridge
.AddCaptureAction(target, OnCameraCapture);
#endif
_attachedCamera = target;
}
}
#endregion
#region MonoBehaviour implementation
void OnDisable()
{
ReleaseSender();
PrepareBuffer(0, 0);
PrepareCameraCapture(null);
}
void Update()
{
// GameView capture mode
if (_captureMethod == CaptureMethod.GameView)
{
PrepareBuffer(Screen.width, Screen.height);
var temp = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);
ScreenCapture.CaptureScreenshotIntoRenderTexture(temp);
Blitter.BlitVFlip(_resources, temp, _buffer, _keepAlpha);
RenderTexture.ReleaseTemporary(temp);
}
// Texture capture mode
if (_captureMethod == CaptureMethod.Texture)
{
if (_sourceTexture == null) return;
PrepareBuffer(_sourceTexture.width, _sourceTexture.height);
Blitter.Blit(_resources, _sourceTexture, _buffer, _keepAlpha);
}
// Camera capture mode
if (_captureMethod == CaptureMethod.Camera)
{
PrepareCameraCapture(_sourceCamera);
if (_sourceCamera == null) return;
PrepareBuffer(_sourceCamera.pixelWidth, _sourceCamera.pixelHeight);
}
// Sender lazy initialization
if (_sender == null) _sender = new Sender(_spoutName, _buffer);
// Sender plugin-side update
_sender.Update();
}
#endregion
}
} // namespace Klak.Spout