refactor(render): encapsulate OpenGL textures into Texture class

This commit is contained in:
2026-07-09 18:36:06 +08:00
parent 29642d7da2
commit b8dcbb086d
6 changed files with 340 additions and 148 deletions

View File

@@ -0,0 +1,90 @@
#pragma once
#include <cstddef>
#include <glad/glad.h>
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

View File

@@ -1,7 +1,9 @@
#pragma once #pragma once
#include "Cubed/gameplay/block.hpp" #include "Cubed/gameplay/block.hpp"
#include "Cubed/render/texture.hpp"
#include <glad/glad.h> #include <glad/glad.h>
#include <memory>
namespace Cubed { namespace Cubed {
@@ -9,19 +11,17 @@ class TextureManager {
private: private:
bool m_need_reload = false; bool m_need_reload = false;
bool m_init = false; bool m_init = false;
GLuint m_block_status_array = 0; std::unique_ptr<Texture> m_block_status_array;
GLuint m_texture_array = 0; std::unique_ptr<Texture> m_texture_array;
GLuint m_cross_plane_array = 0; std::unique_ptr<Texture> m_cross_plane_array;
GLuint m_ui_array = 0; std::unique_ptr<Texture> m_ui_array;
GLuint m_normal_texture_array = 0; std::unique_ptr<Texture> m_normal_texture_array;
std::unique_ptr<Texture> m_skin;
std::vector<std::unique_ptr<Texture>> m_item_textures;
GLfloat m_max_aniso = 0.0f; GLfloat m_max_aniso = 0.0f;
GLuint m_skin = 0;
int m_aniso = 1; int m_aniso = 1;
std::vector<GLuint> m_item_textures;
void load_block_status(unsigned status_id); void load_block_status(unsigned status_id);
void load_block_texture(unsigned block_id); void load_block_texture(unsigned block_id);
void load_block_item_texture(unsigned id); void load_block_item_texture(unsigned id);
@@ -45,7 +45,7 @@ public:
GLuint get_cross_plane_array() const; GLuint get_cross_plane_array() const;
GLuint get_ui_array() const; GLuint get_ui_array() const;
GLuint get_pbr_texture() const; GLuint get_pbr_texture() const;
const std::vector<GLuint>& item_textures() const; const std::vector<std::unique_ptr<Texture>>& item_textures() const;
GLuint get_skin() const; GLuint get_skin() const;
// Must call after MapTable::init_map() and glfwMakeContextCurrent(window); // Must call after MapTable::init_map() and glfwMakeContextCurrent(window);
void init_texture(); void init_texture();

View File

@@ -56,4 +56,5 @@ target_sources(${PROJECT_NAME}
audio/audio_effect_slot.cpp audio/audio_effect_slot.cpp
render/vertex_buffer.cpp render/vertex_buffer.cpp
render/vertex_array.cpp render/vertex_array.cpp
render/texture.cpp
) )

View File

@@ -651,13 +651,14 @@ void DevPanel::show_items_tab_item() {
ImGui::Text("Place Block "); ImGui::Text("Place Block ");
ImGui::SameLine(); ImGui::SameLine();
ImGui::Image(static_cast<ImTextureID>(static_cast<intptr_t>( ImGui::Image(static_cast<ImTextureID>(static_cast<intptr_t>(
textures[m_player->place_block()])), textures[m_player->place_block()]->id())),
ImVec2{48, 48}); ImVec2{48, 48});
for (size_t i = 1; i < textures.size(); i++) { for (size_t i = 1; i < textures.size(); i++) {
if (ImGui::ImageButton(("##item" + std::to_string(i)).c_str(), if (ImGui::ImageButton(
static_cast<ImTextureID>( ("##item" + std::to_string(i)).c_str(),
static_cast<intptr_t>(textures[i])), static_cast<ImTextureID>(
ImVec2{48, 48})) { static_cast<intptr_t>(textures[i]->id())),
ImVec2{48, 48})) {
m_player->set_place_block(i); m_player->set_place_block(i);
} }
if (ImGui::IsItemHovered()) { if (ImGui::IsItemHovered()) {

147
src/render/texture.cpp Normal file
View File

@@ -0,0 +1,147 @@
#include "Cubed/render/texture.hpp"
#include "Cubed/tools/cubed_assert.hpp"
#include <utility>
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<GLfloat>(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

View File

@@ -38,49 +38,56 @@ TextureManager::~TextureManager() { delet_texture(); }
void TextureManager::delet_texture() { void TextureManager::delet_texture() {
if (m_init) { if (m_init) {
glDeleteTextures(1, &m_texture_array); m_texture_array.reset();
glDeleteTextures(1, &m_block_status_array); m_block_status_array.reset();
glDeleteTextures(1, &m_cross_plane_array); m_cross_plane_array.reset();
glDeleteTextures(1, &m_normal_texture_array); m_normal_texture_array.reset();
for (auto& id : m_item_textures) { for (auto& id : m_item_textures) {
glDeleteTextures(1, &id); id.reset();
} }
glDeleteTextures(1, &m_skin); m_skin.reset();
Logger::info("Successfully delete all texture"); Logger::info("Successfully delete all texture");
} }
} }
GLuint TextureManager::get_block_status_array() const { 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 { 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 { GLuint TextureManager::get_pbr_texture() const {
return m_normal_texture_array; return m_normal_texture_array->id();
} }
const std::vector<GLuint>& TextureManager::item_textures() const { const std::vector<std::unique_ptr<Texture>>&
TextureManager::item_textures() const {
return m_item_textures; 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) { void TextureManager::load_block_status(unsigned id) {
ASSERT_MSG(id < MAX_BLOCK_STATUS, "Exceed the max status sum limit"); ASSERT_MSG(id < MAX_BLOCK_STATUS, "Exceed the max status sum limit");
std::string path = "texture/status/" + std::to_string(id) + ".png"; std::string path = "texture/status/" + std::to_string(id) + ".png";
unsigned char* image_data = nullptr; unsigned char* image_data = nullptr;
image_data = (Tools::load_image_data(path)); 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, m_block_status_array->tex_sub_image_3d(
BLOCK_STATUS_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, TextureFormat::RGBA, GL_UNSIGNED_BYTE, image_data, 0, 0, id,
image_data); BLOCK_STATUS_SIZE, BLOCK_STATUS_SIZE);
Tools::delete_image_data(image_data); 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[4] = (Tools::load_image_data(block_texture_path + "/top.png"));
image_data[5] = (Tools::load_image_data(block_texture_path + "/base.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(); Tools::check_opengl_error();
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id * 6 + i, BLOCK_SIZE, m_texture_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE,
BLOCK_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, image_data[i], 0, 0, id * 6 + i,
image_data[i]); BLOCK_SIZE, BLOCK_SIZE);
Tools::check_opengl_error(); Tools::check_opengl_error();
Tools::delete_image_data(image_data[i]); 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"; std::string path = "texture/item/block/" + name + ".png";
unsigned char* data = nullptr; unsigned char* data = nullptr;
data = Tools::load_image_data(path); data = Tools::load_image_data(path);
GLuint texture; std::unique_ptr<Texture> texture =
glGenTextures(1, &texture); std::make_unique<Texture>(TextureType::TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture); texture->tex_image_2d(TextureFormat::RGBA8, TextureFormat::RGBA,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, BLOCK_ITEM_SIZE, BLOCK_ITEM_SIZE, GL_UNSIGNED_BYTE, data, BLOCK_ITEM_SIZE,
0, GL_RGBA, GL_UNSIGNED_BYTE, data); BLOCK_ITEM_SIZE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); texture->set_nearest();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texture->set_clamp_to_border();
GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D); m_item_textures.push_back(std::move(texture));
if (m_aniso >= 1) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY,
static_cast<GLfloat>(m_aniso));
}
m_item_textures.push_back(texture);
Tools::delete_image_data(data); Tools::delete_image_data(data);
} }
@@ -148,10 +149,10 @@ void TextureManager::load_cross_plane_texture(unsigned id) {
std::string path = std::string path =
"texture/block/" + BlockManager::name_form_id(id) + "/cross.png"; "texture/block/" + BlockManager::name_form_id(id) + "/cross.png";
unsigned char* image_data = Tools::load_image_data(path); unsigned char* image_data = Tools::load_image_data(path);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); m_cross_plane_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE,
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, image_data, 0, 0,
BlockManager::cross_plane_index(id), CROSS_PLANE_SIZE, BlockManager::cross_plane_index(id),
CROSS_PLANE_SIZE, 1, GL_RGBA, GL_UNSIGNED_BYTE, image_data); CROSS_PLANE_SIZE, CROSS_PLANE_SIZE);
Tools::delete_image_data(image_data); 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"; std::string path = "texture/ui/" + std::to_string(id) + ".png";
unsigned char* image_data = nullptr; unsigned char* image_data = nullptr;
image_data = (Tools::load_image_data(path)); image_data = (Tools::load_image_data(path));
glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); m_ui_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE,
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id, UI_SIZE, UI_SIZE, 1, image_data, 0, 0, id, UI_SIZE, UI_SIZE);
GL_RGBA, GL_UNSIGNED_BYTE, image_data);
Tools::delete_image_data(image_data); 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[4] = (Tools::load_image_data(path + "/top_n.png", false));
image_data[5] = (Tools::load_image_data(path + "/base_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++) { for (int i = 0; i < 6; i++) {
unsigned char* data = image_data[i]; unsigned char* data = image_data[i];
bool is_fallback = false; bool is_fallback = false;
@@ -197,9 +196,10 @@ void TextureManager::load_pbr_texture(unsigned id) {
is_fallback = true; is_fallback = true;
data = generate_flat_normal_map(); data = generate_flat_normal_map();
} }
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, id * 6 + i, m_normal_texture_array->tex_sub_image_3d(
BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE, 1, GL_RGBA, TextureFormat::RGBA, GL_UNSIGNED_BYTE, data, 0, 0, id * 6 + i,
GL_UNSIGNED_BYTE, data); BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE);
if (is_fallback) { if (is_fallback) {
delete[] data; delete[] data;
} else { } else {
@@ -209,125 +209,78 @@ void TextureManager::load_pbr_texture(unsigned id) {
} }
void TextureManager::init_block() { void TextureManager::init_block() {
m_texture_array = std::make_unique<Texture>(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); m_cross_plane_array =
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_array); std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, BLOCK_SIZE, BLOCK_SIZE, m_cross_plane_array->tex_image_3d(
BlockManager::sums() * 6, 0, GL_RGBA, GL_UNSIGNED_BYTE, TextureFormat::RGBA, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr,
nullptr); CROSS_PLANE_SIZE, CROSS_PLANE_SIZE, BlockManager::cross_plane_sum());
glGenTextures(1, &m_cross_plane_array); m_normal_texture_array =
glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, CROSS_PLANE_SIZE, m_normal_texture_array->tex_image_3d(
CROSS_PLANE_SIZE, BlockManager::cross_plane_sum(), 0, GL_RGBA, TextureFormat::RGBA8, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr,
GL_UNSIGNED_BYTE, nullptr); BLOCK_NORMAL_SIZE, BLOCK_NORMAL_SIZE, BlockManager::sums() * 6);
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);
for (unsigned i = 0; i < BlockManager::sums(); i++) { for (unsigned i = 0; i < BlockManager::sums(); i++) {
load_block_texture(i); load_block_texture(i);
load_block_item_texture(i); load_block_item_texture(i);
load_pbr_texture(i); load_pbr_texture(i);
} }
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_array); m_texture_array->set_nearest_and_minpmap();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); m_texture_array->set_repeat(false, true, true);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, m_texture_array->set_aniso(m_aniso);
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<GLfloat>(m_aniso));
}
glBindTexture(GL_TEXTURE_2D_ARRAY, m_cross_plane_array); m_cross_plane_array->set_nearest_and_minpmap();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); m_texture_array->set_repeat(false, true, true);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, m_cross_plane_array->set_clamp_to_edge(m_aniso);
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<GLfloat>(m_aniso));
}
glBindTexture(GL_TEXTURE_2D_ARRAY, m_normal_texture_array); m_normal_texture_array->set_nearest_and_minpmap();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); m_normal_texture_array->set_repeat(false, true, true);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, m_normal_texture_array->set_aniso(m_aniso);
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<GLfloat>(m_aniso));
}
Logger::info("Block Texture Load Success"); Logger::info("Block Texture Load Success");
} }
void TextureManager::init_ui() { void TextureManager::init_ui() {
glGenTextures(1, &m_ui_array); m_ui_array = std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); m_ui_array->tex_image_3d(TextureFormat::RGBA, TextureFormat::RGBA,
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, UI_SIZE, UI_SIZE, MAX_UI_NUM, GL_UNSIGNED_BYTE, nullptr, UI_SIZE, UI_SIZE,
0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); MAX_UI_NUM);
for (int i = 0; i < MAX_UI_NUM; i++) { for (int i = 0; i < MAX_UI_NUM; i++) {
load_ui_texture(i); load_ui_texture(i);
} }
glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array); m_ui_array->set_nearest();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
} }
void TextureManager::init_skin() { void TextureManager::init_skin() {
m_skin = std::make_unique<Texture>(TextureType::TEXTURE_2D);
glGenTextures(1, &m_skin);
glBindTexture(GL_TEXTURE_2D, m_skin);
std::string path = "texture/skin/player001.png"; std::string path = "texture/skin/player001.png";
unsigned char* image_data = nullptr; unsigned char* image_data = nullptr;
image_data = (Tools::load_image_data(path)); image_data = (Tools::load_image_data(path));
glBindTexture(GL_TEXTURE_2D, m_skin); m_skin->tex_image_2d(TextureFormat::RGBA, TextureFormat::RGBA,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SKIN_SIZE, SKIN_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data, SKIN_SIZE, SKIN_SIZE);
GL_UNSIGNED_BYTE, image_data);
Tools::delete_image_data(image_data); Tools::delete_image_data(image_data);
glBindTexture(GL_TEXTURE_2D, m_skin); m_skin->set_nearest_and_minpmap();
m_skin->set_aniso(m_aniso);
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<GLfloat>(m_aniso));
}
} }
void TextureManager::init_block_status() { void TextureManager::init_block_status() {
glGenTextures(1, &m_block_status_array); m_block_status_array =
glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array); std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, BLOCK_STATUS_SIZE, m_block_status_array->tex_image_3d(
BLOCK_STATUS_SIZE, MAX_BLOCK_STATUS, 0, GL_RGBA, TextureFormat::RGBA, TextureFormat::RGBA, GL_UNSIGNED_BYTE, nullptr,
GL_UNSIGNED_BYTE, nullptr); BLOCK_STATUS_SIZE, BLOCK_STATUS_SIZE, MAX_BLOCK_STATUS);
for (int i = 0; i < MAX_BLOCK_STATUS; i++) { for (int i = 0; i < MAX_BLOCK_STATUS; i++) {
load_block_status(i); load_block_status(i);
} }
glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array); m_block_status_array->set_nearest_and_minpmap();
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST); m_block_status_array->set_aniso(m_aniso);
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<GLfloat>(m_aniso));
}
} }
void TextureManager::init_texture() { void TextureManager::init_texture() {
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &m_max_aniso); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &m_max_aniso);