#pragma once #ifndef _NB_TEXTURES #define _NB_TEXTURES #include "Buffers.hpp" #include "Image.hpp" #include "OGLObjects.hpp" namespace nb { class TextureBuffer : public virtual Buffer { public: TextureBuffer() : Buffer(GL_TEXTURE_BUFFER) {} }; class RenderTarget : public OpenGLObject { protected: using Base = OpenGLObject; using Base::_id; RenderTarget(GLenum target) : Target(target) {} RenderTarget(RenderTarget&& rhs) : Target(rhs.Target), Base(std::move(rhs)) {} public: using Base::Base; using Base::id; const GLenum Target; }; class Texture : public RenderTarget { protected: using Base = RenderTarget; using Base::_id; Texture(GLenum); virtual GLuint declare() override { if (!_id) { glGenTextures(1, &_id); } bind(); return _id; } virtual void remove() override { if (_id) { bind(); glDeleteTextures(0, &_id); } } public: using Base::Base; using Base::id; using Base::Target; virtual void bind() const override { if (_id) { glBindTexture(Target, _id); } else { THROW(OGLError( OGLError::Codes::INVALID_OBJECT, "w/ Texture" )); } } virtual void unbind() const override { glBindTexture(Target, 0); } template void parameter(GLenum param_, const T& val_); void parameter(GLenum param_, const int& val_) { declare(); glTexParameteri(_id, param_, val_); } void parameter(GLenum param_, const std::vector& val_) { declare(); glTexParameteriv(_id, param_, val_.data()); } void parameter(GLenum param_, const std::vector& val_) { declare(); glTexParameterfv(_id, param_, val_.data()); } void parameter(GLenum param_, const std::vector& val_) { declare(); glTexParameterIuiv(_id, param_, val_.data()); } void generateMipmaps() const { bind(); glGenerateMipmap(Target); } }; template class ImageTexture; template struct OGLPixelFormat; template struct OGLPixelFormat>; template<> struct OGLPixelFormat> { static constexpr GLenum glFormat = GL_RGB; static constexpr GLenum glData = GL_UNSIGNED_BYTE; }; template<> struct OGLPixelFormat> { static constexpr GLenum glFormat = GL_RGBA; static constexpr GLenum glData = GL_UNSIGNED_BYTE; }; template class ImageTexture> : public Texture { protected: using Texture::Texture; using PixelType = Pixel; public: using Texture::generateMipmaps; ImageTexture() : Texture(GL_TEXTURE_2D) {} ImageTexture(ImageTexture&& cpy) { *this = std::move(cpy); } ImageTexture& operator=(ImageTexture&& rhs) { return Texture::operator=(std::move(rhs)); } void setImage(const Image& img, unsigned int layer) { using Format = OGLPixelFormat; declare(); glTexImage2D( Target, layer, Format::glFormat, img.width, img.height, 0, Format::glFormat, Format::glData, img.data() ); } void setImage(const Image& img, bool generateMipmap=true) { setImage(img, (unsigned int)0); if (generateMipmap) { generateMipmaps(); } } }; } // namespace nb #endif // _NB_TEXTURES