#ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H #include "data/Array.h" #include "data/ArrayList.h" #include "math/Vector.h" #include "rendering/Texture.h" template class Framebuffer final { Array textures; GL::Framebuffer buffer; public: Framebuffer() : buffer(0) { } ~Framebuffer() { GL::deleteFramebuffers(buffer); } Framebuffer(const Framebuffer&) = delete; Framebuffer(Framebuffer&&) = delete; Framebuffer& operator=(const Framebuffer&) = delete; Framebuffer& operator=(Framebuffer&&) = delete; template Error init(const IntVector2& size, Args&&... args) { const int n = sizeof...(args); Texture::Format init[static_cast(n)] = {args...}; static_assert(N == n, "framebuffer size and amount of arguments do not match"); for(int i = 0; i < N; i++) { textures[i].init(init[i], 0); textures[i].setClampWrap(); if(init[i].linear) { textures[i].setLinearFilter(); } } buffer = GL::genFramebuffer(); GL::bindFramebuffer(buffer); ArrayList attachments; for(Texture& t : textures) { t.setData(size[0], size[1]); if(t.format.depth) { GL::framebufferDepthTexture2D(t.texture); } else { attachments.add(GL::framebufferColorTexture2D( t.texture, attachments.getLength())); } } GL::drawBuffers(attachments.getLength(), attachments.begin()); return GL::getFramebufferError(); } void bindAndClear() { GL::bindFramebuffer(buffer); GL::clear(); } void bindTextureTo(int index, int textureUnit) const { textures[index].bindTo(textureUnit); } void resize(const IntVector2& size) { for(Texture& t : textures) { t.setData(size[0], size[1]); } } }; #endif