NBEngine/engine/NBGraphics/Textures.hpp
2026-07-19 22:20:05 -05:00

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