2 Commits

21 changed files with 650 additions and 305 deletions

View File

@@ -6,7 +6,7 @@
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#include "Cubed/camera.hpp" #include "Cubed/camera.hpp"
#include "Cubed/dev_panel.hpp" #include "Cubed/dev_panel.hpp"
#include "Cubed/renderer.hpp" #include "Cubed/render/renderer.hpp"
#include "Cubed/texture_manager.hpp" #include "Cubed/texture_manager.hpp"
#include "Cubed/window.hpp" #include "Cubed/window.hpp"
namespace Cubed { namespace Cubed {

View File

@@ -58,8 +58,8 @@ public:
void rebuild_world(); void rebuild_world();
void push_delete_vbo(GLuint vbo); void push_delete_vbo(std::unique_ptr<VertexBuffer>& vbo);
void push_delete_vao(GLuint vao); void push_delete_vao(std::unique_ptr<VertexArray>& vao);
// void hot_reload(); // void hot_reload();
// void rebuild_world(); // void rebuild_world();
@@ -134,8 +134,8 @@ private:
tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue; tbb::concurrent_queue<std::unique_ptr<ClientChunk>> m_pending_upload_queue;
tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue; tbb::concurrent_queue<ChunkPos> m_dirty_chunk_queue;
tbb::concurrent_queue<PendingSound> m_pending_sound; tbb::concurrent_queue<PendingSound> m_pending_sound;
std::vector<GLuint> m_pending_delete_vbo; std::vector<std::unique_ptr<VertexBuffer>> m_pending_delete_vbo;
std::vector<GLuint> m_pending_delete_vao; std::vector<std::unique_ptr<VertexArray>> m_pending_delete_vao;
std::deque<ChunkPos> m_dirty_queue; std::deque<ChunkPos> m_dirty_queue;
std::vector<const ChunkRenderSnapshot*> m_render_snapshots; std::vector<const ChunkRenderSnapshot*> m_render_snapshots;

View File

@@ -1,15 +1,18 @@
#pragma once #pragma once
#include "Cubed/primitive_data.hpp" #include "Cubed/primitive_data.hpp"
#include "Cubed/render/vertex_array.hpp"
#include "Cubed/render/vertex_buffer.hpp"
#include <atomic> #include <atomic>
#include <glad/glad.h> #include <glad/glad.h>
#include <memory>
#include <vector> #include <vector>
namespace Cubed { namespace Cubed {
class ClientWorld; class ClientWorld;
struct VertexData { struct VertexData {
std::vector<Vertex3D> m_vertices; std::vector<Vertex3D> m_vertices;
GLuint m_vbo = 0; std::unique_ptr<VertexBuffer> m_vbo;
GLuint m_vao = 0; std::unique_ptr<VertexArray> m_vao;
std::atomic<std::size_t> m_sum{0}; std::atomic<std::size_t> m_sum{0};
ClientWorld& m_world; ClientWorld& m_world;
VertexData(ClientWorld& world); VertexData(ClientWorld& world);

View File

@@ -1,8 +1,10 @@
#pragma once #pragma once
#include "Cubed/constants.hpp" #include "Cubed/constants.hpp"
#include "Cubed/player_renderer.hpp"
#include "Cubed/primitive_data.hpp" #include "Cubed/primitive_data.hpp"
#include "Cubed/render/player_renderer.hpp"
#include "Cubed/render/vertex_array.hpp"
#include "Cubed/render/vertex_buffer.hpp"
#include "Cubed/shader.hpp" #include "Cubed/shader.hpp"
#include "Cubed/ui/text.hpp" #include "Cubed/ui/text.hpp"
@@ -126,12 +128,14 @@ private:
glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat, m_norm_mat; glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat, m_norm_mat;
GLuint m_sky_vbo = 0; std::unique_ptr<VertexBuffer> m_sky_vbo;
GLuint m_text_vbo = 0; std::unique_ptr<VertexBuffer> m_text_vbo = 0;
GLuint m_outline_indices_vbo = 0; std::unique_ptr<VertexBuffer> m_outline_indices_vbo = 0;
GLuint m_outline_vbo = 0; std::unique_ptr<VertexBuffer> m_outline_vbo = 0;
GLuint m_ui_vbo = 0; std::unique_ptr<VertexBuffer> m_ui_vbo = 0;
GLuint m_player_vbo = 0; std::unique_ptr<VertexBuffer> m_player_vbo = 0;
std::unique_ptr<VertexBuffer> m_quad_vbo = 0;
GLuint m_fbo = 0; GLuint m_fbo = 0;
GLuint m_screen_texture = 0; GLuint m_screen_texture = 0;
GLuint m_screen_depth_texture = 0; GLuint m_screen_depth_texture = 0;
@@ -144,8 +148,6 @@ private:
GLuint m_depth_map_fbo = 0; GLuint m_depth_map_fbo = 0;
GLuint m_depth_map_texture = 0; GLuint m_depth_map_texture = 0;
GLuint m_quad_vbo = 0;
glm::mat4 m_ui_proj; glm::mat4 m_ui_proj;
glm::mat4 m_ui_m_matrix; glm::mat4 m_ui_m_matrix;
std::unordered_map<std::size_t, Shader> m_shaders; std::unordered_map<std::size_t, Shader> m_shaders;
@@ -184,7 +186,7 @@ private:
3 - ui vao 3 - ui vao
4 - text vao 4 - text vao
*/ */
std::vector<GLuint> m_vao; std::vector<VertexArray> m_vao;
std::vector<Vertex2D> m_ui; std::vector<Vertex2D> m_ui;
void init_quad(); void init_quad();

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

@@ -0,0 +1,26 @@
#pragma once
#include <glad/glad.h>
namespace Cubed {
class VertexArray {
public:
VertexArray();
VertexArray(const VertexArray&) = delete;
VertexArray(VertexArray&&) noexcept;
VertexArray& operator=(const VertexArray&) = delete;
VertexArray& operator=(VertexArray&&) noexcept;
~VertexArray();
void bind() const;
static void unbind();
GLuint id() const;
void attribute(GLuint index, GLint size, GLenum type, GLsizei stride,
const void* ptr, bool normalized = false) const;
private:
GLuint m_vao = 0;
};
} // namespace Cubed

View File

@@ -0,0 +1,36 @@
#pragma once
#include <glad/glad.h>
namespace Cubed {
enum class BufferType : GLenum {
ARRAY_BUFFER = GL_ARRAY_BUFFER,
ELEMENT_ARRAY_BUFFER = GL_ELEMENT_ARRAY_BUFFER
};
enum class BufferUsage : GLenum {
STATIC_DRAW = GL_STATIC_DRAW,
DYNAMIC_DRAW = GL_DYNAMIC_DRAW
};
class VertexBuffer {
public:
VertexBuffer(BufferType type = BufferType::ARRAY_BUFFER);
VertexBuffer(const VertexBuffer&) = delete;
VertexBuffer(VertexBuffer&&) noexcept;
VertexBuffer& operator=(const VertexBuffer&) = delete;
VertexBuffer& operator=(VertexBuffer&&) noexcept;
~VertexBuffer();
void bind() const;
static void unbind();
GLuint id() const;
void buffer_data(const void* data, GLsizeiptr size,
BufferUsage usage = BufferUsage::STATIC_DRAW) const;
private:
GLuint m_vbo = 0;
BufferType m_type = BufferType::ARRAY_BUFFER;
GLenum get_buffer_target() 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

@@ -11,7 +11,7 @@ target_sources(${PROJECT_NAME}
gameplay/tree.cpp gameplay/tree.cpp
input.cpp input.cpp
map_table.cpp map_table.cpp
renderer.cpp render/renderer.cpp
shader.cpp shader.cpp
texture_manager.cpp texture_manager.cpp
tools/cubed_random.cpp tools/cubed_random.cpp
@@ -43,7 +43,7 @@ target_sources(${PROJECT_NAME}
gameplay/client_player.cpp gameplay/client_player.cpp
gameplay/session.cpp gameplay/session.cpp
gameplay/network_client.cpp gameplay/network_client.cpp
player_renderer.cpp render/player_renderer.cpp
audio/audio_engine.cpp audio/audio_engine.cpp
audio/audio_loader.cpp audio/audio_loader.cpp
audio/audio_source.cpp audio/audio_source.cpp
@@ -54,4 +54,7 @@ target_sources(${PROJECT_NAME}
audio/audio_filter.cpp audio/audio_filter.cpp
audio/audio_effect.cpp audio/audio_effect.cpp
audio/audio_effect_slot.cpp audio/audio_effect_slot.cpp
render/vertex_buffer.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()) {

View File

@@ -198,7 +198,12 @@ void ClientChunk::gen_vertex_data(
m_is_on_gen_vertex_data = false; m_is_on_gen_vertex_data = false;
} }
GLuint ClientChunk::get_normal_vao() const { return m_vertex_data[0].m_vao; } GLuint ClientChunk::get_normal_vao() const {
if (!m_vertex_data[0].m_vao) {
return 0;
}
return m_vertex_data[0].m_vao->id();
}
size_t ClientChunk::get_normal_vertices_sum() const { size_t ClientChunk::get_normal_vertices_sum() const {
if (m_vertex_data[0].m_sum == 0) { if (m_vertex_data[0].m_sum == 0) {
@@ -207,26 +212,43 @@ size_t ClientChunk::get_normal_vertices_sum() const {
return m_vertex_data[0].m_sum.load(); return m_vertex_data[0].m_sum.load();
} }
GLuint ClientChunk::get_cross_vao() const { return m_vertex_data[1].m_vao; } GLuint ClientChunk::get_cross_vao() const {
if (!m_vertex_data[1].m_vao) {
return 0;
}
return m_vertex_data[1].m_vao->id();
}
size_t ClientChunk::get_cross_vertices_sum() const { size_t ClientChunk::get_cross_vertices_sum() const {
return m_vertex_data[1].m_sum.load(); return m_vertex_data[1].m_sum.load();
} }
GLuint ClientChunk::get_normal_discard_vao() const { GLuint ClientChunk::get_normal_discard_vao() const {
return m_vertex_data[2].m_vao; if (!m_vertex_data[2].m_vao) {
return 0;
}
return m_vertex_data[2].m_vao->id();
} }
size_t ClientChunk::get_normal_discard_vertices_sum() const { size_t ClientChunk::get_normal_discard_vertices_sum() const {
return m_vertex_data[2].m_sum.load(); return m_vertex_data[2].m_sum.load();
} }
GLuint ClientChunk::get_normal_blend_vao() const { GLuint ClientChunk::get_normal_blend_vao() const {
return m_vertex_data[3].m_vao; if (!m_vertex_data[3].m_vao) {
return 0;
}
return m_vertex_data[3].m_vao->id();
} }
size_t ClientChunk::get_normal_blend_vertices_sum() const { size_t ClientChunk::get_normal_blend_vertices_sum() const {
return m_vertex_data[3].m_sum.load(); return m_vertex_data[3].m_sum.load();
} }
GLuint ClientChunk::get_water_vao() const { return m_vertex_data[4].m_vao; } GLuint ClientChunk::get_water_vao() const {
if (!m_vertex_data[4].m_vao) {
return 0;
}
return m_vertex_data[4].m_vao->id();
}
size_t ClientChunk::get_water_vertices_sum() const { size_t ClientChunk::get_water_vertices_sum() const {
return m_vertex_data[4].m_sum.load(); return m_vertex_data[4].m_sum.load();
} }

View File

@@ -32,16 +32,10 @@ ClientWorld::~ClientWorld() {
{ {
std::lock_guard lk(m_delete_vbo_mutex); std::lock_guard lk(m_delete_vbo_mutex);
for (auto x : m_pending_delete_vbo) {
glDeleteBuffers(1, &x);
}
m_pending_delete_vbo.clear(); m_pending_delete_vbo.clear();
} }
{ {
std::lock_guard lk(m_delete_vao_mutex); std::lock_guard lk(m_delete_vao_mutex);
for (auto x : m_pending_delete_vao) {
glDeleteVertexArrays(1, &x);
}
m_pending_delete_vao.clear(); m_pending_delete_vao.clear();
} }
m_ticktimers.clear(); m_ticktimers.clear();
@@ -267,13 +261,13 @@ void ClientWorld::set_block(const glm::ivec3& block_pos, unsigned id) {
}); });
} }
} }
void ClientWorld::push_delete_vbo(GLuint vbo) { void ClientWorld::push_delete_vbo(std::unique_ptr<VertexBuffer>& vbo) {
std::lock_guard lk(m_delete_vbo_mutex); std::lock_guard lk(m_delete_vbo_mutex);
m_pending_delete_vbo.push_back(vbo); m_pending_delete_vbo.push_back(std::move(vbo));
} }
void ClientWorld::push_delete_vao(GLuint vao) { void ClientWorld::push_delete_vao(std::unique_ptr<VertexArray>& vao) {
std::lock_guard lk(m_delete_vao_mutex); std::lock_guard lk(m_delete_vao_mutex);
m_pending_delete_vao.push_back(vao); m_pending_delete_vao.push_back(std::move(vao));
} }
void ClientWorld::report_block_change(const glm::ivec3& pos, void ClientWorld::report_block_change(const glm::ivec3& pos,
@@ -729,17 +723,11 @@ void ClientWorld::update(float delta_time) {
m_player.update(delta_time); m_player.update(delta_time);
{ {
std::lock_guard lk(m_delete_vbo_mutex); std::lock_guard lk(m_delete_vbo_mutex);
for (auto x : m_pending_delete_vbo) {
glDeleteBuffers(1, &x);
}
m_pending_delete_vbo.clear(); m_pending_delete_vbo.clear();
} }
{ {
std::lock_guard lk(m_delete_vao_mutex); std::lock_guard lk(m_delete_vao_mutex);
for (auto x : m_pending_delete_vao) {
glDeleteVertexArrays(1, &x);
}
m_pending_delete_vao.clear(); m_pending_delete_vao.clear();
} }

View File

@@ -5,64 +5,60 @@
namespace Cubed { namespace Cubed {
VertexData::VertexData(ClientWorld& world) : m_world(world) {} VertexData::VertexData(ClientWorld& world) : m_world(world) {}
VertexData::~VertexData() { VertexData::~VertexData() {
if (m_vbo != 0) {
m_world.push_delete_vbo(m_vbo); m_world.push_delete_vbo(m_vbo);
}
if (m_vao != 0) { m_world.push_delete_vao(m_vao);
m_world.push_delete_vao(m_vao);
}
} }
VertexData::VertexData(VertexData&& o) noexcept VertexData::VertexData(VertexData&& o) noexcept
: m_vertices(std::move(o.m_vertices)), m_vbo(o.m_vbo), m_vao(o.m_vao), : m_vertices(std::move(o.m_vertices)), m_vbo(std::move(o.m_vbo)),
m_sum(o.m_sum.load()), m_world(o.m_world) { m_vao(std::move(o.m_vao)), m_sum(o.m_sum.exchange(0)),
o.m_vbo = 0; m_world(o.m_world) {}
o.m_sum = 0;
o.m_vao = 0;
}
VertexData& VertexData::operator=(VertexData&& o) noexcept { VertexData& VertexData::operator=(VertexData&& o) noexcept {
m_vbo = o.m_vbo; if (this == &o) {
o.m_vbo = 0; return *this;
m_sum = o.m_sum.load(); }
o.m_sum = 0;
m_world.push_delete_vao(m_vao);
m_world.push_delete_vbo(m_vbo);
m_vbo = std::move(o.m_vbo);
m_vao = std::move(o.m_vao);
m_sum = o.m_sum.exchange(0);
m_vertices = std::move(o.m_vertices); m_vertices = std::move(o.m_vertices);
m_vao = o.m_vao;
o.m_vao = 0;
return *this; return *this;
} }
void VertexData::upload() { void VertexData::upload() {
if (m_vertices.size() == 0) { if (m_vertices.size() == 0) {
return; return;
} }
if (m_vao == 0) { if (!m_vao) {
glGenVertexArrays(1, &m_vao); m_vao = std::make_unique<VertexArray>();
} }
if (m_vbo == 0) { if (!m_vbo) {
glGenBuffers(1, &m_vbo); m_vbo = std::make_unique<VertexBuffer>();
} }
glBindVertexArray(m_vao); m_vao->bind();
glBindBuffer(GL_ARRAY_BUFFER, m_vbo); m_vbo->buffer_data(m_vertices.data(), m_vertices.size() * sizeof(Vertex3D),
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex3D), BufferUsage::DYNAMIC_DRAW);
m_vertices.data(), GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void*)0); m_vao->attribute(0, 3, GL_FLOAT, sizeof(Vertex3D), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), m_vao->attribute(1, 2, GL_FLOAT, sizeof(Vertex3D),
(void*)offsetof(Vertex3D, s)); (void*)offsetof(Vertex3D, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), m_vao->attribute(2, 1, GL_FLOAT, sizeof(Vertex3D),
(void*)offsetof(Vertex3D, layer)); (void*)offsetof(Vertex3D, layer));
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), m_vao->attribute(3, 3, GL_FLOAT, sizeof(Vertex3D),
(void*)offsetof(Vertex3D, nx)); (void*)offsetof(Vertex3D, nx));
glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), m_vao->attribute(4, 1, GL_FLOAT, sizeof(Vertex3D),
(void*)offsetof(Vertex3D, roughness)); (void*)offsetof(Vertex3D, roughness));
glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), m_vao->attribute(5, 3, GL_FLOAT, sizeof(Vertex3D),
(void*)offsetof(Vertex3D, tx)); (void*)offsetof(Vertex3D, tx));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1); VertexArray::unbind();
glEnableVertexAttribArray(2); VertexBuffer::unbind();
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
glEnableVertexAttribArray(5);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// Release memory // Release memory
m_vertices.clear(); m_vertices.clear();

View File

@@ -1,9 +1,9 @@
#include "Cubed/player_renderer.hpp" #include "Cubed/render/player_renderer.hpp"
#include "Cubed/camera.hpp" #include "Cubed/camera.hpp"
#include "Cubed/gameplay/client_world.hpp" #include "Cubed/gameplay/client_world.hpp"
#include "Cubed/primitive_data.hpp" #include "Cubed/primitive_data.hpp"
#include "Cubed/renderer.hpp" #include "Cubed/render/renderer.hpp"
#include "Cubed/texture_manager.hpp" #include "Cubed/texture_manager.hpp"
#include <glm/glm.hpp> #include <glm/glm.hpp>

View File

@@ -1,4 +1,4 @@
#include "Cubed/renderer.hpp" #include "Cubed/render/renderer.hpp"
#include "Cubed/camera.hpp" #include "Cubed/camera.hpp"
#include "Cubed/config.hpp" #include "Cubed/config.hpp"
@@ -30,14 +30,14 @@ Renderer::Renderer(const Camera& camera, ClientWorld& world,
Renderer::~Renderer() { Renderer::~Renderer() {
if (m_init) { if (m_init) {
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &m_outline_vbo); m_outline_vbo.reset();
glDeleteBuffers(1, &m_outline_indices_vbo); m_outline_indices_vbo.reset();
glDeleteBuffers(1, &m_sky_vbo); m_sky_vbo.reset();
glDeleteBuffers(1, &m_ui_vbo); m_ui_vbo.reset();
glDeleteBuffers(1, &m_text_vbo); m_text_vbo.reset();
glDeleteBuffers(1, &m_player_vbo); m_player_vbo.reset();
glBindVertexArray(0); glBindVertexArray(0);
glDeleteVertexArrays(NUM_VAO, m_vao.data()); m_vao.clear();
glDeleteFramebuffers(1, &m_fbo); glDeleteFramebuffers(1, &m_fbo);
glDeleteTextures(1, &m_screen_texture); glDeleteTextures(1, &m_screen_texture);
glDeleteTextures(1, &m_screen_depth_texture); glDeleteTextures(1, &m_screen_depth_texture);
@@ -133,52 +133,43 @@ void Renderer::init(bool debug_on) {
#endif #endif
m_vao.resize(NUM_VAO); m_vao.resize(NUM_VAO);
glGenVertexArrays(NUM_VAO, m_vao.data()); VertexArray::unbind();
glBindVertexArray(0);
glBindVertexArray(m_vao[2]); m_outline_vbo = std::make_unique<VertexBuffer>();
glGenBuffers(1, &m_outline_vbo); m_outline_indices_vbo =
glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo); std::make_unique<VertexBuffer>(BufferType::ELEMENT_ARRAY_BUFFER);
glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VER), CUBE_VER, GL_STATIC_DRAW); m_player_vbo = std::make_unique<VertexBuffer>();
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); m_quad_vbo = std::make_unique<VertexBuffer>();
glEnableVertexAttribArray(0); m_sky_vbo = std::make_unique<VertexBuffer>();
glGenBuffers(1, &m_outline_indices_vbo); m_text_vbo = std::make_unique<VertexBuffer>();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo); m_ui_vbo = std::make_unique<VertexBuffer>();
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(OUTLINE_CUBE_INDICES),
OUTLINE_CUBE_INDICES, GL_STATIC_DRAW);
glBindVertexArray(m_vao[1]); m_vao[2].bind();
glGenBuffers(1, &m_sky_vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_POS), VERTICES_POS,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); m_outline_vbo->buffer_data(CUBE_VER, sizeof(CUBE_VER));
glEnableVertexAttribArray(0); m_vao[2].attribute(0, 3, GL_FLOAT, 0, 0);
m_outline_indices_vbo->buffer_data(OUTLINE_CUBE_INDICES,
sizeof(OUTLINE_CUBE_INDICES));
glBindVertexArray(m_vao[3]); m_vao[1].bind();
glGenBuffers(1, &m_ui_vbo); m_sky_vbo->buffer_data(VERTICES_POS, sizeof(VERTICES_POS));
glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo);
m_vao[1].attribute(0, 3, GL_FLOAT, 0, 0);
m_vao[3].bind();
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
Vertex2D vex{SQUARE_VERTICES[i][0], SQUARE_VERTICES[i][1], Vertex2D vex{SQUARE_VERTICES[i][0], SQUARE_VERTICES[i][1],
SQUARE_TEXTURE_POS[i][0], SQUARE_TEXTURE_POS[i][1], 0}; SQUARE_TEXTURE_POS[i][0], SQUARE_TEXTURE_POS[i][1], 0};
m_ui.emplace_back(vex); m_ui.emplace_back(vex);
} }
m_ui_vbo->buffer_data(m_ui.data(), m_ui.size() * sizeof(Vertex2D));
glBufferData(GL_ARRAY_BUFFER, m_ui.size() * sizeof(Vertex2D), m_ui.data(), m_vao[3].attribute(0, 3, GL_FLOAT, sizeof(Vertex2D), (void*)0);
GL_STATIC_DRAW); m_vao[3].attribute(1, 2, GL_FLOAT, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, s));
glBindBuffer(GL_ARRAY_BUFFER, m_ui_vbo); m_vao[3].attribute(2, 1, GL_FLOAT, sizeof(Vertex2D),
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0); (void*)offsetof(Vertex2D, layer));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, s));
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex2D),
(void*)offsetof(Vertex2D, layer));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
init_quad(); init_quad();
init_text(); init_text();
@@ -186,8 +177,8 @@ void Renderer::init(bool debug_on) {
m_player_renderer.init(); m_player_renderer.init();
glBindVertexArray(0); VertexArray::unbind();
glBindBuffer(GL_ARRAY_BUFFER, 0); VertexBuffer::unbind();
m_init = true; m_init = true;
} }
@@ -198,28 +189,24 @@ const Shader& Renderer::get_shader(const std::string& name) const {
} }
void Renderer::init_quad() { void Renderer::init_quad() {
glBindVertexArray(m_vao[0]); m_vao[0].bind();
glGenBuffers(1, &m_quad_vbo); m_quad_vbo->buffer_data(QUAD_VERTICES, sizeof(QUAD_VERTICES));
glBindBuffer(GL_ARRAY_BUFFER, m_quad_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(QUAD_VERTICES), QUAD_VERTICES,
GL_STATIC_DRAW);
glEnableVertexAttribArray(0); m_vao[0].attribute(0, 2, GL_FLOAT, 4 * sizeof(float), (void*)0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)0); m_vao[0].attribute(1, 2, GL_FLOAT, 4 * sizeof(float),
glEnableVertexAttribArray(1); (void*)(2 * sizeof(float)));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
(void*)(2 * sizeof(float)));
} }
void Renderer::init_text() { void Renderer::init_text() {
glBindVertexArray(m_vao[4]); m_vao[4].bind();
glGenBuffers(1, &m_text_vbo); m_text_vbo->buffer_data(NULL, sizeof(float) * 6 * 4,
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo); BufferUsage::DYNAMIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 6 * 4, NULL, GL_DYNAMIC_DRAW);
const auto& shader = get_shader("text"); const auto& shader = get_shader("text");
Text::set_loc(shader); Text::set_loc(shader);
DebugCollector::get().init_text(); DebugCollector::get().init_text();
} }
@@ -291,7 +278,7 @@ void Renderer::render_outline() {
shader.set_loc("mv_matrix", m_mv_mat); shader.set_loc("mv_matrix", m_mv_mat);
shader.set_loc("proj_matrix", m_p_mat); shader.set_loc("proj_matrix", m_p_mat);
glBindVertexArray(m_vao[2]); m_vao[2].bind();
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
@@ -364,7 +351,7 @@ void Renderer::render_sky() {
sky_shader.set_loc("cloudWhiteMix", m_sky_uniform.cloud_white_mix); sky_shader.set_loc("cloudWhiteMix", m_sky_uniform.cloud_white_mix);
sky_shader.set_loc("cloudThresholdLow", m_cloud_threshold_low); sky_shader.set_loc("cloudThresholdLow", m_cloud_threshold_low);
sky_shader.set_loc("cloudThresholdHigh", m_cloud_threshold_high); sky_shader.set_loc("cloudThresholdHigh", m_cloud_threshold_high);
glBindVertexArray(m_vao[1]); m_vao[1].bind();
glDisable(GL_DEPTH_TEST); glDisable(GL_DEPTH_TEST);
@@ -376,7 +363,7 @@ void Renderer::render_sky() {
billboard.use(); billboard.use();
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glBindVertexArray(m_vao[0]); m_vao[0].bind();
// draw sun // draw sun
glm::vec3 sun_pos = m_camera.get_camera_pos() + glm::vec3 sun_pos = m_camera.get_camera_pos() +
normalize(-m_world.sunlight_dir()) * (FAR_PLANE * 0.9f); normalize(-m_world.sunlight_dir()) * (FAR_PLANE * 0.9f);
@@ -408,7 +395,7 @@ void Renderer::render_sky() {
void Renderer::render_text() { void Renderer::render_text() {
glBindVertexArray(m_vao[4]); m_vao[4].bind();
const auto& shader = get_shader("text"); const auto& shader = get_shader("text");
@@ -440,7 +427,7 @@ void Renderer::render_ui() {
shader.set_loc("m_matrix", m_ui_m_matrix); shader.set_loc("m_matrix", m_ui_m_matrix);
shader.set_loc("proj_matrix", m_ui_proj); shader.set_loc("proj_matrix", m_ui_proj);
glBindVertexArray(m_vao[3]); m_vao[3].bind();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_ui_array()); glBindTexture(GL_TEXTURE_2D_ARRAY, m_texture_manager.get_ui_array());
@@ -455,7 +442,7 @@ void Renderer::render_underwater() {
const auto& shader = get_shader("under_water"); const auto& shader = get_shader("under_water");
shader.use(); shader.use();
glBindVertexArray(m_vao[0]); m_vao[0].bind();
shader.set_loc("u_sceneTexture", 0); shader.set_loc("u_sceneTexture", 0);
shader.set_loc("u_time", static_cast<float>(glfwGetTime())); shader.set_loc("u_time", static_cast<float>(glfwGetTime()));
@@ -951,7 +938,7 @@ void Renderer::render_world() {
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glBindVertexArray(m_vao[0]); m_vao[0].bind();
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_accum_texture); glBindTexture(GL_TEXTURE_2D, m_accum_texture);
@@ -984,8 +971,8 @@ void Renderer::render_player() {
shader.set_loc("minRadius", m_min_radius); shader.set_loc("minRadius", m_min_radius);
shader.set_loc("maxRadius", m_max_radius); shader.set_loc("maxRadius", m_max_radius);
shader.set_loc("samples", m_samples); shader.set_loc("samples", m_samples);
shader.set_loc("renderDistance", m_world.rendering_distance()); // shader.set_loc("renderDistance", m_world.rendering_distance());
shader.set_loc("skyColor", m_sky_uniform.sky_top); // shader.set_loc("skyColor", m_sky_uniform.sky_top);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_depth_map_texture); glBindTexture(GL_TEXTURE_2D, m_depth_map_texture);

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

@@ -0,0 +1,39 @@
#include "Cubed/render/vertex_array.hpp"
#include <utility>
namespace Cubed {
VertexArray::VertexArray() { glGenVertexArrays(1, &m_vao); }
VertexArray::~VertexArray() {
if (m_vao) {
glDeleteVertexArrays(1, &m_vao);
}
}
VertexArray::VertexArray(VertexArray&& o) noexcept
: m_vao(std::exchange(o.m_vao, 0)) {}
VertexArray& VertexArray::operator=(VertexArray&& o) noexcept {
if (this != &o) {
if (m_vao) {
glDeleteVertexArrays(1, &m_vao);
}
m_vao = std::exchange(o.m_vao, 0);
}
return *this;
}
void VertexArray::bind() const { glBindVertexArray(m_vao); }
void VertexArray::unbind() { glBindVertexArray(0); }
GLuint VertexArray::id() const { return m_vao; }
void VertexArray::attribute(GLuint index, GLint size, GLenum type,
GLsizei stride, const void* ptr,
bool normalized) const {
bind();
glVertexAttribPointer(index, size, type, normalized ? GL_TRUE : GL_FALSE,
stride, ptr);
glEnableVertexAttribArray(index);
}
} // namespace Cubed

View File

@@ -0,0 +1,52 @@
#include "Cubed/render/vertex_buffer.hpp"
#include <utility>
namespace Cubed {
VertexBuffer::VertexBuffer(BufferType type) : m_type(type) {
glGenBuffers(1, &m_vbo);
}
VertexBuffer::~VertexBuffer() {
if (m_vbo) {
glDeleteBuffers(1, &m_vbo);
}
}
VertexBuffer::VertexBuffer(VertexBuffer&& o) noexcept
: m_vbo(std::exchange(o.m_vbo, 0)), m_type(o.m_type) {}
VertexBuffer& VertexBuffer::operator=(VertexBuffer&& o) noexcept {
if (this != &o) {
if (m_vbo) {
glDeleteBuffers(1, &m_vbo);
}
m_vbo = std::exchange(o.m_vbo, 0);
m_type = o.m_type;
}
return *this;
}
void VertexBuffer::bind() const { glBindBuffer(get_buffer_target(), m_vbo); }
void VertexBuffer::unbind() {
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
GLuint VertexBuffer::id() const { return m_vbo; }
GLenum VertexBuffer::get_buffer_target() const {
return std::to_underlying(m_type);
}
void VertexBuffer::buffer_data(const void* data, GLsizeiptr size,
BufferUsage usage) const {
bind();
GLenum target = get_buffer_target();
glBufferData(target, size, data, std::to_underlying(usage));
}
} // 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);

View File

@@ -1,7 +1,7 @@
#include "Cubed/window.hpp" #include "Cubed/window.hpp"
#include "Cubed/config.hpp" #include "Cubed/config.hpp"
#include "Cubed/renderer.hpp" #include "Cubed/render/renderer.hpp"
#include "Cubed/tools/cubed_assert.hpp" #include "Cubed/tools/cubed_assert.hpp"
#include "Cubed/tools/font.hpp" #include "Cubed/tools/font.hpp"
#include "Cubed/tools/log.hpp" #include "Cubed/tools/log.hpp"