our_dick/include/gfx/ogl/texture.hpp

209 lines
6.4 KiB
C++

/**
This file is a part of our_dick
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OUR_DICK_GRAPHICS_OGL_TEXTURE_HPP
#define OUR_DICK_GRAPHICS_OGL_TEXTURE_HPP
#include "egn/image.hpp"
#include "gl_include.hpp"
#include <rml/vec.hpp>
namespace gfx::ogl{
//class representing an opengl 2D texture
class texture_base
{
public:
//all available wrapping styles as a strongly typed enum
enum class wrap : GLint{
CLAMP_EDGE = GL_CLAMP_TO_EDGE,
CLAMP_BORDER = GL_CLAMP_TO_BORDER,
MIRROR_REPEAT = GL_MIRRORED_REPEAT,
REPEAT = GL_REPEAT,
MIRROR_CLAMP_EDGE = GL_MIRROR_CLAMP_TO_EDGE,
};
//all available minfilter styles as a strongly typed enum
enum class minfilter : GLint{
NEAREST = GL_NEAREST,
LINEAR = GL_LINEAR,
NMIPMAP_NEAREST = GL_NEAREST_MIPMAP_NEAREST,
LMIPMAP_NEAREST = GL_LINEAR_MIPMAP_NEAREST,
NMIPMAP_LINEAR = GL_NEAREST_MIPMAP_LINEAR,
LMIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR,
};
//all available magfilter styles as a strongly typed enum
enum class magfilter : GLint{
NEAREST = GL_NEAREST,
LINEAR = GL_LINEAR,
};
protected:
GLuint m_tex_id = 0; //handle to texture object
GLsizei m_width = 0;
GLsizei m_height = 0;
GLenum m_format = 0;
GLenum m_type = GL_UNSIGNED_BYTE;
bool m_mipmapped = true;
texture_base(void) = default;
texture_base(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap);
texture_base(const texture_base&);
texture_base(texture_base&&);
~texture_base(void);
texture_base& operator=(const texture_base&);
texture_base& operator=(texture_base&&);
public:
GLuint raw(void)const;
//change wrap mode for both x and y
void set_wrap_mode(wrap w);
void set_wrap_mode(wrap w, wrap h);
//change wrap mode for one direction
void set_wrap_x(wrap w);
void set_wrap_y(wrap h);
void set_border_color(GLfloat r, GLfloat g, GLfloat b, GLfloat a = 1.0f);
void set_filter(minfilter min, magfilter mag);
void set_mag_filter(magfilter m);
void set_min_filter(minfilter m);
magfilter get_mag_filter(void)const;
minfilter get_min_filter(void)const;
rml::vec4f get_border_color(void)const;
wrap get_wrap_x(void)const;
wrap get_wrap_y(void)const;
GLsizei get_width(void)const;
GLsizei get_height(void)const;
void enable_auto_mipmap(bool enable);
void generate_mipmap(void);
//release ownership of this texture object
GLuint release(void);
};
class texture : public texture_base
{
public:
//create the texture with no image data
texture(void);
texture(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
texture(GLenum format, GLsizei w, GLsizei h, GLenum type, bool mipmap = true);
//create the texture with image data from 'i'
texture(const egn::image& i, bool mipmap = true);
texture(const texture&);
texture(texture&&);
~texture(void) = default;
texture& operator=(const texture&);
texture& operator=(texture&&);
//overwrite the current image data with 'i'
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
bool set_image(const egn::image& i);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type,
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset);
//bind to target
void bind(GLuint target = GL_TEXTURE_2D)const;
//bind to given texture unit and load into given program uniform location
void bind_unit(GLuint tunit)const;
private:
bool create_texture_storage_(void);
};
class texture_array;
//Represents a single layer of a texture_array
class texture_slice
{
private:
texture_array* m_owner;
size_t m_level;
public:
texture_slice(texture_array* tex, int level);
texture_slice(const texture_slice&) = default;
texture_slice(texture_slice&&) = default;
~texture_slice(void) = default;
texture_slice& operator=(const texture_slice&) = default;
texture_slice& operator=(texture_slice&&) = default;
bool valid(void)const;
GLuint raw(void)const;
int get_level(void)const;
GLsizei get_width(void)const;
GLsizei get_height(void)const;
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type);
bool set_image(const egn::image& i);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type, GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset);
};
class texture_array : public texture_base
{
private:
size_t m_levels = 0;
public:
texture_array(void);
texture_array(size_t layers);
texture_array(const egn::image& i, size_t layers, bool mipmap = true);
texture_array(GLenum format, GLsizei w, GLsizei h, GLenum type, size_t layers, bool mipmap = true);
texture_array(const texture_array&);
texture_array(texture_array&&);
~texture_array(void) = default;
texture_array& operator=(const texture_array&);
texture_array& operator=(texture_array&&);
//overwrite the current image data with 'i'
bool set_image(const unsigned char* data, GLenum format, GLsizei w, GLsizei h, GLenum type, size_t layer);
bool set_image(const egn::image& i, size_t layer);
bool set_subimage(const unsigned char* data, GLenum format, GLenum type,
GLsizei xoffset, GLsizei yoffset, GLsizei w, GLsizei h, size_t layer);
bool set_subimage(const egn::image& i, GLsizei xoffset, GLsizei yoffset, size_t layer);
//bind to target
void bind(GLuint target = GL_TEXTURE_2D_ARRAY)const;
//bind to given texture unit and load into given program uniform location
void bind_unit(GLuint tunit)const;
texture_slice operator[](size_t layer);
private:
bool create_texture_storage_(void);
};
class texture_view
{
//TODO
//lookup glTextureView to remind yourself
};
}
#endif