void FrameBuffer::applyFBO() { CHECK_GL_ERROR_DEBUG(); glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&_previousFBO); glBindFramebuffer(GL_FRAMEBUFFER, _fbo); // CCASSERT(_fbo==0 || _fbo != _previousFBO, "calling applyFBO without restoring the previous one"); CHECK_GL_ERROR_DEBUG(); if(_fboBindingDirty && !isDefaultFBO()) { CHECK_GL_ERROR_DEBUG(); if(RenderTargetBase::Type::Texture2D == _rt->getType()) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _rt->getTexture()->getName(), 0); else glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _rt->getBuffer()); CHECK_GL_ERROR_DEBUG(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); CHECK_GL_ERROR_DEBUG(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); CHECK_GL_ERROR_DEBUG(); CCLOG("FBO is %d _fbo %d color, %d ds", _fbo, RenderTargetBase::Type::Texture2D == _rt->getType() ? _rt->getTexture()->getName() : _rt->getBuffer(), nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); _fboBindingDirty = false; } if(GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) { CCLOG("FrameBuffer Status Error %d", (int)glCheckFramebufferStatus(GL_FRAMEBUFFER)); } CHECK_GL_ERROR_DEBUG(); }
bool FrameBuffer::init(uint8_t fid, unsigned int width, unsigned int height) { _fid = fid; _width = width; _height = height; GLint oldfbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfbo); glGenFramebuffers(1, &_fbo); glBindFramebuffer(GL_FRAMEBUFFER, _fbo); glBindFramebuffer(GL_FRAMEBUFFER, oldfbo); // _rt = RenderTarget::create(width, height); // if(nullptr == _rt) return false; #if CC_ENABLE_CACHE_TEXTURE_DATA _dirtyFBOListener = EventListenerCustom::create(EVENT_RENDERER_RECREATED, [this](EventCustom* event){ if(isDefaultFBO()) return; GLint oldfbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldfbo); glGenFramebuffers(1, &_fbo); glBindFramebuffer(GL_FRAMEBUFFER, _fbo); glBindFramebuffer(GL_FRAMEBUFFER, oldfbo); CCLOG("Recreate FrameBufferObject _fbo is %d", _fbo); _fboBindingDirty = true; }); Director::getInstance()->getEventDispatcher()->addEventListenerWithFixedPriority(_dirtyFBOListener, -1); #endif return true; }
void FrameBuffer::applyFBO() { CHECK_GL_ERROR_DEBUG(); glBindFramebuffer(GL_FRAMEBUFFER, _fbo); CHECK_GL_ERROR_DEBUG(); if(_fboBindingDirty && !isDefaultFBO()) { CHECK_GL_ERROR_DEBUG(); if(RenderTargetBase::Type::Texture2D == _rt->getType()) glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _rt->getTexture()->getName(), 0); else glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _rt->getBuffer()); CHECK_GL_ERROR_DEBUG(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); CHECK_GL_ERROR_DEBUG(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); CHECK_GL_ERROR_DEBUG(); CCLOG("FBO is %d _fbo %d color, %d ds", _fbo, RenderTargetBase::Type::Texture2D == _rt->getType() ? _rt->getTexture()->getName() : _rt->getBuffer(), nullptr == _rtDepthStencil ? 0 : _rtDepthStencil->getBuffer()); _fboBindingDirty = false; } if(GL_FRAMEBUFFER_COMPLETE != glCheckFramebufferStatus(GL_FRAMEBUFFER)) { CCLOG("FrameBuffer Status Error %d", (int)glCheckFramebufferStatus(GL_FRAMEBUFFER)); } CHECK_GL_ERROR_DEBUG(); }
FrameBuffer::~FrameBuffer() { { CC_SAFE_RELEASE_NULL(_rt); CC_SAFE_RELEASE_NULL(_rtDepthStencil); glDeleteFramebuffers(1, &_fbo); _fbo = 0; _frameBuffers.erase(this); #if CC_ENABLE_CACHE_TEXTURE_DATA Director::getInstance()->getEventDispatcher()->removeEventListener(_dirtyFBOListener); #endif if (isDefaultFBO()) _defaultFBO = nullptr; } }
void FrameBuffer::attachDepthStencilTarget(RenderTargetDepthStencil* rt) { if(isDefaultFBO()) { CCLOG("Can not apply depth stencil target to default FBO"); return; } if(nullptr != rt && (rt->getWidth() != _width || rt->getHeight() != _height)) { CCLOG("Error, attach a render target Depth stencil with different size, Skip."); return; } CC_SAFE_RETAIN(rt); CC_SAFE_RELEASE(_rtDepthStencil); _rtDepthStencil = rt; _fboBindingDirty = true; }
void FrameBuffer::attachRenderTarget(RenderTargetBase* rt) { if(isDefaultFBO()) { CCLOG("Can not apply render target to default FBO"); return; } CC_ASSERT(rt); if(rt->getWidth() != _width || rt->getHeight() != _height) { CCLOG("Error, attach a render target with different size, Skip."); return; } CC_SAFE_RETAIN(rt); CC_SAFE_RELEASE(_rt); _rt = rt; _fboBindingDirty = true; }