diff --git a/src/renderer/gl_engine/tvgGlRenderPass.cpp b/src/renderer/gl_engine/tvgGlRenderPass.cpp index 1eb53f4b..9c9c2d19 100644 --- a/src/renderer/gl_engine/tvgGlRenderPass.cpp +++ b/src/renderer/gl_engine/tvgGlRenderPass.cpp @@ -48,6 +48,22 @@ void GlRenderTarget::init(GLint resolveId) GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mFbo)); + GL_CHECK(glGenRenderbuffers(1, &mColorBuffer)); + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mColorBuffer)); + GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, mWidth, mHeight)); + + GL_CHECK(glGenRenderbuffers(1, &mStencilBuffer)); + + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer)); + + GL_CHECK(glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_STENCIL_INDEX8, mWidth, mHeight)); + + GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0)); + + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorBuffer)); + GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer)); + + // resolve target GL_CHECK(glGenTextures(1, &mColorTex)); GL_CHECK(glBindTexture(GL_TEXTURE_2D, mColorTex)); @@ -60,16 +76,9 @@ void GlRenderTarget::init(GLint resolveId) GL_CHECK(glBindTexture(GL_TEXTURE_2D, 0)); - GL_CHECK(glGenRenderbuffers(1, &mStencilBuffer)); - - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, mStencilBuffer)); - - GL_CHECK(glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, mWidth, mHeight)); - - GL_CHECK(glBindRenderbuffer(GL_RENDERBUFFER, 0)); - + GL_CHECK(glGenFramebuffers(1, &mResolveFbo)); + GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, mResolveFbo)); GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTex, 0)); - GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mStencilBuffer)); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, resolveId)); } diff --git a/src/renderer/gl_engine/tvgGlRenderPass.h b/src/renderer/gl_engine/tvgGlRenderPass.h index c0b15c39..241ad42c 100644 --- a/src/renderer/gl_engine/tvgGlRenderPass.h +++ b/src/renderer/gl_engine/tvgGlRenderPass.h @@ -40,14 +40,20 @@ public: void init(GLint resolveId); GLuint getFboId() { return mFbo; } + GLuint getResolveFboId() { return mResolveFbo; } GLuint getColorTexture() { return mColorTex; } + uint32_t getWidth() const { return mWidth; } + uint32_t getHeight() const { return mHeight; } + private: uint32_t mWidth = 0; uint32_t mHeight = 0; GLuint mFbo = 0; - GLuint mColorTex = 0; + GLuint mColorBuffer = 0; GLuint mStencilBuffer = 0; + GLuint mResolveFbo = 0; + GLuint mColorTex = 0; }; class GlRenderPass @@ -66,7 +72,7 @@ public: template T* endRenderPass(GlProgram* program, GLuint targetFbo) { - return new T(program, targetFbo, mFbo->getFboId(), std::move(mTasks)); + return new T(program, targetFbo, mFbo, std::move(mTasks)); } private: GlRenderTarget* mFbo; diff --git a/src/renderer/gl_engine/tvgGlRenderTask.cpp b/src/renderer/gl_engine/tvgGlRenderTask.cpp index ab4000e1..37142d99 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.cpp +++ b/src/renderer/gl_engine/tvgGlRenderTask.cpp @@ -22,6 +22,7 @@ #include "tvgGlRenderTask.h" #include "tvgGlProgram.h" +#include "tvgGlRenderPass.h" /************************************************************************/ /* External Class Implementation */ @@ -131,8 +132,8 @@ void GlStencilCoverTask::run() GL_CHECK(glDisable(GL_STENCIL_TEST)); } -GlComposeTask::GlComposeTask(GlProgram* program, GLuint target, GLuint selfFbo, Array&& tasks) - :GlRenderTask(program) ,mTargetFbo(target), mSelfFbo(selfFbo), mTasks() +GlComposeTask::GlComposeTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks) + :GlRenderTask(program) ,mTargetFbo(target), mFbo(fbo), mTasks() { mTasks.push(tasks); tasks.clear(); @@ -162,10 +163,23 @@ void GlComposeTask::run() GLenum stencil_attachment = GL_STENCIL_ATTACHMENT; GL_CHECK(glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &stencil_attachment)); + + onResolve(); } -GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GLuint compose, Array&& tasks) - : GlComposeTask(program, target, compose, std::move(tasks)) +GLuint GlComposeTask::getSelfFbo() { return mFbo->getFboId(); } + +GLuint GlComposeTask::getResolveFboId() { return mFbo->getResolveFboId(); } + +void GlComposeTask::onResolve() { + GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, getSelfFbo())); + GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, getResolveFboId())); + + GL_CHECK(glBlitFramebuffer(0, 0, mFbo->getWidth(), mFbo->getHeight(), 0, 0, mFbo->getWidth(), mFbo->getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST)); +} + +GlBlitTask::GlBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks) + : GlComposeTask(program, target, fbo, std::move(tasks)) { } @@ -186,8 +200,8 @@ void GlBlitTask::run() GL_CHECK(glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST)); } -GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GLuint compose, Array&& tasks) - : GlComposeTask(program, target, compose, std::move(tasks)) +GlDrawBlitTask::GlDrawBlitTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks) + : GlComposeTask(program, target, fbo, std::move(tasks)) { } diff --git a/src/renderer/gl_engine/tvgGlRenderTask.h b/src/renderer/gl_engine/tvgGlRenderTask.h index 424012e6..3256a00a 100644 --- a/src/renderer/gl_engine/tvgGlRenderTask.h +++ b/src/renderer/gl_engine/tvgGlRenderTask.h @@ -110,10 +110,12 @@ private: GlRenderTask* mCoverTask; }; +class GlRenderTarget; + class GlComposeTask : public GlRenderTask { public: - GlComposeTask(GlProgram* program, GLuint target, GLuint selfFbo, Array&& tasks); + GlComposeTask(GlProgram* program, GLuint target, GlRenderTarget* fbo, Array&& tasks); ~GlComposeTask() override; void run() override; @@ -121,24 +123,30 @@ public: protected: GLuint getTargetFbo() { return mTargetFbo; } - GLuint getSelfFbo() { return mSelfFbo; } + GLuint getSelfFbo(); + GLuint getResolveFboId(); + + virtual void onResolve(); private: GLuint mTargetFbo; - GLuint mSelfFbo; + GlRenderTarget* mFbo; Array mTasks; }; class GlBlitTask : public GlComposeTask { public: - GlBlitTask(GlProgram*, GLuint target, GLuint compose, Array&& tasks); + GlBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array&& tasks); ~GlBlitTask() override = default; void setSize(uint32_t width, uint32_t height); void run() override; +protected: + void onResolve() override {} + private: uint32_t mWidth = 0; uint32_t mHeight = 0; @@ -147,7 +155,7 @@ private: class GlDrawBlitTask : public GlComposeTask { public: - GlDrawBlitTask(GlProgram*, GLuint target, GLuint compose, Array&& tasks); + GlDrawBlitTask(GlProgram*, GLuint target, GlRenderTarget* fbo, Array&& tasks); ~GlDrawBlitTask() override = default; void run() override;