#ifndef FRAMEBUFFER_H #define FRAMEBUFFER_H #include #include "rendering/Texture.h" #include "utils/ArrayList.h" #include "utils/Size.h" template class Framebuffer final { ArrayList textures; GL::Framebuffer buffer; public: template Framebuffer(const TextureFormat& a, Args&&... args) : buffer(0) { const int size = sizeof...(args) + 1; TextureFormat init[size] = {a, args...}; static_assert(N == size, "framebuffer size and amount of arguments do not match"); for(int i = 0; i < N; i++) { textures.add(init[i]); textures[i].setClampWrap(); if(init[i].linear) { textures[i].setLinearFilter(); } } } ~Framebuffer() { GL::deleteFramebuffers(buffer); } Framebuffer(const Framebuffer&) = delete; Framebuffer(Framebuffer&&) = delete; Framebuffer& operator=(const Framebuffer&) = delete; Framebuffer& operator=(Framebuffer&&) = delete; bool init(const Size& size) { buffer = GL::genFramebuffer(); GL::bindFramebuffer(buffer); ArrayList attachments; for(Texture& t : textures) { t.setData(size.width, size.height); 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::printFramebufferError(); } void bindAndClear() { GL::bindFramebuffer(buffer); GL::clear(); } void bindTextureTo(int index, int textureUnit) const { textures[index].bindTo(textureUnit); } void resize(const Size& size) { for(Texture& t : textures) { t.setData(size.width, size.height); } } }; #endif