glframebuffer.h File Reference

Go to the documentation of this file. Source: include/ffw/graphics/glframebuffer.h

/* This file is part of FineFramework project */
#ifndef FFW_GRAPHICS_FRAMEBUFFER
#define FFW_GRAPHICS_FRAMEBUFFER

#include "glrenderextensions.h"
#include "gltexture2d.h"
#include "gltexture2dms.h"
#include "glrenderbuffer2d.h"
#include "glrenderbuffer2dms.h"
#include "gltexturecubemap.h"
#include <functional>

namespace ffw {
    class FFW_API GLFramebuffer {
    public:
        class Attachment {
        public:
            Attachment(const ffw::GLTexture2D* texture, const GLenum attachment, const GLint level = 0) {
                action = [=](GLFramebuffer& fbo){
                    fbo.addTexture(attachment, GL_TEXTURE_2D, texture->getHandle(), level);
                };
            }
            Attachment(const ffw::GLTexture2DMS* texture, const GLenum attachment, const GLint level = 0) {
                action = [=](GLFramebuffer& fbo) {
                    fbo.addTexture(attachment, GL_TEXTURE_2D_MULTISAMPLE, texture->getHandle(), level);
                };
            }
            Attachment(const ffw::GLRenderbuffer2D* texture, const GLenum attachment, const GLint level = 0) {
                action = [=](GLFramebuffer& fbo) {
                    fbo.addRenderbuffer(attachment, texture->getHandle());
                };
            }
            Attachment(const ffw::GLRenderbuffer2DMS* texture, const GLenum attachment, const GLint level = 0) {
                action = [=](GLFramebuffer& fbo) {
                    fbo.addRenderbuffer(attachment, texture->getHandle());
                };
            }
            Attachment(const ffw::GLTextureCubemap* texture, const GLenum attachment, const int side, const GLint level = 0) {
                action = [=](GLFramebuffer& fbo) {
                    fbo.addTexture(attachment, GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, texture->getHandle(), level);
                };
            }
            void operator()(GLFramebuffer& fbo) const {
                action(fbo);
            }
        private:
            std::function<void(GLFramebuffer&)> action;
        };
        static const std::initializer_list<Attachment> NO_ATTACHMENTS;
        GLFramebuffer(const std::initializer_list<Attachment>& attachments);
        template<typename Iterator>
        GLFramebuffer(Iterator begin, Iterator end):GLFramebuffer({}) {
            for (auto it = begin; it != end; ++it) {
                *it(*this);
            }
        }
        GLFramebuffer();
        GLFramebuffer(const GLFramebuffer& other) = delete;
        GLFramebuffer(GLFramebuffer&& other) NOEXCEPT;
        void swap(GLFramebuffer& other) NOEXCEPT;
        ~GLFramebuffer();
        inline bool isCreated() const {
            return created;
        }
        void addTexture(GLenum attachment, GLuint textype, GLuint texture, GLint level = 0) const;
        void addRenderbuffer(GLenum attachment, GLuint texture) const;
        inline void addStencilTexture(const ffw::GLTexture2D* texture, const GLint level = 0) {
            addTexture(GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture->getHandle(), level);
        }
        inline void addStencilBuffer(const ffw::GLRenderbuffer2D* texture) {
            addRenderbuffer(GL_STENCIL_ATTACHMENT, texture->getHandle());
        }
        void addColorTexture(const ffw::GLTexture2D* texture, const GLint level = 0) {
            addTexture(GL_COLOR_ATTACHMENT0 + colorcount,
                GL_TEXTURE_2D, texture->getHandle(), level);
            colorcount++;
        }
        void addCubemapTexture(const ffw::GLTextureCubemap* texture,
            const GLint side, const GLint level = 0) {
            addTexture(GL_COLOR_ATTACHMENT0 + colorcount,
                GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, texture->getHandle(), level);
            colorcount++;
        }
        void addDepthTexture(const ffw::GLTexture2D* texture, const GLint level = 0) {
            addTexture(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 
                texture->getHandle(), level);
        }
        void addColorTextureMS(const ffw::GLTexture2DMS* texture, const GLint level = 0) {
            addTexture(GL_COLOR_ATTACHMENT0 + colorcount, GL_TEXTURE_2D_MULTISAMPLE,
                texture->getHandle(), level);
            colorcount++;
        }
        void addDepthTextureMS(const ffw::GLTexture2DMS* texture, const GLint level = 0) {
            addTexture(GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, 
                texture->getHandle(), level);
        }
        void addColorRenderbuffer(const ffw::GLRenderbuffer2D* texture) {
            addRenderbuffer(GL_COLOR_ATTACHMENT0 + colorcount, 
                texture->getHandle());
            colorcount++;
        }
        void addDepthRenderbuffer(const ffw::GLRenderbuffer2D* texture) {
            addRenderbuffer(GL_DEPTH_ATTACHMENT, texture->getHandle());
        }
        void addColorRenderbufferMS(const ffw::GLRenderbuffer2DMS* texture) {
            addRenderbuffer(GL_COLOR_ATTACHMENT0 + colorcount, 
                texture->getHandle());
            colorcount++;
        }
        void addDepthRenderbufferMS(const ffw::GLRenderbuffer2DMS* texture) {
            addRenderbuffer(GL_DEPTH_ATTACHMENT, texture->getHandle());
        }
        bool checkStatus();
        inline unsigned int getHandle() const {
            return fbo;
        }
        inline void resetColorCount() {
            colorcount = 0;
        }
        bool destroy();
        void bind() const;
        void unbind() const;
        GLFramebuffer& operator = (const GLFramebuffer& other) = delete;
        GLFramebuffer& operator = (GLFramebuffer&& other) NOEXCEPT;
    private:
        bool created;
        unsigned int fbo;
        int colorcount;
    };
};

inline void swap(ffw::GLFramebuffer& first, ffw::GLFramebuffer& second) NOEXCEPT {
    first.swap(second);
}
#endif