153 lines
3.7 KiB
C++
153 lines
3.7 KiB
C++
#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 <typename T>
|
|
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<int>& val_) {
|
|
declare();
|
|
glTexParameteriv(_id, param_, val_.data());
|
|
}
|
|
void parameter(GLenum param_, const std::vector<float>& val_) {
|
|
declare();
|
|
glTexParameterfv(_id, param_, val_.data());
|
|
}
|
|
void parameter(GLenum param_, const std::vector<unsigned int>& val_) {
|
|
declare();
|
|
glTexParameterIuiv(_id, param_, val_.data());
|
|
}
|
|
void generateMipmaps() const {
|
|
bind();
|
|
glGenerateMipmap(Target);
|
|
}
|
|
|
|
};
|
|
|
|
template<typename T>
|
|
class ImageTexture;
|
|
|
|
template<typename T>
|
|
struct OGLPixelFormat;
|
|
|
|
template<typename T, typename... Channels>
|
|
struct OGLPixelFormat<Pixel<T, Channels...>>;
|
|
|
|
template<>
|
|
struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue>> {
|
|
static constexpr GLenum glFormat = GL_RGB;
|
|
static constexpr GLenum glData = GL_UNSIGNED_BYTE;
|
|
};
|
|
|
|
template<>
|
|
struct OGLPixelFormat<Pixel<uint8_t, Red, Green, Blue, Alpha>> {
|
|
static constexpr GLenum glFormat = GL_RGBA;
|
|
static constexpr GLenum glData = GL_UNSIGNED_BYTE;
|
|
};
|
|
|
|
template<typename T, typename... Channels>
|
|
class ImageTexture<Pixel<T, Channels...>> : public Texture {
|
|
protected:
|
|
using Texture::Texture;
|
|
using PixelType = Pixel<T, Channels...>;
|
|
|
|
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<PixelType>& img, unsigned int layer) {
|
|
using Format = OGLPixelFormat<PixelType>;
|
|
declare();
|
|
glTexImage2D(
|
|
Target,
|
|
layer,
|
|
Format::glFormat,
|
|
img.width,
|
|
img.height,
|
|
0,
|
|
Format::glFormat,
|
|
Format::glData,
|
|
img.data()
|
|
);
|
|
}
|
|
void setImage(const Image<PixelType>& img, bool generateMipmap=true) {
|
|
setImage(img, (unsigned int)0);
|
|
if (generateMipmap) { generateMipmaps(); }
|
|
}
|
|
|
|
};
|
|
|
|
} // namespace nb
|
|
#endif // _NB_TEXTURES
|