diff --git a/include/Cubed/render/texture.hpp b/include/Cubed/render/texture.hpp new file mode 100644 index 0000000..022eeec --- /dev/null +++ b/include/Cubed/render/texture.hpp @@ -0,0 +1,90 @@ +#pragma once +#include +#include +namespace Cubed { + +enum TextureType : GLenum { + TEXTURE_2D = GL_TEXTURE_2D, + TEXTURE_2D_ARRAY = GL_TEXTURE_2D_ARRAY +}; + +enum TexturePname : GLenum { + MIN_FILTER = GL_TEXTURE_MIN_FILTER, + MAG_FILTER = GL_TEXTURE_MAG_FILTER, + WRAP_S = GL_TEXTURE_WRAP_S, + WRAP_T = GL_TEXTURE_WRAP_T, + WRAP_R = GL_TEXTURE_WRAP_R, + BORDER_COLOR = GL_TEXTURE_BORDER_COLOR, + COMPARE_MODE = GL_TEXTURE_COMPARE_MODE +}; + +enum TextureParam : GLenum { + LINEAR = GL_LINEAR, + NEAREST = GL_NEAREST, + LINEAR_MIPMAP_LINEAR = GL_LINEAR_MIPMAP_LINEAR, + CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER, + CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE, + T_NONE = GL_NONE, + REPEAT = GL_REPEAT +}; + +enum TextureFormat : GLenum { + DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F, + DEPTH_COMPONENT = GL_DEPTH_COMPONENT, + R16F = GL_R16F, + RED = GL_RED, + RGBA = GL_RGBA, + RGBA8 = GL_RGBA8, + +}; + +class Texture { +public: + explicit Texture(TextureType type); + ~Texture(); + Texture(const Texture&) = delete; + Texture(Texture&&) noexcept; + Texture& operator=(const Texture&) = delete; + Texture& operator=(Texture&&) noexcept; + + void bind() const; + void bind(size_t unit) const; + static void unbind(); + static void active(size_t id); + GLuint id() const; + + void parameter(TexturePname pname, TextureParam param) const; + void parameterfv(TexturePname pname, const float* param) const; + + void tex_image_2d(TextureFormat internalformat, TextureFormat format, + GLenum type, const void* data, GLsizei width, + GLsizei height, GLint level = 0, GLint border = 0) const; + + void tex_image_3d(TextureFormat internalformat, TextureFormat format, + GLenum type, const void* data, GLsizei width, + GLsizei height, GLsizei depth, GLint level = 0, + GLint border = 0) const; + + void tex_sub_image_3d(TextureFormat format, GLenum type, const void* data, + GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth = 1, + GLint level = 0) const; + + void set_aniso(int aniso) const; + + void gen_mipmap() const; + + void set_linear() const; + void set_nearest_and_minpmap() const; + void set_nearest() const; + void set_repeat(bool r = true, bool s = true, bool t = true) const; + void set_clamp_to_border(bool r = true, bool s = true, bool t = true) const; + void set_clamp_to_edge(bool r = true, bool s = true, bool t = true) const; + +private: + GLuint m_id = 0; + const TextureType M_TYPE; + + GLenum get_gl_texture_type() const; +}; +} // namespace Cubed \ No newline at end of file diff --git a/include/Cubed/texture_manager.hpp b/include/Cubed/texture_manager.hpp index 130b92d..a0d2e80 100644 --- a/include/Cubed/texture_manager.hpp +++ b/include/Cubed/texture_manager.hpp @@ -1,7 +1,9 @@ #pragma once #include "Cubed/gameplay/block.hpp" +#include "Cubed/render/texture.hpp" #include +#include namespace Cubed { @@ -9,19 +11,17 @@ class TextureManager { private: bool m_need_reload = false; bool m_init = false; - GLuint m_block_status_array = 0; - GLuint m_texture_array = 0; - GLuint m_cross_plane_array = 0; - GLuint m_ui_array = 0; - GLuint m_normal_texture_array = 0; + std::unique_ptr m_block_status_array; + std::unique_ptr m_texture_array; + std::unique_ptr m_cross_plane_array; + std::unique_ptr m_ui_array; + std::unique_ptr m_normal_texture_array; + std::unique_ptr m_skin; + std::vector> m_item_textures; GLfloat m_max_aniso = 0.0f; - GLuint m_skin = 0; - int m_aniso = 1; - std::vector m_item_textures; - void load_block_status(unsigned status_id); void load_block_texture(unsigned block_id); void load_block_item_texture(unsigned id); @@ -45,7 +45,7 @@ public: GLuint get_cross_plane_array() const; GLuint get_ui_array() const; GLuint get_pbr_texture() const; - const std::vector& item_textures() const; + const std::vector>& item_textures() const; GLuint get_skin() const; // Must call after MapTable::init_map() and glfwMakeContextCurrent(window); void init_texture(); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 32ab8e2..e3ccd42 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -56,4 +56,5 @@ target_sources(${PROJECT_NAME} audio/audio_effect_slot.cpp render/vertex_buffer.cpp render/vertex_array.cpp + render/texture.cpp ) \ No newline at end of file diff --git a/src/dev_panel.cpp b/src/dev_panel.cpp index e46ec54..3bae7c4 100644 --- a/src/dev_panel.cpp +++ b/src/dev_panel.cpp @@ -651,13 +651,14 @@ void DevPanel::show_items_tab_item() { ImGui::Text("Place Block "); ImGui::SameLine(); ImGui::Image(static_cast(static_cast( - textures[m_player->place_block()])), + textures[m_player->place_block()]->id())), ImVec2{48, 48}); for (size_t i = 1; i < textures.size(); i++) { - if (ImGui::ImageButton(("##item" + std::to_string(i)).c_str(), - static_cast( - static_cast(textures[i])), - ImVec2{48, 48})) { + if (ImGui::ImageButton( + ("##item" + std::to_string(i)).c_str(), + static_cast( + static_cast(textures[i]->id())), + ImVec2{48, 48})) { m_player->set_place_block(i); } if (ImGui::IsItemHovered()) { diff --git a/src/render/texture.cpp b/src/render/texture.cpp new file mode 100644 index 0000000..bc47b6e --- /dev/null +++ b/src/render/texture.cpp @@ -0,0 +1,147 @@ +#include "Cubed/render/texture.hpp" + +#include "Cubed/tools/cubed_assert.hpp" + +#include + +namespace Cubed { +Texture::Texture(TextureType type) : M_TYPE(type) { glGenTextures(1, &m_id); } +Texture::~Texture() { + if (m_id) { + glDeleteTextures(1, &m_id); + } +} +Texture::Texture(Texture&& o) noexcept + : m_id(std::exchange(o.m_id, 0)), M_TYPE(o.M_TYPE) {} + +Texture& Texture::operator=(Texture&& o) noexcept { + if (this == &o) { + return *this; + } + if (M_TYPE != o.M_TYPE) { + ASSERT_MSG(false, "Texture Type is not same"); + } + if (m_id) { + glDeleteTextures(1, &m_id); + } + + m_id = std::exchange(o.m_id, 0); + return *this; +} +void Texture::bind() const { glBindTexture(get_gl_texture_type(), m_id); } + +void Texture::bind(size_t unit) const { + active(unit); + bind(); +} + +GLuint Texture::id() const { return m_id; } + +void Texture::parameter(TexturePname pname, TextureParam param) const { + bind(); + glTexParameteri(get_gl_texture_type(), std::to_underlying(pname), + std::to_underlying(param)); +} +void Texture::parameterfv(TexturePname pname, const float* param) const { + bind(); + glTexParameterfv(get_gl_texture_type(), std::to_underlying(pname), param); +} +void Texture::tex_image_2d(TextureFormat internalformat, TextureFormat format, + GLenum type, const void* data, GLsizei width, + GLsizei height, GLint level, GLint border) const { + bind(); + glTexImage2D(get_gl_texture_type(), level, + std::to_underlying(internalformat), width, height, border, + std::to_underlying(format), type, data); +} + +void Texture::tex_image_3d(TextureFormat internalformat, TextureFormat format, + GLenum type, const void* data, GLsizei width, + GLsizei height, GLsizei depth, GLint level, + GLint border) const { + bind(); + glTexImage3D(get_gl_texture_type(), level, + std::to_underlying(internalformat), width, height, depth, + border, std::to_underlying(format), type, data); +} +void Texture::tex_sub_image_3d(TextureFormat format, GLenum type, + const void* data, GLint xoffset, GLint yoffset, + GLint zoffset, GLsizei width, GLsizei height, + GLsizei depth, GLint level) const { + bind(); + glTexSubImage3D(get_gl_texture_type(), level, xoffset, yoffset, zoffset, + width, height, depth, std::to_underlying(format), type, + data); +} +void Texture::set_aniso(int aniso) const { + if (aniso >= 1) { + bind(); + glTexParameterf(get_gl_texture_type(), GL_TEXTURE_MAX_ANISOTROPY, + static_cast(aniso)); + } +} + +void Texture::gen_mipmap() const { + bind(); + glGenerateMipmap(get_gl_texture_type()); +} + +void Texture::set_linear() const { + parameter(TexturePname::MIN_FILTER, TextureParam::LINEAR); + parameter(TexturePname::MAG_FILTER, TextureParam::LINEAR); +} +void Texture::set_nearest_and_minpmap() const { + parameter(TexturePname::MAG_FILTER, TextureParam::NEAREST); + parameter(TexturePname::MIN_FILTER, TextureParam::LINEAR_MIPMAP_LINEAR); + gen_mipmap(); +} +void Texture::set_nearest() const { + parameter(TexturePname::MAG_FILTER, TextureParam::NEAREST); + parameter(TexturePname::MIN_FILTER, TextureParam::NEAREST); +} +void Texture::set_repeat(bool r, bool s, bool t) const { + if (r) { + parameter(TexturePname::WRAP_R, TextureParam::REPEAT); + } + if (s) { + parameter(TexturePname::WRAP_S, TextureParam::REPEAT); + } + if (t) { + parameter(TexturePname::WRAP_T, TextureParam::REPEAT); + } +} +void Texture::set_clamp_to_border(bool r, bool s, bool t) const { + if (r) { + parameter(TexturePname::WRAP_R, TextureParam::CLAMP_TO_BORDER); + } + if (s) { + parameter(TexturePname::WRAP_S, TextureParam::CLAMP_TO_BORDER); + } + if (t) { + parameter(TexturePname::WRAP_T, TextureParam::CLAMP_TO_BORDER); + } +} + +void Texture::set_clamp_to_edge(bool r, bool s, bool t) const { + if (r) { + parameter(TexturePname::WRAP_R, TextureParam::CLAMP_TO_EDGE); + } + if (s) { + parameter(TexturePname::WRAP_S, TextureParam::CLAMP_TO_EDGE); + } + if (t) { + parameter(TexturePname::WRAP_T, TextureParam::CLAMP_TO_EDGE); + } +} + +void Texture::unbind() { + glBindTexture(GL_TEXTURE_2D, 0); + glBindTexture(GL_TEXTURE_2D_ARRAY, 0); +} +void Texture::active(size_t id) { glActiveTexture(GL_TEXTURE0 + id); } + +GLenum Texture::get_gl_texture_type() const { + return std::to_underlying(M_TYPE); +} + +} // namespace Cubed \ No newline at end of file diff --git a/src/texture_manager.cpp b/src/texture_manager.cpp index 99065fd..1729eae 100644 --- a/src/texture_manager.cpp +++ b/src/texture_manager.cpp @@ -38,49 +38,56 @@ TextureManager::~TextureManager() { delet_texture(); } void TextureManager::delet_texture() { if (m_init) { - glDeleteTextures(1, &m_texture_array); - glDeleteTextures(1, &m_block_status_array); - glDeleteTextures(1, &m_cross_plane_array); - glDeleteTextures(1, &m_normal_texture_array); + m_texture_array.reset(); + m_block_status_array.reset(); + m_cross_plane_array.reset(); + m_normal_texture_array.reset(); for (auto& id : m_item_textures) { - glDeleteTextures(1, &id); + id.reset(); } - glDeleteTextures(1, &m_skin); + m_skin.reset(); Logger::info("Successfully delete all texture"); } } GLuint TextureManager::get_block_status_array() const { - return m_block_status_array; + return m_block_status_array->id(); } -GLuint TextureManager::get_texture_array() const { return m_texture_array; } +GLuint TextureManager::get_texture_array() const { + return m_texture_array->id(); +} GLuint TextureManager::get_cross_plane_array() const { - return m_cross_plane_array; + return m_cross_plane_array->id(); } -GLuint TextureManager::get_ui_array() const { return m_ui_array; } +GLuint TextureManager::get_ui_array() const { return m_ui_array->id(); } GLuint TextureManager::get_pbr_texture() const { - return m_normal_texture_array; + return m_normal_texture_array->id(); } -const std::vector& TextureManager::item_textures() const { +const std::vector>& +TextureManager::item_textures() const { return m_item_textures; } -GLuint TextureManager::get_skin() const { return m_skin; } +GLuint TextureManager::get_skin() const { return m_skin->id(); } void TextureManager::load_block_status(unsigned id) { ASSERT_MSG(id < MAX_BLOCK_STATUS, "Exceed the max status sum limit"); + std::string path = "texture/status/" + std::to_string(id) + ".png"; + unsigned char* image_data = nullptr; + image_data = (Tools::load_image_data(path)); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id, BLOCK_STATUS_SIZE, - BLOCK_STATUS_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, - image_data); + + m_block_status_array->tex_sub_image_3d( + TextureFormat::RGBA, GL_UNSIGNED_BYTE, image_data, 0, 0, id, + BLOCK_STATUS_SIZE, BLOCK_STATUS_SIZE); + Tools::delete_image_data(image_data); } @@ -107,12 +114,11 @@ void TextureManager::load_block_texture(unsigned id) { image_data[4] = (Tools::load_image_data(block_texture_path + "/top.png")); image_data[5] = (Tools::load_image_data(block_texture_path + "/base.png")); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_array); Tools::check_opengl_error(); for (int i = 0; i < 6; i++) { - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id * 6 + i, BLOCK_SIZE, - BLOCK_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, - image_data[i]); + m_texture_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE, + image_data[i], 0, 0, id * 6 + i, + BLOCK_SIZE, BLOCK_SIZE); Tools::check_opengl_error(); Tools::delete_image_data(image_data[i]); } @@ -126,21 +132,16 @@ void TextureManager::load_block_item_texture(unsigned id) { std::string path = "texture/item/block/" + name + ".png"; unsigned char* data = nullptr; data = Tools::load_image_data(path); - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, BLOCK_ITEM_SIZE, BLOCK_ITEM_SIZE, - 0, GL_RGBA, GL_UNSIGNED_BYTE, data); + std::unique_ptr texture = + std::make_unique(TextureType::TEXTURE_2D); + texture->tex_image_2d(TextureFormat::RGBA8, TextureFormat::RGBA, + GL_UNSIGNED_BYTE, data, BLOCK_ITEM_SIZE, + BLOCK_ITEM_SIZE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D); - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } - m_item_textures.push_back(texture); + texture->set_nearest(); + texture->set_clamp_to_border(); + + m_item_textures.push_back(std::move(texture)); Tools::delete_image_data(data); } @@ -148,10 +149,10 @@ void TextureManager::load_cross_plane_texture(unsigned id) { std::string path = "texture/block/" + BlockManager::name_form_id(id) + "/cross.png"; unsigned char* image_data = Tools::load_image_data(path); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, - BlockManager::cross_plane_index(id), CROSS_PLANE_SIZE, - CROSS_PLANE_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, image_data); + m_cross_plane_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE, + image_data, 0, 0, + BlockManager::cross_plane_index(id), + CROSS_PLANE_SIZE, CROSS_PLANE_SIZE); Tools::delete_image_data(image_data); } @@ -161,9 +162,8 @@ void TextureManager::load_ui_texture(unsigned id) { std::string path = "texture/ui/" + std::to_string(id) + ".png"; unsigned char* image_data = nullptr; image_data = (Tools::load_image_data(path)); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id, UI_SIZE, UI_SIZE, 1, - GL_RGBA, GL_UNSIGNED_BYTE, image_data); + m_ui_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE, + image_data, 0, 0, id, UI_SIZE, UI_SIZE); Tools::delete_image_data(image_data); } @@ -189,7 +189,6 @@ void TextureManager::load_pbr_texture(unsigned id) { image_data[4] = (Tools::load_image_data(path + "/top_n.png", false)); image_data[5] = (Tools::load_image_data(path + "/base_n.png", false)); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_normal_texture_array); for (int i = 0; i < 6; i++) { unsigned char* data = image_data[i]; bool is_fallback = false; @@ -197,9 +196,10 @@ void TextureManager::load_pbr_texture(unsigned id) { is_fallback = true; data = generate_flat_normal_map(); } - glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id * 6 + i, - BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE, 1, GL_RGBA, - GL_UNSIGNED_BYTE, data); + m_normal_texture_array->tex_sub_image_3d( + TextureFormat::RGBA, GL_UNSIGNED_BYTE, data, 0, 0, id * 6 + i, + BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE); + if (is_fallback) { delete[] data; } else { @@ -209,125 +209,78 @@ void TextureManager::load_pbr_texture(unsigned id) { } void TextureManager::init_block() { + m_texture_array = std::make_unique(TextureType::TEXTURE_2D_ARRAY); + m_texture_array->tex_image_3d(TextureFormat::RGBA, TextureFormat::RGBA, + GL_UNSIGNED_BYTE, nullptr, BLOCK_SIZE, + BLOCK_SIZE, BlockManager::sums() * 6); - glGenTextures(1, &m_texture_array); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_array); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, BLOCK_SIZE, BLOCK_SIZE, - BlockManager::sums() * 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, - nullptr); + m_cross_plane_array = + std::make_unique(TextureType::TEXTURE_2D_ARRAY); + m_cross_plane_array->tex_image_3d( + TextureFormat::RGBA, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr, + CROSS_PLANE_SIZE, CROSS_PLANE_SIZE, BlockManager::cross_plane_sum()); - glGenTextures(1, &m_cross_plane_array); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, CROSS_PLANE_SIZE, - CROSS_PLANE_SIZE, BlockManager::cross_plane_sum(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, nullptr); - glGenTextures(1, &m_normal_texture_array); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_normal_texture_array); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, BLOCK_NORMAL_SIZE, - BLOCK_NORMAL_SIZE, BlockManager::sums() * 6, 0, GL_RGBA, - GL_UNSIGNED_BYTE, nullptr); + m_normal_texture_array = + std::make_unique(TextureType::TEXTURE_2D_ARRAY); + m_normal_texture_array->tex_image_3d( + TextureFormat::RGBA8, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr, + BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE, BlockManager::sums() * 6); for (unsigned i = 0; i < BlockManager::sums(); i++) { load_block_texture(i); load_block_item_texture(i); load_pbr_texture(i); } - glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_array); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); - glGenerateMipmap(GL_TEXTURE_2D_ARRAY); - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } + m_texture_array->set_nearest_and_minpmap(); + m_texture_array->set_repeat(false, true, true); + m_texture_array->set_aniso(m_aniso); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glGenerateMipmap(GL_TEXTURE_2D_ARRAY); - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } + m_cross_plane_array->set_nearest_and_minpmap(); + m_texture_array->set_repeat(false, true, true); + m_cross_plane_array->set_clamp_to_edge(m_aniso); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_normal_texture_array); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_REPEAT); - glGenerateMipmap(GL_TEXTURE_2D_ARRAY); - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } + m_normal_texture_array->set_nearest_and_minpmap(); + m_normal_texture_array->set_repeat(false, true, true); + m_normal_texture_array->set_aniso(m_aniso); Logger::info("Block Texture Load Success"); } void TextureManager::init_ui() { - glGenTextures(1, &m_ui_array); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, UI_SIZE, UI_SIZE, MAX_UI_NUM, - 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); + m_ui_array = std::make_unique(TextureType::TEXTURE_2D_ARRAY); + m_ui_array->tex_image_3d(TextureFormat::RGBA, TextureFormat::RGBA, + GL_UNSIGNED_BYTE, nullptr, UI_SIZE, UI_SIZE, + MAX_UI_NUM); for (int i = 0; i < MAX_UI_NUM; i++) { load_ui_texture(i); } - glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + m_ui_array->set_nearest(); } void TextureManager::init_skin() { - - glGenTextures(1, &m_skin); - glBindTexture(GL_TEXTURE_2D, m_skin); + m_skin = std::make_unique(TextureType::TEXTURE_2D); std::string path = "texture/skin/player001.png"; unsigned char* image_data = nullptr; image_data = (Tools::load_image_data(path)); - glBindTexture(GL_TEXTURE_2D, m_skin); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SKIN_SIZE, SKIN_SIZE, 0, GL_RGBA, - GL_UNSIGNED_BYTE, image_data); + m_skin->tex_image_2d(TextureFormat::RGBA, TextureFormat::RGBA, + GL_UNSIGNED_BYTE, image_data, SKIN_SIZE, SKIN_SIZE); Tools::delete_image_data(image_data); - glBindTexture(GL_TEXTURE_2D, m_skin); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D); - - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } + m_skin->set_nearest_and_minpmap(); + m_skin->set_aniso(m_aniso); } void TextureManager::init_block_status() { - glGenTextures(1, &m_block_status_array); - glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array); - glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, BLOCK_STATUS_SIZE, - BLOCK_STATUS_SIZE, MAX_BLOCK_STATUS, 0, GL_RGBA, - GL_UNSIGNED_BYTE, nullptr); + m_block_status_array = + std::make_unique(TextureType::TEXTURE_2D_ARRAY); + m_block_status_array->tex_image_3d( + TextureFormat::RGBA, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr, + BLOCK_STATUS_SIZE, BLOCK_STATUS_SIZE, MAX_BLOCK_STATUS); for (int i = 0; i < MAX_BLOCK_STATUS; i++) { load_block_status(i); } - glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, - GL_LINEAR_MIPMAP_LINEAR); - glGenerateMipmap(GL_TEXTURE_2D_ARRAY); - - if (m_aniso >= 1) { - glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAX_ANISOTROPY, - static_cast(m_aniso)); - } + m_block_status_array->set_nearest_and_minpmap(); + m_block_status_array->set_aniso(m_aniso); } void TextureManager::init_texture() { glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &m_max_aniso);