bool OGLCoreFramebuffer::setup(const GraphicsFramebufferDesc& framebufferDesc) noexcept { assert(GL_NONE == _fbo); assert(framebufferDesc.getGraphicsFramebufferLayout()); assert(framebufferDesc.getGraphicsFramebufferLayout()->isInstanceOf<OGLFramebufferLayout>()); assert(framebufferDesc.getWidth() > 0 && framebufferDesc.getHeight() > 0); glCreateFramebuffers(1, &_fbo); if (_fbo == GL_NONE) { this->getDevice()->downcast<OGLDevice>()->message("glCreateFramebuffers() fail"); return false; } GLenum drawCount = 0; GLenum drawBuffers[GL_COLOR_ATTACHMENT15 - GL_COLOR_ATTACHMENT0]; const auto& textureComponents = framebufferDesc.getGraphicsFramebufferLayout()->getGraphicsFramebufferLayoutDesc().getComponents(); const auto& colorAttachments = framebufferDesc.getColorAttachments(); if (colorAttachments.size() > (sizeof(drawBuffers) / sizeof(drawBuffers[0]))) { this->getDevice()->downcast<OGLDevice>()->message("The color attachment in framebuffer is out of range."); return false; } for (std::size_t i = 0; i < textureComponents.size(); i++) { auto type = textureComponents[i].getAttachType(); switch (type) { case GraphicsImageLayout::GraphicsImageLayoutGeneral: break; case GraphicsImageLayout::GraphicsImageLayoutColorAttachmentOptimal: { GLint slot = GL_COLOR_ATTACHMENT0 + textureComponents[i].getAttachSlot(); GLint mipLevel = colorAttachments[drawCount].getBindingLevel(); GLint layer = colorAttachments[drawCount].getBindingLayer(); if (!this->bindRenderTexture(colorAttachments[drawCount].getBindingTexture(), slot, mipLevel, layer)) return false; drawBuffers[drawCount++] = slot; } break; case GraphicsImageLayout::GraphicsImageLayoutDepthStencilAttachmentOptimal: case GraphicsImageLayout::GraphicsImageLayoutDepthStencilReadOnlyOptimal: { const auto& depthStencilAttachment = framebufferDesc.getDepthStencilAttachment(); if (!depthStencilAttachment.getBindingTexture()) { this->getDevice()->downcast<OGLDevice>()->message("Need depth or stencil texture."); return false; } auto texture = depthStencilAttachment.getBindingTexture(); auto format = texture->getGraphicsTextureDesc().getTexFormat(); auto level = depthStencilAttachment.getBindingLevel(); auto layer = depthStencilAttachment.getBindingLayer(); if (OGLTypes::isDepthStencilFormat(format)) { if (!this->bindRenderTexture(texture, GL_DEPTH_STENCIL_ATTACHMENT, level, layer)) return false; } else if (OGLTypes::isDepthFormat(format)) { if (!this->bindRenderTexture(texture, GL_DEPTH_ATTACHMENT, level, layer)) return false; } else if (OGLTypes::isStencilFormat(format)) { if (!this->bindRenderTexture(texture, GL_STENCIL_ATTACHMENT, level, layer)) return false; } else { this->getDevice()->downcast<OGLDevice>()->message("Invalid texture format"); return false; } } case GraphicsImageLayout::GraphicsImageLayoutShaderReadOnlyOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutTransferSrcOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutTransferDstOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutPreinitialized: break; case GraphicsImageLayout::GraphicsImageLayoutPresentSrcKhr: break; default: break; } } glNamedFramebufferDrawBuffers(_fbo, drawCount, drawBuffers); _framebufferDesc = framebufferDesc; return OGLCheck::checkError(); }
bool EGL2Framebuffer::setup(const GraphicsFramebufferDesc& framebufferDesc) noexcept { assert(GL_NONE == _fbo); assert(framebufferDesc.getGraphicsFramebufferLayout()); assert(framebufferDesc.getWidth() > 0 && framebufferDesc.getHeight() > 0); std::uint32_t numAttachment = framebufferDesc.getColorAttachments().size(); if (numAttachment > 1) { GL_PLATFORM_LOG("Can't support multi framebuffer"); return false; } GL_CHECK(glGenFramebuffers(1, &_fbo)); if (_fbo == GL_NONE) { GL_PLATFORM_LOG("glCreateFramebuffers() fail"); return false; } GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, _fbo)); const auto& textureComponents = framebufferDesc.getGraphicsFramebufferLayout()->getGraphicsFramebufferLayoutDesc().getComponents(); const auto& colorAttachments = framebufferDesc.getColorAttachments(); for (std::size_t i = 0; i < textureComponents.size(); i++) { auto type = textureComponents[i].getAttachType(); switch (type) { case GraphicsImageLayout::GraphicsImageLayoutGeneral: break; case GraphicsImageLayout::GraphicsImageLayoutColorAttachmentOptimal: { GLint slot = GL_COLOR_ATTACHMENT0 + textureComponents[i].getAttachSlot(); GLint mipLevel = colorAttachments[0].getBindingLevel(); GLint layer = colorAttachments[0].getBindingLayer(); if (!this->bindRenderTexture(colorAttachments[0].getBindingTexture(), slot, mipLevel, layer)) return false; } break; case GraphicsImageLayout::GraphicsImageLayoutDepthStencilAttachmentOptimal: case GraphicsImageLayout::GraphicsImageLayoutDepthStencilReadOnlyOptimal: { const auto& depthStencilAttachment = framebufferDesc.getDepthStencilAttachment(); if (!depthStencilAttachment.getBindingTexture()) { GL_PLATFORM_LOG("Need depth or stencil texture."); return false; } auto texture = depthStencilAttachment.getBindingTexture(); auto format = texture->getGraphicsTextureDesc().getTexFormat(); auto level = depthStencilAttachment.getBindingLevel(); auto layer = depthStencilAttachment.getBindingLayer(); if (EGL2Types::isDepthFormat(format)) { if (!this->bindRenderTexture(texture, GL_DEPTH_ATTACHMENT, level, layer)) return false; } else if (EGL2Types::isStencilFormat(format)) { if (!this->bindRenderTexture(texture, GL_STENCIL_ATTACHMENT, level, layer)) return false; } else { GL_PLATFORM_LOG("Invalid texture format"); return false; } } case GraphicsImageLayout::GraphicsImageLayoutShaderReadOnlyOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutTransferSrcOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutTransferDstOptimal: break; case GraphicsImageLayout::GraphicsImageLayoutPreinitialized: break; case GraphicsImageLayout::GraphicsImageLayoutPresentSrcKhr: break; default: break; } } GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE)); _framebufferDesc = framebufferDesc; return EGL2Check::checkError(); }