134 lines
3.5 KiB
C#
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
|