gl_engine: using normal texture rendering in final color blit

Since blit msaa framebuffer to another msaa framebuffer may generate
GLError in some platforms. Use normal texture rendering to blit the final
color buffer onto target framebuffer.
This commit is contained in:
RuiwenTang 2024-04-10 13:45:32 +08:00 committed by Hermet Park
parent 4d8f617af6
commit d9d677acc6
6 changed files with 54 additions and 24 deletions

View file

@ -202,25 +202,26 @@ void GlComposeTask::onResolve() {
}
GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks)
: GlComposeTask(program, target, fbo, std::move(tasks))
: GlComposeTask(program, target, fbo, std::move(tasks)), mColorTex(fbo->getColorTexture())
{
}
void GlBlitTask::setSize(uint32_t width, uint32_t height)
{
mWidth = width;
mHeight = height;
}
void GlBlitTask::run()
{
GlComposeTask::run();
GL_CHECK(glScissor(0, 0, mWidth, mHeight));
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo()));
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, getSelfFbo()));
GL_CHECK(glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST));
if (mClearBuffer) {
GL_CHECK(glClearColor(0, 0, 0, 0));
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT));
}
// make sure the blending is correct
GL_CHECK(glEnable(GL_BLEND));
GL_CHECK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
GlRenderTask::run();
}
GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks)

View file

@ -130,7 +130,7 @@ protected:
GLuint getResolveFboId();
virtual void onResolve();
void onResolve();
private:
GLuint mTargetFbo;
GlRenderTarget* mFbo;
@ -143,16 +143,11 @@ public:
GlBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array<GlRenderTask*>&& tasks);
~GlBlitTask() override = default;
void setSize(uint32_t width, uint32_t height);
void run() override;
protected:
void onResolve() override {}
GLuint getColorTextore() const { return mColorTex; }
private:
uint32_t mWidth = 0;
uint32_t mHeight = 0;
GLuint mColorTex = 0;
};
class GlDrawBlitTask : public GlComposeTask

View file

@ -86,8 +86,6 @@ bool GlRenderer::sync()
//nothing to be done.
if (mRenderPassStack.size() == 0) return true;
mGpuBuffer->flushToGPU();
// Blend function for straight alpha
GL_CHECK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA));
GL_CHECK(glEnable(GL_BLEND));
@ -95,14 +93,15 @@ bool GlRenderer::sync()
GL_CHECK(glCullFace(GL_FRONT_AND_BACK));
GL_CHECK(glFrontFace(GL_CCW));
mGpuBuffer->bind();
auto task = mRenderPassStack.front().endRenderPass<GlBlitTask>(mPrograms[RT_Blit].get(), mTargetFboId);
auto task = mRenderPassStack.front().endRenderPass<GlBlitTask>(nullptr, mTargetFboId);
task->setSize(surface.w, surface.h);
prepareBlitTask(task);
task->mClearBuffer = mClearBuffer;
mGpuBuffer->flushToGPU();
mGpuBuffer->bind();
task->run();
mGpuBuffer->unbind();
@ -490,6 +489,8 @@ void GlRenderer::initShaders()
mPrograms.push_back(make_unique<GlProgram>(GlShader::gen(MASK_VERT_SHADER, MASK_DIFF_FRAG_SHADER)));
// stencil Renderer
mPrograms.push_back(make_unique<GlProgram>(GlShader::gen(STENCIL_VERT_SHADER, STENCIL_FRAG_SHADER)));
// blit Renderer
mPrograms.push_back(make_unique<GlProgram>(GlShader::gen(BLIT_VERT_SHADER, BLIT_FRAG_SHADER)));
}
@ -692,6 +693,16 @@ GlRenderPass* GlRenderer::currentPass()
return &mRenderPassStack.back();
}
void GlRenderer::prepareBlitTask(GlBlitTask* task)
{
prepareCmpTask(task);
{
uint32_t loc = task->getProgram()->getUniformLocation("uSrcTexture");
task->addBindResource(GlBindingResource{0, task->getColorTextore(), loc});
}
}
void GlRenderer::prepareCmpTask(GlRenderTask* task)
{
// we use 1:1 blit mapping since compositor fbo is same size as root fbo

View file

@ -47,6 +47,7 @@ public:
RT_MaskIntersect,
RT_MaskDifference,
RT_Stencil,
RT_Blit,
RT_None,
};
@ -90,6 +91,7 @@ private:
GlRenderPass* currentPass();
void prepareBlitTask(GlBlitTask* task);
void prepareCmpTask(GlRenderTask* task);
void endRenderPass(Compositor* cmp);

View file

@ -453,3 +453,22 @@ const char* STENCIL_FRAG_SHADER = TVG_COMPOSE_SHADER(
out vec4 FragColor; \n
void main() { FragColor = vec4(0.0); } \n
);
const char* BLIT_VERT_SHADER = TVG_COMPOSE_SHADER(
layout(location = 0) in vec2 aLocation; \n
layout(location = 1) in vec2 aUV; \n
out vec2 vUV; \n
void main() { \n
vUV = aUV; \n
gl_Position = vec4(aLocation, 0.0, 1.0); \n
}
);
const char* BLIT_FRAG_SHADER = TVG_COMPOSE_SHADER(
uniform sampler2D uSrcTexture; \n
in vec2 vUV; \n
out vec4 FragColor; \n
void main() { \n
FragColor = texture(uSrcTexture, vUV); \n
}
);

View file

@ -41,5 +41,7 @@ extern const char* MASK_INTERSECT_FRAG_SHADER;
extern const char* MASK_DIFF_FRAG_SHADER;
extern const char* STENCIL_VERT_SHADER;
extern const char* STENCIL_FRAG_SHADER;
extern const char* BLIT_VERT_SHADER;
extern const char* BLIT_FRAG_SHADER;
#endif /* _TVG_GL_SHADERSRC_H_ */