private void CopyRenderTargetToTexture() { #if false // RJT TODO: If using D3D12 we need to read the current 'Display.main.colorBuffer', pass it down // to native and extract the texture using 'IUnityGraphicsD3D12v5::TextureFromRenderBuffer()' // - Although, as is, this doesn't work: https://forum.unity.com/threads/direct3d12-native-plugin-render-to-screen.733025/ if (_targetNativePointer == System.IntPtr.Zero) { _targetNativePointer = Display.main.colorBuffer.GetNativeRenderBufferPtr(); // _targetNativePointer = Graphics.activeColorBuffer.GetNativeRenderBufferPtr(); NativePlugin.SetColourBuffer(_handle, _targetNativePointer); } #endif #if true if ((_targetNativePointer == System.IntPtr.Zero) || (_resolveTexture && ((_resolveTexture.width != Screen.width) || (_resolveTexture.height != Screen.height))) ) { FreeRenderResources(); // Create RT matching screen extents _resolveTexture = RenderTexture.GetTemporary(Screen.width, Screen.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB, 1); _resolveTexture.Create(); _targetNativePointer = _resolveTexture.GetNativeTexturePtr(); NativePlugin.SetTexturePointer(_handle, _targetNativePointer); // Create command buffer _commandBuffer = new CommandBuffer(); _commandBuffer.name = "AVPro Movie Capture copy"; _commandBuffer.Blit(BuiltinRenderTextureType.CurrentActive, _resolveTexture); } #endif Graphics.ExecuteCommandBuffer(_commandBuffer); }
private void Capture() { TickFrameTimer(); AccumulateMotionBlur(); if (_capturing && !_paused) { if (_cubeTarget != null && _camera != null) { bool canGrab = true; if (IsUsingMotionBlur()) { // TODO: fix motion blur //this._motionBlur.RenderImage() // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab && CanOutputFrame()) { EncodeUnityAudio(); RenderTexture finalTexture = _finalTarget; if (!IsUsingMotionBlur()) { UpdateTexture(); } else { finalTexture = _motionBlur.FinalTexture; } if (_targetNativePointer == System.IntPtr.Zero || _supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = finalTexture.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); // ADG NOTE: Causes screen flickering under D3D12, even if we're not doing any rendering at native level // And also seems to cause GL.sRGBWrite to be set to false, which causes screen darkening in Linear mode if (SystemInfo.graphicsDeviceType != GraphicsDeviceType.Direct3D12) { GL.InvalidateState(); } UpdateFPS(); } } } RenormTimer(); }
public override void UnprepareCapture() { NativePlugin.SetTexturePointer(_handle, System.IntPtr.Zero); if (_target != null) { _target.DiscardContents(); } base.UnprepareCapture(); }
public override void UpdateFrame() { TickFrameTimer(); AccumulateMotionBlur(); if (_capturing && !_paused) { if (_settings.camera != null && _handle >= 0) { bool canGrab = true; if (IsUsingMotionBlur()) { // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab && CanOutputFrame()) { // Frame to encode either comes from rendering, or motion blur accumulation RenderTexture finalTexture = null; if (!IsUsingMotionBlur()) { RenderFrame(); finalTexture = _final; } else { finalTexture = _motionBlur.FinalTexture; } if (_targetNativePointer == System.IntPtr.Zero || _supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = finalTexture.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); GL.InvalidateState(); UpdateFPS(); } } } base.UpdateFrame(); RenormTimer(); }
public override void UnprepareCapture() { _targetNativePointer = System.IntPtr.Zero; NativePlugin.SetTexturePointer(_handle, System.IntPtr.Zero); if (_renderTexture != null) { RenderTexture.ReleaseTemporary(_renderTexture); _renderTexture = null; } base.UnprepareCapture(); }
public override void UnprepareCapture() { if (_handle != -1) { #if false NativePlugin.SetColourBuffer(_handle, System.IntPtr.Zero); #endif NativePlugin.SetTexturePointer(_handle, System.IntPtr.Zero); } FreeRenderResources(); if (_mouseCursor != null) { _mouseCursor.enabled = false; } base.UnprepareCapture(); }
public override void UpdateFrame() { TickFrameTimer(); AccumulateMotionBlur(); if (_capturing && !_paused) { if (_cubeTarget != null && _camera != null) { bool canGrab = true; if (IsUsingMotionBlur()) { // TODO: fix motion blur //this._motionBlur.RenderImage() // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab && CanOutputFrame()) { if (IsRecordingUnityAudio()) { int audioDataLength = 0; System.IntPtr audioDataPtr = _audioCapture.ReadData(out audioDataLength); if (audioDataLength > 0) { NativePlugin.EncodeAudio(_handle, audioDataPtr, (uint)audioDataLength); } } RenderTexture finalTexture = _finalTarget; if (!IsUsingMotionBlur()) { UpdateTexture(); } else { finalTexture = _motionBlur.FinalTexture; } if (_targetNativePointer == System.IntPtr.Zero || _supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = finalTexture.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); GL.InvalidateState(); UpdateFPS(); } } } base.UpdateFrame(); RenormTimer(); }
private void Capture() { TickFrameTimer(); AccumulateMotionBlur(); if (ShouldCaptureFrame()) { bool hasSourceTextureChanged = HasSourceTextureChanged(); // If motion blur is enabled, wait until all frames are accumulated if (IsUsingMotionBlur()) { // If the motion blur is still accumulating, don't grab this frame hasSourceTextureChanged = _motionBlur.IsFrameAccumulated; } _isSourceTextureChanged = false; if (hasSourceTextureChanged) { if ((_manualUpdate /*&& NativePlugin.IsNewFrameDue(_handle)*/) || CanOutputFrame()) { // If motion blur is enabled, use the motion blur result Texture sourceTexture = _sourceTexture; if (IsUsingMotionBlur()) { sourceTexture = _motionBlur.FinalTexture; } // If the texture isn't a RenderTexture then blit it to the Rendertexture so the native plugin can grab it if (!(sourceTexture is RenderTexture)) { _renderTexture.DiscardContents(); Graphics.Blit(sourceTexture, _renderTexture); sourceTexture = _renderTexture; } if (_targetNativePointer == System.IntPtr.Zero || _supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = sourceTexture.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); if (!IsUsingMotionBlur()) { _isSourceTextureChanged = false; } // Handle audio from Unity if (IsRecordingUnityAudio()) { int audioDataLength = 0; System.IntPtr audioDataPtr = _audioCapture.ReadData(out audioDataLength); if (audioDataLength > 0) { NativePlugin.EncodeAudio(_handle, audioDataPtr, (uint)audioDataLength); } } UpdateFPS(); } } } RenormTimer(); }
// If we're forcing a resolution or AA change then we have to render the camera again to the new target // If we try to just set the targetTexture of the camera and grab it in OnRenderImage we can't render it to the screen as before :( public override void UpdateFrame() { TickFrameTimer(); if (_capturing && !_paused && HasCamera()) { bool canGrab = true; if (IsUsingMotionBlur()) { // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab) { /*while (_handle >= 0 && !AVProMovieCapturePlugin.IsNewFrameDue(_handle)) * { * System.Threading.Thread.Sleep(1); * }*/ if (_handle >= 0 && CanOutputFrame()) { // Render the camera(s) if (!IsUsingMotionBlur()) { // Render a single camera if (!HasContributingCameras()) { RenderTexture prev = _lastCamera.targetTexture; // Reset the viewport rect as we're rendering to a texture captures the full viewport Rect prevRect = _lastCamera.rect; CameraClearFlags prevClear = _lastCamera.clearFlags; Color prevColor = _lastCamera.backgroundColor; bool clearChanged = false; if (_lastCamera.clearFlags == CameraClearFlags.Nothing || _lastCamera.clearFlags == CameraClearFlags.Depth) { clearChanged = true; _lastCamera.clearFlags = CameraClearFlags.SolidColor; if (!_supportAlpha) { _lastCamera.backgroundColor = Color.black; } else { _lastCamera.backgroundColor = new Color(0f, 0f, 0f, 0f); } } // Render _lastCamera.rect = new Rect(0f, 0f, 1f, 1f); _lastCamera.targetTexture = _target; _lastCamera.Render(); // Restore camera { _lastCamera.rect = prevRect; if (clearChanged) { _lastCamera.clearFlags = prevClear; _lastCamera.backgroundColor = prevColor; } _lastCamera.targetTexture = prev; } } // Render the camera chain else { // First render contributing cameras for (int cameraIndex = 0; cameraIndex < _contribCameras.Length; cameraIndex++) { Camera camera = _contribCameras[cameraIndex]; if (camera != null) { RenderTexture prev = camera.targetTexture; camera.targetTexture = _target; camera.Render(); camera.targetTexture = prev; } } // Finally render the last camera if (_lastCamera != null) { RenderTexture prev = _lastCamera.targetTexture; _lastCamera.targetTexture = _target; _lastCamera.Render(); _lastCamera.targetTexture = prev; } } } else { // Just grab the last result of the motion blur Graphics.Blit(_motionBlur.FinalTexture, _target); } if (_supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = _target.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); if (IsRecordingUnityAudio()) { int audioDataLength = 0; System.IntPtr audioDataPtr = _audioCapture.ReadData(out audioDataLength); if (audioDataLength > 0) { NativePlugin.EncodeAudio(_handle, audioDataPtr, (uint)audioDataLength); } } UpdateFPS(); } } } base.UpdateFrame(); RenormTimer(); }
// If we're forcing a resolution or AA change then we have to render the camera again to the new target // If we try to just set the targetTexture of the camera and grab it in OnRenderImage we can't render it to the screen as before :( public IEnumerator Capture() { TickFrameTimer(); if (_capturing && !_paused && HasCamera()) { bool canGrab = true; if (IsUsingMotionBlur()) { // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab) { /*while (_handle >= 0 && !AVProMovieCapturePlugin.IsNewFrameDue(_handle)) * { * System.Threading.Thread.Sleep(1); * }*/ if (_handle >= 0 && CanOutputFrame()) { RenderTexture sourceTexture = _target; // In 2018.3 and above a different method is used to render the gizmos etc, so we don't yet support capturing these #if SUPPORT_SCENE_VIEW_GIZMOS_CAPTURE // Support capturing the Scene View target texture directly so that we get all gizmo rendering if (_lastCamera != null && _includeSceneViewGizmos && (_lastCamera.hideFlags & HideFlags.NotEditable) != 0 && _lastCamera.targetTexture != null) { sourceTexture = _lastCamera.targetTexture; } #endif if (sourceTexture == _target) { // Render the camera(s) if (!IsUsingMotionBlur()) { UpdateTexture(); } else { // Just grab the last result of the motion blur _target.DiscardContents(); Graphics.Blit(_motionBlur.FinalTexture, _target); } } // If the texture isn't suitable then blit it to the Rendertexture so the native plugin can grab it if (RequiresResolve(sourceTexture)) { CreateResolveTexture(sourceTexture.width, sourceTexture.height); _resolveTexture.DiscardContents(); Graphics.Blit(sourceTexture, _resolveTexture); sourceTexture = _resolveTexture; } if (_supportTextureRecreate || _targetNativeTexture != sourceTexture) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = sourceTexture.GetNativeTexturePtr(); _targetNativeTexture = sourceTexture; } _previewTexture = sourceTexture; NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); EncodeUnityAudio(); UpdateFPS(); } } } base.UpdateFrame(); RenormTimer(); yield break; }
// If we're forcing a resolution or AA change then we have to render the camera again to the new target // If we try to just set the targetTexture of the camera and grab it in OnRenderImage we can't render it to the screen as before :( public override void UpdateFrame() { TickFrameTimer(); if (_capturing && !_paused && HasCamera()) { bool canGrab = true; if (IsUsingMotionBlur()) { // If the motion blur is still accumulating, don't grab this frame canGrab = _motionBlur.IsFrameAccumulated; } if (canGrab) { /*while (_handle >= 0 && !AVProMovieCapturePlugin.IsNewFrameDue(_handle)) * { * System.Threading.Thread.Sleep(1); * }*/ if (_handle >= 0 && CanOutputFrame()) { // Render the camera(s) if (!IsUsingMotionBlur()) { UpdateTexture(); } else { // Just grab the last result of the motion blur _target.DiscardContents(); Graphics.Blit(_motionBlur.FinalTexture, _target); } if (_supportTextureRecreate) { // NOTE: If support for captures to survive through alt-tab events, or window resizes where the GPU resources are recreated // is required, then this line is needed. It is very expensive though as it does a sync with the rendering thread. _targetNativePointer = _target.GetNativeTexturePtr(); } NativePlugin.SetTexturePointer(_handle, _targetNativePointer); RenderThreadEvent(NativePlugin.PluginEvent.CaptureFrameBuffer); if (IsRecordingUnityAudio()) { int audioDataLength = 0; System.IntPtr audioDataPtr = _audioCapture.ReadData(out audioDataLength); if (audioDataLength > 0) { NativePlugin.EncodeAudio(_handle, audioDataPtr, (uint)audioDataLength); } } UpdateFPS(); } } } base.UpdateFrame(); RenormTimer(); }