diff --git a/core/renderer/Renderer.cpp b/core/renderer/Renderer.cpp index d3b98ba15..d83099429 100644 --- a/core/renderer/Renderer.cpp +++ b/core/renderer/Renderer.cpp @@ -844,9 +844,9 @@ void Renderer::beginRenderPass() auto depthStencil = _dsDesc; if (!_currentRT->isDefaultRenderTarget()) { - if (!_currentRT->_depth) + if (!_currentRT->_attchmnt[backend::RenderTarget::O_DEPTH]) depthStencil.removeFlag(DepthStencilFlags::DEPTH_TEST | DepthStencilFlags::DEPTH_WRITE); - if (!_currentRT->_stencil) + if (!_currentRT->_attchmnt[backend::RenderTarget::O_STENCIL]) depthStencil.removeFlag(DepthStencilFlags::STENCIL_TEST); } diff --git a/core/renderer/backend/RenderTarget.h b/core/renderer/backend/RenderTarget.h index 7a70e57cc..187c8b6c8 100644 --- a/core/renderer/backend/RenderTarget.h +++ b/core/renderer/backend/RenderTarget.h @@ -8,6 +8,29 @@ NS_AX_BACKEND_BEGIN class RenderTarget : public ax::Object { + +public: + + enum ORDER + { + O_COLOR_0, + O_COLOR_1, + O_COLOR_2, + O_COLOR_3, + O_DEPTH, + O_STENCIL + }; + + enum FLAGS : int + { + F_COLOR_0 = 0x1, + F_COLOR_1 = 0x2, + F_COLOR_2 = 0x4, + F_COLOR_3 = 0x8, + F_DEPTH = 0x10, + F_STENCIL = 0x20 + }; + public: struct RenderBuffer { @@ -16,61 +39,59 @@ public: explicit operator bool() const { return texture != nullptr; } }; typedef RenderBuffer ColorAttachment[MAX_COLOR_ATTCHMENT]; + typedef RenderBuffer AllAttachment[MAX_COLOR_ATTCHMENT + 2]; RenderTarget(bool defaultRenderTarget) : _defaultRenderTarget(defaultRenderTarget) {} virtual ~RenderTarget() { - for (auto colorItem : _color) - AX_SAFE_RELEASE(colorItem.texture); - AX_SAFE_RELEASE(_depth.texture); - AX_SAFE_RELEASE(_stencil.texture); + for (auto& one : _attchmnt) + AX_SAFE_RELEASE(one.texture); } bool isDefaultRenderTarget() const { return _defaultRenderTarget; } void setColorAttachment(ColorAttachment attachment) { - for (auto colorItem : _color) - AX_SAFE_RELEASE(colorItem.texture); - memcpy(_color, attachment, sizeof(ColorAttachment)); - for (auto colorItem : _color) - AX_SAFE_RETAIN(colorItem.texture); + for (int i = 0; i < MAX_COLOR_ATTCHMENT; ++i) + AX_SAFE_RELEASE(_attchmnt[i].texture); + memcpy(_attchmnt, attachment, sizeof(ColorAttachment)); + for (int i = 0; i < MAX_COLOR_ATTCHMENT; ++i) + AX_SAFE_RETAIN(_attchmnt[i].texture); _dirty = true; }; void setColorAttachment(TextureBackend* attachment, int level = 0, int index = 0) { - AX_SAFE_RELEASE(_color[index].texture); - _color[index].texture = attachment; - _color[index].level = level; - AX_SAFE_RETAIN(_color[index].texture); + AX_SAFE_RELEASE(_attchmnt[index].texture); + _attchmnt[index].texture = attachment; + _attchmnt[index].level = level; + AX_SAFE_RETAIN(_attchmnt[index].texture); _dirty = true; } void setDepthAttachment(TextureBackend* attachment, int level = 0) { - AX_SAFE_RELEASE(_depth.texture); - _depth.texture = attachment; - _depth.level = level; - AX_SAFE_RETAIN(_depth.texture); + AX_SAFE_RELEASE(_attchmnt[O_DEPTH].texture); + _attchmnt[O_DEPTH].texture = attachment; + _attchmnt[O_DEPTH].level = level; + AX_SAFE_RETAIN(_attchmnt[O_DEPTH].texture); _dirty = true; }; void setStencilAttachment(TextureBackend* attachment, int level = 0) { - AX_SAFE_RELEASE(_stencil.texture); - _stencil.texture = attachment; - _stencil.level = level; - AX_SAFE_RETAIN(_stencil.texture); + AX_SAFE_RELEASE(_attchmnt[O_STENCIL].texture); + _attchmnt[O_STENCIL].texture = attachment; + _attchmnt[O_STENCIL].level = level; + AX_SAFE_RETAIN(_attchmnt[O_STENCIL].texture); _dirty = true; }; bool isDirty() const { return _dirty; } - ColorAttachment _color{}; - RenderBuffer _depth{}; - RenderBuffer _stencil{}; + AllAttachment _attchmnt{}; + FLAGS _flags{F_COLOR_0|F_DEPTH|F_STENCIL}; // by default as it supported now, but this flags should be cleared new created render target if it needed protected: bool _defaultRenderTarget = false; diff --git a/core/renderer/backend/opengl/CommandBufferGL.cpp b/core/renderer/backend/opengl/CommandBufferGL.cpp index 46ff2b071..0573ba619 100644 --- a/core/renderer/backend/opengl/CommandBufferGL.cpp +++ b/core/renderer/backend/opengl/CommandBufferGL.cpp @@ -444,7 +444,7 @@ void CommandBufferGL::readPixels(RenderTarget* rt, std::function_color[0].texture; + auto colorAttachment = rt->_attchmnt[backend::RenderTarget::O_COLOR_0].texture; if (colorAttachment) { readPixels(rt, 0, 0, colorAttachment->getWidth(), colorAttachment->getHeight(), diff --git a/core/renderer/backend/opengl/RenderTargetGL.cpp b/core/renderer/backend/opengl/RenderTargetGL.cpp index 0f70f2861..84fe84d05 100644 --- a/core/renderer/backend/opengl/RenderTargetGL.cpp +++ b/core/renderer/backend/opengl/RenderTargetGL.cpp @@ -21,11 +21,8 @@ RenderTargetGL::~RenderTargetGL() { bindFrameBuffer(); - for (auto slot = 0; slot < MAX_COLOR_ATTCHMENT; ++slot) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + slot, GL_TEXTURE_2D, 0, 0); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0); - - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0); + for (auto slot = 0; slot < MAX_COLOR_ATTCHMENT + 2; ++slot) + glFramebufferTexture2D(GL_FRAMEBUFFER, _attch_const[slot], GL_TEXTURE_2D, 0, 0); unbindFrameBuffer(); glDeleteFramebuffers(1, &_FBO); @@ -45,35 +42,27 @@ void RenderTargetGL::unbindFrameBuffer() const void RenderTargetGL::update() const { if (!_dirty) return; - if(!_defaultRenderTarget) { - { // color attachments - GLenum bufs[MAX_COLOR_ATTCHMENT] = {GL_NONE}; - for (size_t i = 0; i < MAX_COLOR_ATTCHMENT; ++i) + if(!_defaultRenderTarget) + { + GLenum bufs[MAX_COLOR_ATTCHMENT + 2] = {GL_NONE}; + for (size_t i = 0; i < MAX_COLOR_ATTCHMENT + 2; ++i) + { + if ((_flags >> i)&1) { GLuint texture = 0; GLint level = 0; - if (_color[i]) + if (_attchmnt[i]) { - texture = static_cast(_color[i].texture->getHandler()); - level = _color[i].level; - bufs[i] = GL_COLOR_ATTACHMENT0 + i; + texture = static_cast(_attchmnt[i].texture->getHandler()); + level = _attchmnt[i].level; + bufs[i] = _attch_const[i]; } - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, texture, level); + glFramebufferTexture2D(GL_FRAMEBUFFER, _attch_const[i], GL_TEXTURE_2D, texture, level); } + } #if AX_TARGET_PLATFORM == AX_PLATFORM_WIN32 || AX_TARGET_PLATFORM == AX_PLATFORM_LINUX - glDrawBuffers(MAX_COLOR_ATTCHMENT, bufs); + glDrawBuffers(MAX_COLOR_ATTCHMENT, bufs); #endif - CHECK_GL_ERROR_DEBUG(); - } - - // depth attacmhemt - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, - _depth.texture != nullptr ? _depth.texture->getHandler() : 0, _depth.level); - CHECK_GL_ERROR_DEBUG(); - - // stencil attachment - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, - _stencil.texture != nullptr ? _stencil.texture->getHandler() : 0, _stencil.level); CHECK_GL_ERROR_DEBUG(); } diff --git a/core/renderer/backend/opengl/RenderTargetGL.h b/core/renderer/backend/opengl/RenderTargetGL.h index d37ee8bd2..4b270c17f 100644 --- a/core/renderer/backend/opengl/RenderTargetGL.h +++ b/core/renderer/backend/opengl/RenderTargetGL.h @@ -9,6 +9,19 @@ class DriverGL; class RenderTargetGL : public RenderTarget { + +protected: + + const std::array _attch_const = + { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3, + GL_DEPTH_ATTACHMENT, + GL_STENCIL_ATTACHMENT + }; + public: /* * generateFBO, false, use for screen framebuffer