// Copy the frame texture from GPU to CPU. private void CopyFrameTexture() { // Save original render texture RenderTexture prevTexture = RenderTexture.active; if (captureSource == CaptureSource.SCREEN) { RenderTexture.active = null; } else if (captureSource == CaptureSource.RENDERTEXTURE) { // Bind user input texture. RenderTexture.active = inputTexture; } else if (captureSource == CaptureSource.CAMERA) { if (stereoMode == StereoMode.NONE) { // Bind camera render texture. RenderTexture.active = outputTexture; } else { // Stereo cubemap capture not support. if (captureMode == CaptureMode._360 && projectionType == ProjectionType.CUBEMAP) { return; } BlitStereoTextures(); RenderTexture.active = stereoOutputTexture; } } // Enqueue frame texture Texture2D texture2D = Utils.CreateTexture(outputFrameWidth, outputFrameHeight, null); // TODO, using native plugin to avoid expensive step of copying pixel data from GPU to CPU. texture2D.ReadPixels(new Rect(0, 0, outputFrameWidth, outputFrameHeight), 0, 0, false); texture2D.Apply(); // Restore RenderTexture states. RenderTexture.active = prevTexture; StartCoroutine(EnqueueFrameTexture(texture2D)); }
private void updateTextureToNative() { EncoderStatus status; if ((inputTexture || outputTexture) && captureStarted) { if (captureSource == CaptureSource.RENDERTEXTURE) { // Passing input texture to GPUEncoder status = GPUEncoder_CaptureTexture(inputTexture.GetNativeTexturePtr()); } else if (stereoMode != StereoMode.NONE) { BlitStereoTextures(); // Passing render texture to GPUEncoder status = GPUEncoder_CaptureTexture(stereoOutputTexture.GetNativeTexturePtr()); } else { // Passing render texture to GPUEncoder status = GPUEncoder_CaptureTexture(outputTexture.GetNativeTexturePtr()); } if (status != EncoderStatus.OK) { OnError(EncoderErrorCode.TEXTURE_ENCODE_FAILED, status); StopCapture(); return; } } if ((inputTexture || outputTexture) && screenshotStarted) { screenshotStarted = false; if (captureSource == CaptureSource.RENDERTEXTURE) { // Passing input texture to GPUEncoder status = GPUEncoder_SaveScreenShot(inputTexture.GetNativeTexturePtr()); } else if (stereoMode != StereoMode.NONE) { BlitStereoTextures(); // Hack to fix first screensot image black Texture2D tempTexture = Utils.CreateTexture(1, 1, null); RenderTexture.active = stereoOutputTexture; tempTexture.ReadPixels(new Rect(0, 0, 1, 1), 0, 0, false); RenderTexture.active = null; Destroy(tempTexture); // Passing render texture to GPUEncoder status = GPUEncoder_SaveScreenShot(stereoOutputTexture.GetNativeTexturePtr()); } else { // Passing render texture to GPUEncoder status = GPUEncoder_SaveScreenShot(outputTexture.GetNativeTexturePtr()); } if (status != EncoderStatus.OK) { OnError(EncoderErrorCode.SCREENSHOT_FAILED, status); return; } else { OnComplete(screenshotSavePath); return; } } }
/// <summary> /// Create the RenderTexture for encoding texture /// </summary> private void CreateRenderTextures() { outputFrameWidth = inputTexture == null ? frameWidth : inputTexture.width; outputFrameHeight = inputTexture == null ? frameHeight : inputTexture.height; if (outputTexture != null && (outputFrameWidth != outputTexture.width || outputFrameHeight != outputTexture.height)) { if (outputTexture) { Destroy(outputTexture); outputTexture = null; } if (equirectTexture) { Destroy(equirectTexture); equirectTexture = null; } if (stereoEquirectTexture) { Destroy(stereoEquirectTexture); stereoEquirectTexture = null; } if (stereoTexture) { Destroy(stereoTexture); stereoTexture = null; } if (stereoOutputTexture) { Destroy(stereoOutputTexture); stereoOutputTexture = null; } if (texture2D) { Destroy(texture2D); texture2D = null; } } // Pixels stored in frameRenderTexture(RenderTexture) always read by frameTexture2D. texture2D = Utils.CreateTexture(outputFrameWidth, outputFrameHeight, texture2D); // Capture from user input texture if (inputTexture != null) { return; } // Create a RenderTexture with desired frame size for dedicated camera capture to store pixels in GPU. outputTexture = Utils.CreateRenderTexture(outputFrameWidth, outputFrameHeight, 24, antiAliasing, outputTexture); // For capturing normal 2D video, use frameTexture(Texture2D) for intermediate cpu saving, frameRenderTexture(RenderTexture) store the pixels read by frameTexture. if (captureMode == CaptureMode.REGULAR) { regularCamera.targetTexture = outputTexture; } // For capture panorama video: // EQUIRECTANGULAR: use cubemapTexture(RenderTexture) for intermediate cpu saving. // CUBEMAP: use texture2D for intermediate cpu saving. else if (captureMode == CaptureMode._360) { cubemapCamera.targetTexture = outputTexture; if (projectionType == ProjectionType.CUBEMAP) { CreateCubemapTextures(); } else { // Create equirectangular textures and materials. CreateEquirectTextures(); } } }
private void CaptureFrame() { string savePath = GetImageSavePath(imageIndex); imageIndex++; // Save original render texture RenderTexture prevTexture = RenderTexture.active; if (captureSource == CaptureSource.CAMERA) { // Mono capture if (stereoMode == StereoMode.NONE) { // Bind camera render texture. RenderTexture.active = outputTexture; } else // Stereo capture { // Stereo cubemap capture not support. if (captureMode == CaptureMode._360 && projectionType == ProjectionType.CUBEMAP) { return; } BlitStereoTextures(); RenderTexture.active = stereoOutputTexture; } } else if (captureSource == CaptureSource.RENDERTEXTURE) { // Bind user input texture. RenderTexture.active = inputTexture; } else if (captureSource == CaptureSource.SCREEN) { RenderTexture.active = null; } Texture2D texture2D = Utils.CreateTexture(outputFrameWidth, outputFrameHeight, null); // Read screen contents into the texture texture2D.ReadPixels(new Rect(0, 0, outputFrameWidth, outputFrameHeight), 0, 0); texture2D.Apply(); // Restore RenderTexture states. RenderTexture.active = prevTexture; // Encode image for write byte[] bytes; if (imageFormat == ImageFormat.PNG) { // Encode texture into PNG bytes = texture2D.EncodeToPNG(); } else { // Encode texture into JPG bytes = texture2D.EncodeToJPG(jpgQuality); } // Clean texture resources Destroy(texture2D); File.WriteAllBytes(savePath, bytes); }
private void CaptureFrame() { // Save original render texture RenderTexture prevTexture = RenderTexture.active; if (captureSource == CaptureSource.CAMERA) { // Mono capture if (stereoMode == StereoMode.NONE) { // Bind camera render texture. RenderTexture.active = outputTexture; } else // Stereo capture { // Stereo cubemap capture not support. if (captureMode == CaptureMode._360 && projectionType == ProjectionType.CUBEMAP) { return; } BlitStereoTextures(); RenderTexture.active = stereoOutputTexture; } } else if (captureSource == CaptureSource.RENDERTEXTURE) { // Bind user input texture. RenderTexture.active = inputTexture; } else if (captureSource == CaptureSource.SCREEN) { RenderTexture.active = null; } Texture2D texture2D = Utils.CreateTexture(outputFrameWidth, outputFrameHeight, null); // Read screen contents into the texture texture2D.ReadPixels(new Rect(0, 0, outputFrameWidth, outputFrameHeight), 0, 0); texture2D.Apply(); // Restore RenderTexture states. RenderTexture.active = prevTexture; // Encode image for write if (imageFormat == ImageFormat.PNG) { // Encode texture into PNG imageData = texture2D.EncodeToPNG(); } else { // Encode texture into JPG imageData = texture2D.EncodeToJPG(jpgQuality); } // Clean texture resources if (Application.isEditor) { DestroyImmediate(texture2D); } else { Destroy(texture2D); } // Reset camera settings. ResetCameraSettings(); }