gltexture2d.h File Reference

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

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

#include "gltexture.h"
#include "glimagetype.h"

namespace ffw {
    class FFW_API GLTexture2D: public GLTexture {
    public:
        GLTexture2D();
        GLTexture2D(const GLTexture2D& other) = delete;
        GLTexture2D(GLTexture2D&& other) NOEXCEPT;
        virtual ~GLTexture2D() = default;
        GLTexture2D(GLsizei width, GLsizei height, GLenum internalformat, GLenum format,
            GLenum pixelformat, const GLvoid* pixels = nullptr);
        void setPixels(GLint level, const GLvoid* pixels);
        void resize(GLsizei width, GLsizei height, const GLvoid* pixels = nullptr);
        void setPixels(GLint level, GLint xoffset, GLint yoffset, GLsizei width,
            GLsizei height, const GLvoid* pixels);
        void getPixels(void* pixels) const;
        GLTexture2D& operator = (const GLTexture2D& other) = delete;
        GLTexture2D& operator = (GLTexture2D&& other) NOEXCEPT;
#ifdef FFW_MEDIA_IMAGE_BUFFER
        friend bool createFromBuffer(GLTexture2D& self, const ImageBuffer& image, const bool inverse);
#endif
    private:
        void setPixelsInternal(GLint level, const GLvoid* pixels = nullptr) const;
        void setPixelsInternal(GLint level, GLint xoffset, GLint yoffset, GLsizei width,
            GLsizei height, const GLvoid* pixels) const;
        void create(GLsizei width, GLsizei height, GLenum internalformat, GLenum format,
            GLenum pixelformat, const GLvoid* pixels = nullptr);
    };

#ifdef FFW_MEDIA_IMAGE_BUFFER
    inline bool createFromBuffer(GLTexture2D& self, const ImageBuffer& image, const bool inverse) {
        if (!image.isAllocated())return false;
        if (image.getDepth() > 1)return false;

        const auto openglType = getOpenGLImageType(image.getImageType());
        if (!openglType) {
            return false;
        }

        if (image.isCompressed() && inverse)return false;

        self.destroy();
        self.create(image.getWidth(), image.getHeight(), openglType.internalFormat, 
            openglType.format, openglType.type);

        for(auto m = 0; m <= image.getNumOfMipMaps()-1; m++) {
                
            if(inverse) {
                if (m != 0)self.setPixelsInternal(m, nullptr); // Create mipmap
                for (auto i = 0; i < image.getHeight(m); i++) {
                    const auto ptr = &image.getMipMapPtr(m)[image.getStrideSize(m) * i];
                    self.setPixelsInternal(m, 0, image.getHeight(m) - i - 1, image.getWidth(m), 1, ptr);
                }
            }
            else {
                self.setPixelsInternal(m, image.getMipMapPtr(m));
            }
        }

        if(image.getNumOfMipMaps() > 0) {
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, image.getNumOfMipMaps()-1);
        }

        return true;
    }
#endif
};

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