ore untangling
This commit is contained in:
180
apps/LoopThroughWithOpenGLCompositing/gl/RenderEngine.cpp
Normal file
180
apps/LoopThroughWithOpenGLCompositing/gl/RenderEngine.cpp
Normal file
@@ -0,0 +1,180 @@
|
||||
#include "RenderEngine.h"
|
||||
|
||||
#include <gl/gl.h>
|
||||
|
||||
RenderEngine::RenderEngine(
|
||||
RuntimeHost& runtimeHost,
|
||||
RuntimeSnapshotProvider& runtimeSnapshotProvider,
|
||||
CRITICAL_SECTION& mutex,
|
||||
HDC hdc,
|
||||
HGLRC hglrc,
|
||||
RenderEffectCallback renderEffect,
|
||||
ScreenshotCallback screenshotReady,
|
||||
PreviewPaintCallback previewPaint) :
|
||||
mRenderer(),
|
||||
mRenderPass(mRenderer),
|
||||
mRenderPipeline(mRenderer, runtimeHost, std::move(renderEffect), std::move(screenshotReady), std::move(previewPaint)),
|
||||
mShaderPrograms(mRenderer, runtimeHost, runtimeSnapshotProvider),
|
||||
mMutex(mutex),
|
||||
mHdc(hdc),
|
||||
mHglrc(hglrc)
|
||||
{
|
||||
}
|
||||
|
||||
RenderEngine::~RenderEngine()
|
||||
{
|
||||
mRenderer.DestroyResources();
|
||||
}
|
||||
|
||||
bool RenderEngine::CompileDecodeShader(int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
return mShaderPrograms.CompileDecodeShader(errorMessageSize, errorMessage);
|
||||
}
|
||||
|
||||
bool RenderEngine::CompileOutputPackShader(int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
return mShaderPrograms.CompileOutputPackShader(errorMessageSize, errorMessage);
|
||||
}
|
||||
|
||||
bool RenderEngine::InitializeResources(
|
||||
unsigned inputFrameWidth,
|
||||
unsigned inputFrameHeight,
|
||||
unsigned captureTextureWidth,
|
||||
unsigned outputFrameWidth,
|
||||
unsigned outputFrameHeight,
|
||||
unsigned outputPackTextureWidth,
|
||||
std::string& error)
|
||||
{
|
||||
return mRenderer.InitializeResources(
|
||||
inputFrameWidth,
|
||||
inputFrameHeight,
|
||||
captureTextureWidth,
|
||||
outputFrameWidth,
|
||||
outputFrameHeight,
|
||||
outputPackTextureWidth,
|
||||
error);
|
||||
}
|
||||
|
||||
bool RenderEngine::CompileLayerPrograms(unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
return mShaderPrograms.CompileLayerPrograms(inputFrameWidth, inputFrameHeight, errorMessageSize, errorMessage);
|
||||
}
|
||||
|
||||
bool RenderEngine::CommitPreparedLayerPrograms(const PreparedShaderBuild& preparedBuild, unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
return mShaderPrograms.CommitPreparedLayerPrograms(preparedBuild, inputFrameWidth, inputFrameHeight, errorMessageSize, errorMessage);
|
||||
}
|
||||
|
||||
const std::vector<RuntimeRenderState>& RenderEngine::CommittedLayerStates() const
|
||||
{
|
||||
return mShaderPrograms.CommittedLayerStates();
|
||||
}
|
||||
|
||||
void RenderEngine::ResetTemporalHistoryState()
|
||||
{
|
||||
mShaderPrograms.ResetTemporalHistoryState();
|
||||
}
|
||||
|
||||
void RenderEngine::ResetShaderFeedbackState()
|
||||
{
|
||||
mShaderPrograms.ResetShaderFeedbackState();
|
||||
}
|
||||
|
||||
void RenderEngine::ResizeView(int width, int height)
|
||||
{
|
||||
mRenderer.ResizeView(width, height);
|
||||
}
|
||||
|
||||
bool RenderEngine::TryPresentToWindow(unsigned outputFrameWidth, unsigned outputFrameHeight)
|
||||
{
|
||||
if (!TryEnterCriticalSection(&mMutex))
|
||||
return false;
|
||||
|
||||
mRenderer.PresentToWindow(mHdc, outputFrameWidth, outputFrameHeight);
|
||||
LeaveCriticalSection(&mMutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderEngine::TryUploadInputFrame(const VideoIOFrame& inputFrame, const VideoIOState& videoState)
|
||||
{
|
||||
if (inputFrame.hasNoInputSource || inputFrame.bytes == nullptr)
|
||||
return true;
|
||||
|
||||
const long textureSize = inputFrame.rowBytes * static_cast<long>(inputFrame.height);
|
||||
if (!TryEnterCriticalSection(&mMutex))
|
||||
return false;
|
||||
|
||||
wglMakeCurrent(mHdc, mHglrc);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mRenderer.TextureUploadBuffer());
|
||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, textureSize, inputFrame.bytes, GL_DYNAMIC_DRAW);
|
||||
glBindTexture(GL_TEXTURE_2D, mRenderer.CaptureTexture());
|
||||
if (inputFrame.pixelFormat == VideoIOPixelFormat::V210)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, videoState.captureTextureWidth, videoState.inputFrameSize.height, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, videoState.captureTextureWidth, videoState.inputFrameSize.height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
LeaveCriticalSection(&mMutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderEngine::RenderOutputFrame(const RenderPipelineFrameContext& context, VideoIOOutputFrame& outputFrame)
|
||||
{
|
||||
EnterCriticalSection(&mMutex);
|
||||
wglMakeCurrent(mHdc, mHglrc);
|
||||
const bool rendered = mRenderPipeline.RenderFrame(context, outputFrame);
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
LeaveCriticalSection(&mMutex);
|
||||
return rendered;
|
||||
}
|
||||
|
||||
void RenderEngine::RenderLayerStack(
|
||||
bool hasInputSource,
|
||||
const std::vector<RuntimeRenderState>& layerStates,
|
||||
unsigned inputFrameWidth,
|
||||
unsigned inputFrameHeight,
|
||||
unsigned captureTextureWidth,
|
||||
VideoIOPixelFormat inputPixelFormat,
|
||||
unsigned historyCap)
|
||||
{
|
||||
mRenderPass.Render(
|
||||
hasInputSource,
|
||||
layerStates,
|
||||
inputFrameWidth,
|
||||
inputFrameHeight,
|
||||
captureTextureWidth,
|
||||
inputPixelFormat,
|
||||
historyCap,
|
||||
[this](const RuntimeRenderState& state, OpenGLRenderer::LayerProgram::TextBinding& textBinding, std::string& error) {
|
||||
return mShaderPrograms.UpdateTextBindingTexture(state, textBinding, error);
|
||||
},
|
||||
[this](const RuntimeRenderState& state, unsigned availableSourceHistoryLength, unsigned availableTemporalHistoryLength, bool feedbackAvailable) {
|
||||
return mShaderPrograms.UpdateGlobalParamsBuffer(state, availableSourceHistoryLength, availableTemporalHistoryLength, feedbackAvailable);
|
||||
});
|
||||
}
|
||||
|
||||
bool RenderEngine::ReadOutputFrameRgba(unsigned width, unsigned height, std::vector<unsigned char>& bottomUpPixels)
|
||||
{
|
||||
if (width == 0 || height == 0)
|
||||
return false;
|
||||
|
||||
EnterCriticalSection(&mMutex);
|
||||
wglMakeCurrent(mHdc, mHglrc);
|
||||
|
||||
bottomUpPixels.resize(static_cast<std::size_t>(width) * height * 4);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mRenderer.OutputFramebuffer());
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
|
||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, bottomUpPixels.data());
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
LeaveCriticalSection(&mMutex);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user