Layer stacking
This commit is contained in:
@@ -156,16 +156,15 @@ OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
|
||||
mFastTransferExtensionAvailable(false),
|
||||
mCaptureTexture(0),
|
||||
mDecodedTexture(0),
|
||||
mLayerTempTexture(0),
|
||||
mFBOTexture(0),
|
||||
mDecodeFrameBuf(0),
|
||||
mLayerTempFrameBuf(0),
|
||||
mFullscreenVAO(0),
|
||||
mGlobalParamsUBO(0),
|
||||
mDecodeProgram(0),
|
||||
mDecodeVertexShader(0),
|
||||
mDecodeFragmentShader(0),
|
||||
mProgram(0),
|
||||
mVertexShader(0),
|
||||
mFragmentShader(0),
|
||||
mGlobalParamsUBOSize(0)
|
||||
{
|
||||
InitializeCriticalSection(&pMutex);
|
||||
@@ -228,6 +227,8 @@ OpenGLComposite::~OpenGLComposite()
|
||||
glDeleteBuffers(1, &mGlobalParamsUBO);
|
||||
if (mDecodeFrameBuf != 0)
|
||||
glDeleteFramebuffers(1, &mDecodeFrameBuf);
|
||||
if (mLayerTempFrameBuf != 0)
|
||||
glDeleteFramebuffers(1, &mLayerTempFrameBuf);
|
||||
if (mIdFrameBuf != 0)
|
||||
glDeleteFramebuffers(1, &mIdFrameBuf);
|
||||
if (mIdColorBuf != 0)
|
||||
@@ -238,12 +239,14 @@ OpenGLComposite::~OpenGLComposite()
|
||||
glDeleteTextures(1, &mCaptureTexture);
|
||||
if (mDecodedTexture != 0)
|
||||
glDeleteTextures(1, &mDecodedTexture);
|
||||
if (mLayerTempTexture != 0)
|
||||
glDeleteTextures(1, &mLayerTempTexture);
|
||||
if (mFBOTexture != 0)
|
||||
glDeleteTextures(1, &mFBOTexture);
|
||||
if (mUnpinnedTextureBuffer != 0)
|
||||
glDeleteBuffers(1, &mUnpinnedTextureBuffer);
|
||||
|
||||
destroyShaderProgram();
|
||||
destroyLayerPrograms();
|
||||
destroyDecodeShaderProgram();
|
||||
if (mControlServer)
|
||||
mControlServer->Stop();
|
||||
@@ -536,13 +539,18 @@ bool OpenGLComposite::InitOpenGLState()
|
||||
|
||||
ControlServer::Callbacks callbacks;
|
||||
callbacks.getStateJson = [this]() { return GetRuntimeStateJson(); };
|
||||
callbacks.selectShader = [this](const std::string& shaderId, std::string& error) { return SelectShader(shaderId, error); };
|
||||
callbacks.updateParameter = [this](const std::string& shaderId, const std::string& parameterId, const std::string& valueJson, std::string& error) {
|
||||
return UpdateParameterJson(shaderId, parameterId, valueJson, error);
|
||||
callbacks.addLayer = [this](const std::string& shaderId, std::string& error) { return AddLayer(shaderId, error); };
|
||||
callbacks.removeLayer = [this](const std::string& layerId, std::string& error) { return RemoveLayer(layerId, error); };
|
||||
callbacks.moveLayer = [this](const std::string& layerId, int direction, std::string& error) { return MoveLayer(layerId, direction, error); };
|
||||
callbacks.moveLayerToIndex = [this](const std::string& layerId, std::size_t targetIndex, std::string& error) { return MoveLayerToIndex(layerId, targetIndex, error); };
|
||||
callbacks.setLayerBypass = [this](const std::string& layerId, bool bypassed, std::string& error) { return SetLayerBypass(layerId, bypassed, error); };
|
||||
callbacks.setLayerShader = [this](const std::string& layerId, const std::string& shaderId, std::string& error) { return SetLayerShader(layerId, shaderId, error); };
|
||||
callbacks.updateLayerParameter = [this](const std::string& layerId, const std::string& parameterId, const std::string& valueJson, std::string& error) {
|
||||
return UpdateLayerParameterJson(layerId, parameterId, valueJson, error);
|
||||
};
|
||||
callbacks.resetParameters = [this](const std::string& shaderId, std::string& error) { return ResetShaderParameters(shaderId, error); };
|
||||
callbacks.setBypass = [this](bool bypassEnabled, std::string& error) { return SetBypassEnabled(bypassEnabled, error); };
|
||||
callbacks.setMixAmount = [this](double mixAmount, std::string& error) { return SetMixAmount(mixAmount, error); };
|
||||
callbacks.resetLayerParameters = [this](const std::string& layerId, std::string& error) { return ResetLayerParameters(layerId, error); };
|
||||
callbacks.saveStackPreset = [this](const std::string& presetName, std::string& error) { return SaveStackPreset(presetName, error); };
|
||||
callbacks.loadStackPreset = [this](const std::string& presetName, std::string& error) { return LoadStackPreset(presetName, error); };
|
||||
callbacks.reloadShader = [this](std::string& error) {
|
||||
if (!ReloadShader())
|
||||
{
|
||||
@@ -567,7 +575,7 @@ bool OpenGLComposite::InitOpenGLState()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! compileFragmentShader(sizeof(compilerErrorMessage), compilerErrorMessage))
|
||||
if (! compileLayerPrograms(sizeof(compilerErrorMessage), compilerErrorMessage))
|
||||
{
|
||||
MessageBoxA(NULL, compilerErrorMessage, "OpenGL shader failed to load or compile", MB_OK);
|
||||
return false;
|
||||
@@ -606,10 +614,20 @@ bool OpenGLComposite::InitOpenGLState()
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mFrameWidth, mFrameHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glGenTextures(1, &mLayerTempTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mLayerTempTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, mFrameWidth, mFrameHeight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
|
||||
// Create Frame Buffer Object (FBO) to perform off-screen rendering of scene.
|
||||
// This allows the render to be done on a framebuffer with width and height exactly matching the video format.
|
||||
glGenFramebuffers(1, &mDecodeFrameBuf);
|
||||
glGenFramebuffers(1, &mLayerTempFrameBuf);
|
||||
glGenFramebuffers(1, &mIdFrameBuf);
|
||||
glGenRenderbuffers(1, &mIdColorBuf);
|
||||
glGenRenderbuffers(1, &mIdDepthBuf);
|
||||
@@ -625,6 +643,15 @@ bool OpenGLComposite::InitOpenGLState()
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mLayerTempFrameBuf);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mLayerTempTexture, 0);
|
||||
glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (glStatus != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
MessageBox(NULL, _T("Cannot initialize layer framebuffer."), _T("OpenGL initialization error."), MB_OK);
|
||||
return false;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mIdFrameBuf);
|
||||
|
||||
// Texture for FBO
|
||||
@@ -872,7 +899,7 @@ bool OpenGLComposite::ReloadShader()
|
||||
EnterCriticalSection(&pMutex);
|
||||
wglMakeCurrent(hGLDC, hGLRC);
|
||||
|
||||
bool success = compileFragmentShader(sizeof(compilerErrorMessage), compilerErrorMessage);
|
||||
bool success = compileLayerPrograms(sizeof(compilerErrorMessage), compilerErrorMessage);
|
||||
if (mRuntimeHost)
|
||||
mRuntimeHost->ClearReloadRequest();
|
||||
|
||||
@@ -895,6 +922,98 @@ bool OpenGLComposite::ReloadShader()
|
||||
return success;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::compileSingleLayerProgram(const RuntimeRenderState& state, LayerProgram& layerProgram, int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
GLsizei errorBufferSize = 0;
|
||||
GLint compileResult = GL_FALSE;
|
||||
GLint linkResult = GL_FALSE;
|
||||
std::string fragmentShaderSource;
|
||||
std::string loadError;
|
||||
const char* vertexSource = kVertexShaderSource;
|
||||
|
||||
if (!mRuntimeHost->BuildLayerFragmentShaderSource(state.layerId, fragmentShaderSource, loadError))
|
||||
{
|
||||
CopyErrorMessage(loadError, errorMessageSize, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* fragmentSource = fragmentShaderSource.c_str();
|
||||
|
||||
GLuint newVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(newVertexShader, 1, (const GLchar**)&vertexSource, NULL);
|
||||
glCompileShader(newVertexShader);
|
||||
glGetShaderiv(newVertexShader, GL_COMPILE_STATUS, &compileResult);
|
||||
if (compileResult == GL_FALSE)
|
||||
{
|
||||
glGetShaderInfoLog(newVertexShader, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteShader(newVertexShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLuint newFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(newFragmentShader, 1, (const GLchar**)&fragmentSource, NULL);
|
||||
glCompileShader(newFragmentShader);
|
||||
glGetShaderiv(newFragmentShader, GL_COMPILE_STATUS, &compileResult);
|
||||
if (compileResult == GL_FALSE)
|
||||
{
|
||||
glGetShaderInfoLog(newFragmentShader, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteShader(newVertexShader);
|
||||
glDeleteShader(newFragmentShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLuint newProgram = glCreateProgram();
|
||||
glAttachShader(newProgram, newVertexShader);
|
||||
glAttachShader(newProgram, newFragmentShader);
|
||||
glLinkProgram(newProgram);
|
||||
glGetProgramiv(newProgram, GL_LINK_STATUS, &linkResult);
|
||||
if (linkResult == GL_FALSE)
|
||||
{
|
||||
glGetProgramInfoLog(newProgram, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteProgram(newProgram);
|
||||
glDeleteShader(newVertexShader);
|
||||
glDeleteShader(newFragmentShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
layerProgram.layerId = state.layerId;
|
||||
layerProgram.shaderId = state.shaderId;
|
||||
layerProgram.program = newProgram;
|
||||
layerProgram.vertexShader = newVertexShader;
|
||||
layerProgram.fragmentShader = newFragmentShader;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::compileLayerPrograms(int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
const std::vector<RuntimeRenderState> layerStates = mRuntimeHost ? mRuntimeHost->GetLayerRenderStates(mFrameWidth, mFrameHeight) : std::vector<RuntimeRenderState>();
|
||||
std::vector<LayerProgram> newPrograms;
|
||||
newPrograms.reserve(layerStates.size());
|
||||
|
||||
for (const RuntimeRenderState& state : layerStates)
|
||||
{
|
||||
LayerProgram layerProgram;
|
||||
if (!compileSingleLayerProgram(state, layerProgram, errorMessageSize, errorMessage))
|
||||
{
|
||||
for (LayerProgram& program : newPrograms)
|
||||
destroySingleLayerProgram(program);
|
||||
return false;
|
||||
}
|
||||
newPrograms.push_back(layerProgram);
|
||||
}
|
||||
|
||||
destroyLayerPrograms();
|
||||
mLayerPrograms.swap(newPrograms);
|
||||
|
||||
if (mRuntimeHost)
|
||||
{
|
||||
mRuntimeHost->SetCompileStatus(true, "Shader layers compiled successfully.");
|
||||
mRuntimeHost->ClearReloadRequest();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::compileDecodeShader(int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
GLsizei errorBufferSize = 0;
|
||||
@@ -947,27 +1066,34 @@ bool OpenGLComposite::compileDecodeShader(int errorMessageSize, char* errorMessa
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLComposite::destroyShaderProgram()
|
||||
void OpenGLComposite::destroySingleLayerProgram(LayerProgram& layerProgram)
|
||||
{
|
||||
if (mProgram != 0)
|
||||
if (layerProgram.program != 0)
|
||||
{
|
||||
glDeleteProgram(mProgram);
|
||||
mProgram = 0;
|
||||
glDeleteProgram(layerProgram.program);
|
||||
layerProgram.program = 0;
|
||||
}
|
||||
|
||||
if (mFragmentShader != 0)
|
||||
if (layerProgram.fragmentShader != 0)
|
||||
{
|
||||
glDeleteShader(mFragmentShader);
|
||||
mFragmentShader = 0;
|
||||
glDeleteShader(layerProgram.fragmentShader);
|
||||
layerProgram.fragmentShader = 0;
|
||||
}
|
||||
|
||||
if (mVertexShader != 0)
|
||||
if (layerProgram.vertexShader != 0)
|
||||
{
|
||||
glDeleteShader(mVertexShader);
|
||||
mVertexShader = 0;
|
||||
glDeleteShader(layerProgram.vertexShader);
|
||||
layerProgram.vertexShader = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGLComposite::destroyLayerPrograms()
|
||||
{
|
||||
for (LayerProgram& layerProgram : mLayerPrograms)
|
||||
destroySingleLayerProgram(layerProgram);
|
||||
mLayerPrograms.clear();
|
||||
}
|
||||
|
||||
void OpenGLComposite::destroyDecodeShaderProgram()
|
||||
{
|
||||
if (mDecodeProgram != 0)
|
||||
@@ -1006,29 +1132,45 @@ void OpenGLComposite::renderEffect()
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
renderDecodePass();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mIdFrameBuf);
|
||||
const std::vector<RuntimeRenderState> layerStates = mRuntimeHost ? mRuntimeHost->GetLayerRenderStates(mFrameWidth, mFrameHeight) : std::vector<RuntimeRenderState>();
|
||||
if (layerStates.empty() || mLayerPrograms.empty())
|
||||
{
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, mDecodeFrameBuf);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mIdFrameBuf);
|
||||
glBlitFramebuffer(0, 0, mFrameWidth, mFrameHeight, 0, 0, mFrameWidth, mFrameHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mIdFrameBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLuint sourceTexture = mDecodedTexture;
|
||||
for (std::size_t index = 0; index < layerStates.size() && index < mLayerPrograms.size(); ++index)
|
||||
{
|
||||
const std::size_t remaining = layerStates.size() - index;
|
||||
const bool writeToMain = (remaining % 2) == 1;
|
||||
renderShaderProgram(sourceTexture, writeToMain ? mIdFrameBuf : mLayerTempFrameBuf, mLayerPrograms[index], layerStates[index]);
|
||||
sourceTexture = writeToMain ? mFBOTexture : mLayerTempTexture;
|
||||
}
|
||||
}
|
||||
|
||||
if (mFastTransferExtensionAvailable)
|
||||
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
||||
}
|
||||
|
||||
void OpenGLComposite::renderShaderProgram(GLuint sourceTexture, GLuint destinationFrameBuffer, const LayerProgram& layerProgram, const RuntimeRenderState& state)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, destinationFrameBuffer);
|
||||
glViewport(0, 0, mFrameWidth, mFrameHeight);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glActiveTexture(GL_TEXTURE0 + kDecodedVideoTextureUnit);
|
||||
glBindTexture(GL_TEXTURE_2D, mDecodedTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, sourceTexture);
|
||||
glBindVertexArray(mFullscreenVAO);
|
||||
glUseProgram(mProgram);
|
||||
|
||||
if (mRuntimeHost)
|
||||
{
|
||||
const RuntimeRenderState state = mRuntimeHost->GetRenderState(mFrameWidth, mFrameHeight);
|
||||
updateGlobalParamsBuffer(state);
|
||||
}
|
||||
|
||||
glUseProgram(layerProgram.program);
|
||||
updateGlobalParamsBuffer(state);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||
|
||||
glUseProgram(0);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
if (mFastTransferExtensionAvailable)
|
||||
VideoFrameTransfer::endTextureInUse(VideoFrameTransfer::CPUtoGPU);
|
||||
}
|
||||
|
||||
void OpenGLComposite::renderDecodePass()
|
||||
@@ -1056,82 +1198,6 @@ void OpenGLComposite::renderDecodePass()
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
// Compile a fullscreen shader pass from the runtime Slang source into a core-profile
|
||||
// GLSL program. The renderer owns the fullscreen pass and parameter UBO layout.
|
||||
bool OpenGLComposite::compileFragmentShader(int errorMessageSize, char* errorMessage)
|
||||
{
|
||||
GLsizei errorBufferSize = 0;
|
||||
GLint compileResult = GL_FALSE;
|
||||
GLint linkResult = GL_FALSE;
|
||||
std::string fragmentShaderSource;
|
||||
std::string loadError;
|
||||
const char* vertexSource = kVertexShaderSource;
|
||||
|
||||
if (!mRuntimeHost->BuildActiveFragmentShaderSource(fragmentShaderSource, loadError))
|
||||
{
|
||||
mRuntimeHost->SetCompileStatus(false, loadError);
|
||||
CopyErrorMessage(loadError, errorMessageSize, errorMessage);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* fragmentSource = fragmentShaderSource.c_str();
|
||||
|
||||
GLuint newVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(newVertexShader, 1, (const GLchar**)&vertexSource, NULL);
|
||||
glCompileShader(newVertexShader);
|
||||
glGetShaderiv(newVertexShader, GL_COMPILE_STATUS, &compileResult);
|
||||
if (compileResult == GL_FALSE)
|
||||
{
|
||||
glGetShaderInfoLog(newVertexShader, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteShader(newVertexShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLuint newFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(newFragmentShader, 1, (const GLchar**)&fragmentSource, NULL);
|
||||
glCompileShader(newFragmentShader);
|
||||
glGetShaderiv(newFragmentShader, GL_COMPILE_STATUS, &compileResult);
|
||||
if (compileResult == GL_FALSE)
|
||||
{
|
||||
glGetShaderInfoLog(newFragmentShader, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteShader(newVertexShader);
|
||||
glDeleteShader(newFragmentShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
GLuint newProgram = glCreateProgram();
|
||||
glAttachShader(newProgram, newVertexShader);
|
||||
glAttachShader(newProgram, newFragmentShader);
|
||||
glLinkProgram(newProgram);
|
||||
glGetProgramiv(newProgram, GL_LINK_STATUS, &linkResult);
|
||||
if (linkResult == GL_FALSE)
|
||||
{
|
||||
glGetProgramInfoLog(newProgram, errorMessageSize, &errorBufferSize, errorMessage);
|
||||
glDeleteProgram(newProgram);
|
||||
glDeleteShader(newVertexShader);
|
||||
glDeleteShader(newFragmentShader);
|
||||
return false;
|
||||
}
|
||||
|
||||
destroyShaderProgram();
|
||||
|
||||
mProgram = newProgram;
|
||||
mVertexShader = newVertexShader;
|
||||
mFragmentShader = newFragmentShader;
|
||||
const RuntimeRenderState state = mRuntimeHost->GetRenderState(mFrameWidth, mFrameHeight);
|
||||
if (!updateGlobalParamsBuffer(state))
|
||||
{
|
||||
CopyErrorMessage("Failed to allocate the runtime parameter UBO.", errorMessageSize, errorMessage);
|
||||
destroyShaderProgram();
|
||||
return false;
|
||||
}
|
||||
|
||||
mRuntimeHost->SetCompileStatus(true, "Shader compiled successfully.");
|
||||
mRuntimeHost->ClearReloadRequest();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::PollRuntimeChanges()
|
||||
{
|
||||
if (!mRuntimeHost)
|
||||
@@ -1154,7 +1220,7 @@ bool OpenGLComposite::PollRuntimeChanges()
|
||||
return true;
|
||||
|
||||
char compilerErrorMessage[1024] = {};
|
||||
if (!compileFragmentShader(sizeof(compilerErrorMessage), compilerErrorMessage))
|
||||
if (!compileLayerPrograms(sizeof(compilerErrorMessage), compilerErrorMessage))
|
||||
{
|
||||
mRuntimeHost->SetCompileStatus(false, compilerErrorMessage);
|
||||
mRuntimeHost->ClearReloadRequest();
|
||||
@@ -1251,9 +1317,9 @@ std::string OpenGLComposite::GetRuntimeStateJson() const
|
||||
return mRuntimeHost ? mRuntimeHost->BuildStateJson() : "{}";
|
||||
}
|
||||
|
||||
bool OpenGLComposite::SelectShader(const std::string& shaderId, std::string& error)
|
||||
bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->SelectShader(shaderId, error))
|
||||
if (!mRuntimeHost->AddLayer(shaderId, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
@@ -1261,40 +1327,93 @@ bool OpenGLComposite::SelectShader(const std::string& shaderId, std::string& err
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::UpdateParameterJson(const std::string& shaderId, const std::string& parameterId, const std::string& valueJson, std::string& error)
|
||||
bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->RemoveLayer(layerId, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->MoveLayer(layerId, direction, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->MoveLayerToIndex(layerId, targetIndex, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->SetLayerBypass(layerId, bypassed, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->SetLayerShader(layerId, shaderId, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::UpdateLayerParameterJson(const std::string& layerId, const std::string& parameterId, const std::string& valueJson, std::string& error)
|
||||
{
|
||||
JsonValue parsedValue;
|
||||
if (!ParseJson(valueJson, parsedValue, error))
|
||||
return false;
|
||||
|
||||
if (!mRuntimeHost->UpdateParameter(shaderId, parameterId, parsedValue, error))
|
||||
if (!mRuntimeHost->UpdateLayerParameter(layerId, parameterId, parsedValue, error))
|
||||
return false;
|
||||
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::ResetShaderParameters(const std::string& shaderId, std::string& error)
|
||||
bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->ResetParameters(shaderId, error))
|
||||
if (!mRuntimeHost->ResetLayerParameters(layerId, error))
|
||||
return false;
|
||||
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::SetBypassEnabled(bool bypassEnabled, std::string& error)
|
||||
bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->SetBypass(bypassEnabled, error))
|
||||
if (!mRuntimeHost->SaveStackPreset(presetName, error))
|
||||
return false;
|
||||
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OpenGLComposite::SetMixAmount(double mixAmount, std::string& error)
|
||||
bool OpenGLComposite::LoadStackPreset(const std::string& presetName, std::string& error)
|
||||
{
|
||||
if (!mRuntimeHost->SetMixAmount(mixAmount, error))
|
||||
if (!mRuntimeHost->LoadStackPreset(presetName, error))
|
||||
return false;
|
||||
|
||||
ReloadShader();
|
||||
broadcastRuntimeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user