mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-07 21:23:32 +00:00
gl_engine: Introduce fill effect for opengl renderer
issue: https://github.com/thorvg/thorvg/issues/3054
This commit is contained in:
parent
bf3bd908ff
commit
85e215a294
7 changed files with 100 additions and 0 deletions
|
@ -208,4 +208,9 @@ struct GlGaussianBlur {
|
|||
float extend{};
|
||||
};
|
||||
|
||||
struct GlEffectParams {
|
||||
// fill: [0..3]: color
|
||||
float params[4+4+4];
|
||||
};
|
||||
|
||||
#endif /* _TVG_GL_COMMON_H_ */
|
||||
|
|
|
@ -434,3 +434,27 @@ void GlGaussianBlurTask::run()
|
|||
}
|
||||
GL_CHECK(glEnable(GL_BLEND));
|
||||
}
|
||||
|
||||
void GlEffectColorTransformTask::run()
|
||||
{
|
||||
// const auto vp = getViewport();
|
||||
const auto width = mDstFbo->getWidth();
|
||||
const auto height = mDstFbo->getHeight();
|
||||
// get targets handles and pass to shader
|
||||
GLuint dstCopyTexId = mDstCopyFbo->getColorTexture();
|
||||
GLint srcTextureLoc = getProgram()->getUniformLocation("uSrcTexture");
|
||||
addBindResource({ 0, dstCopyTexId, srcTextureLoc });
|
||||
|
||||
GL_CHECK(glViewport(0, 0, width, height));
|
||||
GL_CHECK(glScissor(0, 0, width, height));
|
||||
// we need to make full copy of dst to intermediate buffers to be sure, that they are not contained prev data
|
||||
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, mDstFbo->getFboId()));
|
||||
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDstCopyFbo->getResolveFboId()));
|
||||
GL_CHECK(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mDstFbo->getFboId()));
|
||||
|
||||
// run transform
|
||||
GL_CHECK(glDisable(GL_BLEND));
|
||||
GlRenderTask::run();
|
||||
GL_CHECK(glEnable(GL_BLEND));
|
||||
}
|
|
@ -237,4 +237,17 @@ private:
|
|||
GlRenderTarget* mDstCopyFbo1;
|
||||
};
|
||||
|
||||
class GlEffectColorTransformTask: public GlRenderTask
|
||||
{
|
||||
public:
|
||||
GlEffectColorTransformTask(GlProgram* program, GlRenderTarget* dstFbo, GlRenderTarget* dstCopyFbo):
|
||||
GlRenderTask(program), mDstFbo(dstFbo), mDstCopyFbo(dstCopyFbo) {};
|
||||
~GlEffectColorTransformTask() {};
|
||||
|
||||
void run() override;
|
||||
private:
|
||||
GlRenderTarget* mDstFbo;
|
||||
GlRenderTarget* mDstCopyFbo;
|
||||
};
|
||||
|
||||
#endif /* _TVG_GL_RENDER_TASK_H_ */
|
||||
|
|
|
@ -144,6 +144,7 @@ void GlRenderer::initShaders()
|
|||
// effects
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, GAUSSIAN_VERTICAL));
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, GAUSSIAN_HORIZONTAL));
|
||||
mPrograms.push(new GlProgram(EFFECT_VERTEX, EFFECT_FILL));
|
||||
}
|
||||
|
||||
|
||||
|
@ -961,6 +962,19 @@ void GlRenderer::effectGaussianBlurUpdate(RenderEffectGaussianBlur* effect, cons
|
|||
}
|
||||
|
||||
|
||||
void GlRenderer::effectFillUpdate(RenderEffectFill* effect, const Matrix& transform)
|
||||
{
|
||||
auto params = (GlEffectParams*)effect->rd;
|
||||
if (!params) params = tvg::malloc<GlEffectParams*>(sizeof(GlEffectParams));
|
||||
params->params[0] = effect->color[0] / 255.0f;
|
||||
params->params[1] = effect->color[1] / 255.0f;
|
||||
params->params[2] = effect->color[2] / 255.0f;
|
||||
params->params[3] = effect->color[3] / 255.0f;
|
||||
effect->rd = params;
|
||||
effect->valid = true;
|
||||
}
|
||||
|
||||
|
||||
bool GlRenderer::effectGaussianBlurRegion(RenderEffectGaussianBlur* effect)
|
||||
{
|
||||
auto gaussianBlur = (GlGaussianBlur*)effect->rd;
|
||||
|
@ -984,6 +998,7 @@ void GlRenderer::prepare(RenderEffect* effect, const Matrix& transform)
|
|||
|
||||
switch (effect->type) {
|
||||
case SceneEffect::GaussianBlur: effectGaussianBlurUpdate(static_cast<RenderEffectGaussianBlur*>(effect), transform); break;
|
||||
case SceneEffect::Fill: effectFillUpdate(static_cast<RenderEffectFill*>(effect), transform); break;
|
||||
default: break;
|
||||
}
|
||||
effect->valid = true;
|
||||
|
@ -994,6 +1009,7 @@ bool GlRenderer::region(RenderEffect* effect)
|
|||
{
|
||||
switch (effect->type) {
|
||||
case SceneEffect::GaussianBlur: return effectGaussianBlurRegion(static_cast<RenderEffectGaussianBlur*>(effect));
|
||||
case SceneEffect::Fill: return true;
|
||||
default: return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -1041,6 +1057,24 @@ bool GlRenderer::render(TVG_UNUSED RenderCompositor* cmp, const RenderEffect* ef
|
|||
gaussianTask->vertTask->setDrawRange(ioffset, 6);
|
||||
// add task to render pipeline
|
||||
pass->addRenderTask(gaussianTask);
|
||||
} // effect fill
|
||||
else if (effect->type == SceneEffect::Fill) {
|
||||
GlProgram* program{};
|
||||
if (effect->type == SceneEffect::Fill) program = mPrograms[RT_EffectFill];
|
||||
// get current and intermidiate framebuffers
|
||||
auto dstFbo = pass->getFbo();
|
||||
auto dstCopyFbo = mBlendPool[0]->getRenderTarget(vp);
|
||||
// add uniform data
|
||||
auto params = (GlEffectParams*)(effect->rd);
|
||||
auto paramsOffset = mGpuBuffer.push(params, sizeof(GlEffectParams), true);
|
||||
// create gaussian blur tasks
|
||||
auto task = new GlEffectColorTransformTask(program, dstFbo, dstCopyFbo);
|
||||
task->setViewport({0, 0, vp.w, vp.h});
|
||||
task->addBindResource(GlBindingResource{0, program->getUniformBlockIndex("Params"), mGpuBuffer.getBufferId(), paramsOffset, sizeof(GlEffectParams)});
|
||||
task->addVertexLayout(GlVertexLayout{0, 2, 2 * sizeof(float), voffset});
|
||||
task->setDrawRange(ioffset, 6);
|
||||
// add task to render pipeline
|
||||
pass->addRenderTask(task);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -62,6 +62,10 @@ public:
|
|||
|
||||
RT_GaussianVert,
|
||||
RT_GaussianHorz,
|
||||
//RT_DropShadow,
|
||||
RT_EffectFill,
|
||||
RT_EffectTint,
|
||||
RT_EffectTritone,
|
||||
|
||||
RT_None,
|
||||
};
|
||||
|
@ -120,6 +124,8 @@ private:
|
|||
void endRenderPass(RenderCompositor* cmp);
|
||||
|
||||
void effectGaussianBlurUpdate(RenderEffectGaussianBlur* effect, const Matrix& transform);
|
||||
void effectFillUpdate(RenderEffectFill* effect, const Matrix& transform);
|
||||
|
||||
bool effectGaussianBlurRegion(RenderEffectGaussianBlur* effect);
|
||||
|
||||
void flush();
|
||||
|
|
|
@ -820,3 +820,20 @@ void main()
|
|||
FragColor = colorSum / weightSum;
|
||||
}
|
||||
)";
|
||||
|
||||
const char* EFFECT_FILL = R"(
|
||||
uniform sampler2D uSrcTexture;
|
||||
layout(std140) uniform Params {
|
||||
vec4 params[3];
|
||||
} uParams;
|
||||
|
||||
in vec2 vUV;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 orig = texture(uSrcTexture, vUV);
|
||||
vec4 fill = uParams.params[0];
|
||||
FragColor = fill * orig.a * fill.a;
|
||||
}
|
||||
)";
|
||||
|
|
|
@ -57,5 +57,6 @@ extern const char* EXCLUSION_BLEND_FRAG;
|
|||
extern const char* EFFECT_VERTEX;
|
||||
extern const char* GAUSSIAN_VERTICAL;
|
||||
extern const char* GAUSSIAN_HORIZONTAL;
|
||||
extern const char* EFFECT_FILL;
|
||||
|
||||
#endif /* _TVG_GL_SHADERSRC_H_ */
|
||||
|
|
Loading…
Add table
Reference in a new issue