Compare commits
13 Commits
a8726b06c3
...
296bd8e07a
| Author | SHA1 | Date | |
|---|---|---|---|
| 296bd8e07a | |||
| 9c7812f205 | |||
| 3aff13ed1e | |||
| 0b0beaf25c | |||
| 7d5b9c34b3 | |||
| cf9aaa62a7 | |||
| 6362536daa | |||
| 42b5661a28 | |||
| ecc1595a39 | |||
| cd107fa35d | |||
| 60319ebcd8 | |||
| 1d04fedb0f | |||
| 311c675852 |
@@ -80,6 +80,7 @@ set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include)
|
|||||||
add_executable(${PROJECT_NAME}
|
add_executable(${PROJECT_NAME}
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
src/app.cpp
|
src/app.cpp
|
||||||
|
src/debug_collector.cpp
|
||||||
src/camera.cpp
|
src/camera.cpp
|
||||||
src/gameplay/chunk.cpp
|
src/gameplay/chunk.cpp
|
||||||
src/gameplay/player.cpp
|
src/gameplay/player.cpp
|
||||||
@@ -94,6 +95,7 @@ add_executable(${PROJECT_NAME}
|
|||||||
src/tools/font.cpp
|
src/tools/font.cpp
|
||||||
src/tools/log.cpp
|
src/tools/log.cpp
|
||||||
src/tools/perlin_noise.cpp
|
src/tools/perlin_noise.cpp
|
||||||
|
src/ui/text.cpp
|
||||||
src/window.cpp
|
src/window.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -109,6 +111,15 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|||||||
target_link_options(${PROJECT_NAME} PRIVATE
|
target_link_options(${PROJECT_NAME} PRIVATE
|
||||||
-fsanitize=address
|
-fsanitize=address
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE DEBUG_MODE)
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||||
|
ASSETS_PATH="${CMAKE_SOURCE_DIR}/assets/"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||||
|
ASSETS_PATH="./assets/"
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})
|
target_include_directories(${PROJECT_NAME} PUBLIC ${INCLUDE_DIR})
|
||||||
@@ -140,11 +151,3 @@ if (UNIX AND NOT APPLE)
|
|||||||
|
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE ${EGL_CFLAGS_OTHER} ${Wayland_CFLAGS_OTHER})
|
target_compile_options(${PROJECT_NAME} PRIVATE ${EGL_CFLAGS_OTHER} ${Wayland_CFLAGS_OTHER})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/shaders"
|
|
||||||
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/shaders"
|
|
||||||
COMMENT "Copying shaders to output directory"
|
|
||||||
)
|
|
||||||
@@ -7,9 +7,9 @@ layout (location = 2) in float layer;
|
|||||||
out vec2 tc;
|
out vec2 tc;
|
||||||
flat out int tex_layer;
|
flat out int tex_layer;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
|
uniform mat4 mv_matrix;
|
||||||
void main(void) {
|
void main(void) {
|
||||||
gl_Position = projection * vec4(pos, 0.0, 1.0);
|
gl_Position = projection * mv_matrix * vec4(pos, 0.0, 1.0);
|
||||||
tc = texCoord;
|
tc = texCoord;
|
||||||
tex_layer = int(layer);
|
tex_layer = int(layer);
|
||||||
}
|
}
|
||||||
BIN
assets/texture/block/dirt/back.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/dirt/base.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/dirt/front.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/dirt/left.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/dirt/right.png
Normal file
|
After Width: | Height: | Size: 482 B |
BIN
assets/texture/block/dirt/top.png
Normal file
|
After Width: | Height: | Size: 482 B |
|
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 362 B After Width: | Height: | Size: 482 B |
|
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 512 B After Width: | Height: | Size: 563 B |
BIN
assets/texture/block/stone/back.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
assets/texture/block/stone/base.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
assets/texture/block/stone/front.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
assets/texture/block/stone/left.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
assets/texture/block/stone/right.png
Normal file
|
After Width: | Height: | Size: 382 B |
BIN
assets/texture/block/stone/top.png
Normal file
|
After Width: | Height: | Size: 382 B |
@@ -29,9 +29,6 @@ private:
|
|||||||
|
|
||||||
Window m_window{m_renderer};
|
Window m_window{m_renderer};
|
||||||
|
|
||||||
|
|
||||||
GLuint m_texture_array = 0;
|
|
||||||
|
|
||||||
inline static double last_time = glfwGetTime();
|
inline static double last_time = glfwGetTime();
|
||||||
inline static double current_time = glfwGetTime();
|
inline static double current_time = glfwGetTime();
|
||||||
inline static double delta_time = 0.0f;
|
inline static double delta_time = 0.0f;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
constexpr int WORLD_SIZE_Y = 256;
|
constexpr int WORLD_SIZE_Y = 256;
|
||||||
constexpr int MAX_BLOCK_NUM = 2;
|
constexpr int MAX_BLOCK_NUM = 4;
|
||||||
constexpr int MAX_UI_NUM = 1;
|
constexpr int MAX_UI_NUM = 1;
|
||||||
|
|
||||||
constexpr int CHUCK_SIZE = 16;
|
constexpr int CHUCK_SIZE = 16;
|
||||||
|
|||||||
20
include/Cubed/debug_collector.hpp
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Cubed/ui/text.hpp>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
class DebugCollector {
|
||||||
|
public:
|
||||||
|
static DebugCollector& get();
|
||||||
|
DebugCollector();
|
||||||
|
|
||||||
|
std::unordered_map<std::size_t, Text>& all_texts();
|
||||||
|
|
||||||
|
Text& text(std::string_view name);
|
||||||
|
void report(std::string_view name, std::string_view content);
|
||||||
|
void init_text();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<std::size_t, Text> m_texts;
|
||||||
|
};
|
||||||
@@ -16,9 +16,14 @@ struct MouseState {
|
|||||||
bool right = false;
|
bool right = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct KeyState {
|
||||||
|
bool r = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct InputState {
|
struct InputState {
|
||||||
MoveState move_state;
|
MoveState move_state;
|
||||||
MouseState mouse_state;
|
MouseState mouse_state;
|
||||||
|
KeyState key_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Input {
|
namespace Input {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <Cubed/config.hpp>
|
#include <Cubed/config.hpp>
|
||||||
#include <Cubed/shader.hpp>
|
#include <Cubed/shader.hpp>
|
||||||
|
#include <Cubed/ui/text.hpp>
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@@ -45,6 +46,9 @@ private:
|
|||||||
std::unordered_map<std::size_t, Shader> m_shaders;
|
std::unordered_map<std::size_t, Shader> m_shaders;
|
||||||
std::vector<GLuint> m_vao;
|
std::vector<GLuint> m_vao;
|
||||||
std::vector<Vertex2D> m_ui;
|
std::vector<Vertex2D> m_ui;
|
||||||
|
|
||||||
|
void init_text();
|
||||||
|
|
||||||
void render_outline();
|
void render_outline();
|
||||||
void render_sky();
|
void render_sky();
|
||||||
void render_text();
|
void render_text();
|
||||||
|
|||||||
@@ -6,12 +6,14 @@
|
|||||||
|
|
||||||
class TextureManager {
|
class TextureManager {
|
||||||
private:
|
private:
|
||||||
|
bool m_need_reload = false;
|
||||||
GLuint m_block_status_array;
|
GLuint m_block_status_array;
|
||||||
GLuint m_texture_array;
|
GLuint m_texture_array;
|
||||||
GLuint m_ui_array;
|
GLuint m_ui_array;
|
||||||
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_ui_texture(unsigned id);
|
void load_ui_texture(unsigned id);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextureManager();
|
TextureManager();
|
||||||
~TextureManager();
|
~TextureManager();
|
||||||
@@ -22,4 +24,8 @@ public:
|
|||||||
GLuint get_ui_array() const;
|
GLuint get_ui_array() 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();
|
||||||
|
void hot_reload();
|
||||||
|
void need_reload();
|
||||||
|
void update();
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -16,10 +16,7 @@ namespace Assert {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef DEBUG_MODE
|
||||||
#define CUBED_ASSERT(cond) ((void)0)
|
|
||||||
#define CUBED_ASSERT_MSG(cond, message) ((void)0)
|
|
||||||
#else
|
|
||||||
#define CUBED_ASSERT(cond) \
|
#define CUBED_ASSERT(cond) \
|
||||||
do { \
|
do { \
|
||||||
if (!(cond)) { \
|
if (!(cond)) { \
|
||||||
@@ -32,4 +29,8 @@ namespace Assert {
|
|||||||
::Assert::msg(#cond, __FILE__, __LINE__, __func__, message); \
|
::Assert::msg(#cond, __FILE__, __LINE__, __func__, message); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define CUBED_ASSERT(cond) ((void)0)
|
||||||
|
#define CUBED_ASSERT_MSG(cond, message) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string_view>
|
||||||
namespace HASH {
|
namespace HASH {
|
||||||
inline std::size_t str(const std::string& value) {
|
inline std::size_t str(std::string_view value) {
|
||||||
return std::hash<std::string>{}(value);
|
return std::hash<std::string_view>{}(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
|
#include <Cubed/config.hpp>
|
||||||
|
|
||||||
struct Character {
|
struct Character {
|
||||||
glm::vec2 uv_min;
|
glm::vec2 uv_min;
|
||||||
glm::vec2 uv_max;
|
glm::vec2 uv_max;
|
||||||
@@ -23,8 +25,8 @@ public:
|
|||||||
Font();
|
Font();
|
||||||
~Font();
|
~Font();
|
||||||
|
|
||||||
static void render_text(const Shader& shader, const std::string& text, float x, float y, float scale, const glm::vec3& color);
|
static std::vector<Vertex2D> vertices(const std::string& text, float x = 0.0f, float y = 0.0f, float scale = 1.0f);
|
||||||
|
static GLuint text_texture();
|
||||||
private:
|
private:
|
||||||
FT_Library m_ft;
|
FT_Library m_ft;
|
||||||
FT_Face m_face;
|
FT_Face m_face;
|
||||||
@@ -32,7 +34,7 @@ private:
|
|||||||
float m_texture_width = 64;
|
float m_texture_width = 64;
|
||||||
float m_texture_height = 64;
|
float m_texture_height = 64;
|
||||||
|
|
||||||
GLuint m_text_texture;
|
static inline GLuint m_text_texture;
|
||||||
std::unordered_map<char8_t, Character> m_characters;
|
std::unordered_map<char8_t, Character> m_characters;
|
||||||
|
|
||||||
void load_character(char8_t c);
|
void load_character(char8_t c);
|
||||||
|
|||||||
67
include/Cubed/tools/system_version.hpp
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <Cubed/tools/log.hpp>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
typedef LONG (WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
|
||||||
|
inline bool get_os_version(std::string& str) {
|
||||||
|
HMODULE hntdll = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
if (!hntdll) return false;
|
||||||
|
|
||||||
|
auto prtl_get_version = reinterpret_cast<RtlGetVersionPtr>(
|
||||||
|
GetProcAddress(hntdll, "RtlGetVersion"));
|
||||||
|
if (!prtl_get_version) return false;
|
||||||
|
|
||||||
|
RTL_OSVERSIONINFOW osvi = { 0 };
|
||||||
|
osvi.dwOSVersionInfoSize = sizeof(osvi);
|
||||||
|
if (prtl_get_version(&osvi) != 0) return false;
|
||||||
|
if (osvi.dwMajorVersion == 10) {
|
||||||
|
if (osvi.dwBuildNumber >= 22000) {
|
||||||
|
str = "Windows 11 Build " + std::to_string(osvi.dwBuildNumber);
|
||||||
|
} else {
|
||||||
|
str = "Windows 10 Build " + std::to_string(osvi.dwBuildNumber);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
str = "Windows Build " + std::to_string(osvi.dwBuildNumber);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
inline bool get_os_version(std::string& str) {
|
||||||
|
std::ifstream file("/etc/os-release");
|
||||||
|
if (!file.is_open()) {
|
||||||
|
Logger::error("Can't Open /etc/os-release");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line)) {
|
||||||
|
size_t eq_pos = line.find("=");
|
||||||
|
if (eq_pos == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::string key = line.substr(0, eq_pos);
|
||||||
|
if (key != "PRETTY_NAME") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
str = line.substr(eq_pos + 1);
|
||||||
|
|
||||||
|
if (str.size() >= 2 && str.front() == '"' && str.back() == '"') {
|
||||||
|
str = str.substr(1, str.size() - 2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
inline bool get_os_version(std::string& str) {
|
||||||
|
str = "Unknown OS";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
65
include/Cubed/ui/color.hpp
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
enum class Color {
|
||||||
|
BLACK,
|
||||||
|
WHITE,
|
||||||
|
RED,
|
||||||
|
GREEN,
|
||||||
|
BLUE,
|
||||||
|
YELLOW,
|
||||||
|
CYAN,
|
||||||
|
MAGENTA,
|
||||||
|
GRAY,
|
||||||
|
ORANGE,
|
||||||
|
PURPLE,
|
||||||
|
PINK,
|
||||||
|
BROWN
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr glm::vec4 color_value(Color color) {
|
||||||
|
using glm::vec4;
|
||||||
|
|
||||||
|
switch (color) {
|
||||||
|
case Color::BLACK:
|
||||||
|
return vec4{0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
case Color::WHITE:
|
||||||
|
return vec4{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
case Color::RED:
|
||||||
|
return vec4{1.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
case Color::GREEN:
|
||||||
|
return vec4{0.0f, 1.0f, 0.0f, 1.0f};
|
||||||
|
case Color::BLUE:
|
||||||
|
return vec4{0.0f, 0.0f, 1.0f, 1.0f};
|
||||||
|
case Color::YELLOW:
|
||||||
|
return vec4{1.0f, 1.0f, 0.0f, 1.0f};
|
||||||
|
case Color::CYAN:
|
||||||
|
return vec4{0.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
case Color::MAGENTA:
|
||||||
|
return vec4{1.0f, 0.0f, 1.0f, 1.0f};
|
||||||
|
case Color::GRAY:
|
||||||
|
return vec4{0.5f, 0.5f, 0.5f, 1.0f};
|
||||||
|
case Color::ORANGE:
|
||||||
|
return vec4{1.0f, 0.647f, 0.0f, 1.0f};
|
||||||
|
case Color::PURPLE:
|
||||||
|
return vec4{0.502f, 0.0f, 0.502f, 1.0f};
|
||||||
|
case Color::PINK:
|
||||||
|
return vec4{1.0f, 0.753f, 0.769f, 1.0f};
|
||||||
|
case Color::BROWN:
|
||||||
|
return vec4{0.647f, 0.165f, 0.165f, 1.0f};
|
||||||
|
default:
|
||||||
|
CUBED_ASSERT_MSG(false, "Unknown Color");
|
||||||
|
return vec4{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
inline glm::vec4 rgb255_to_float(int r, int g, int b, int a) {
|
||||||
|
float nr = static_cast<float>(r) / 255.0f;
|
||||||
|
float ng = static_cast<float>(g) / 255.0f;
|
||||||
|
float nb = static_cast<float>(b) / 255.0f;
|
||||||
|
float na = static_cast<float>(a) / 255.0f;
|
||||||
|
|
||||||
|
return glm::vec4{nr, ng, nb, na};
|
||||||
|
}
|
||||||
53
include/Cubed/ui/text.hpp
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <Cubed/config.hpp>
|
||||||
|
#include <Cubed/ui/color.hpp>
|
||||||
|
|
||||||
|
class Shader;
|
||||||
|
|
||||||
|
class Text {
|
||||||
|
public:
|
||||||
|
explicit Text(std::string_view name);
|
||||||
|
Text(std::string_view name, std::string_view str, glm::vec2 pos = glm::vec2{0.0f, 0.0f}, Color color = Color::BLACK);
|
||||||
|
~Text();
|
||||||
|
Text(const Text&) = delete;
|
||||||
|
Text(Text&&) noexcept;
|
||||||
|
Text& operator=(const Text&) = delete;
|
||||||
|
Text& operator=(Text&&) noexcept = delete;
|
||||||
|
Text& color(Color color);
|
||||||
|
//Text& color(const glm::vec4& color, int pos);
|
||||||
|
Text& name(std::string_view name);
|
||||||
|
Text& position(float x, float y);
|
||||||
|
Text& scale(float s);
|
||||||
|
Text& text(std::string_view str);
|
||||||
|
|
||||||
|
std::size_t uuid() const;
|
||||||
|
static void set_loc(const Shader& shader);
|
||||||
|
void render();
|
||||||
|
|
||||||
|
bool operator==(const Text& other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float m_scale = 1.0f;
|
||||||
|
glm::vec2 m_pos{0.0f, 0.0f};
|
||||||
|
|
||||||
|
const std::string NAME;
|
||||||
|
const std::size_t UUID;
|
||||||
|
std::string m_text;
|
||||||
|
glm::vec4 m_color{1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
|
glm::mat4 m_model_matrix;
|
||||||
|
|
||||||
|
std::vector<Vertex2D> m_vertices;
|
||||||
|
GLuint m_vbo = 0;
|
||||||
|
static inline GLuint m_color_loc = 0;
|
||||||
|
static inline GLuint m_mv_loc = 0;
|
||||||
|
|
||||||
|
void update_vertices();
|
||||||
|
void upload_to_gpu();
|
||||||
|
|
||||||
|
};
|
||||||
@@ -6,12 +6,16 @@ public:
|
|||||||
Window(Renderer& renderer);
|
Window(Renderer& renderer);
|
||||||
~Window();
|
~Window();
|
||||||
|
|
||||||
|
bool is_mouse_enable() const;
|
||||||
const GLFWwindow* get_glfw_window() const;
|
const GLFWwindow* get_glfw_window() const;
|
||||||
GLFWwindow* get_glfw_window();
|
GLFWwindow* get_glfw_window();
|
||||||
void init();
|
void init();
|
||||||
void update_viewport();
|
void update_viewport();
|
||||||
void toggle_fullscreen();
|
void toggle_fullscreen();
|
||||||
|
void toggle_mouse_able();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool m_mouse_enable = false;
|
||||||
float m_aspect;
|
float m_aspect;
|
||||||
GLFWwindow* m_window;
|
GLFWwindow* m_window;
|
||||||
int m_width;
|
int m_width;
|
||||||
|
|||||||
18
src/app.cpp
@@ -1,4 +1,5 @@
|
|||||||
#include <Cubed/app.hpp>
|
#include <Cubed/app.hpp>
|
||||||
|
#include <Cubed/debug_collector.hpp>
|
||||||
#include <Cubed/gameplay/player.hpp>
|
#include <Cubed/gameplay/player.hpp>
|
||||||
#include <Cubed/map_table.hpp>
|
#include <Cubed/map_table.hpp>
|
||||||
#include <Cubed/tools/cubed_assert.hpp>
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
@@ -18,7 +19,10 @@ App::~App() {
|
|||||||
void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
|
void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
|
||||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||||
CUBED_ASSERT_MSG(app, "nullptr");
|
CUBED_ASSERT_MSG(app, "nullptr");
|
||||||
app->m_camera.update_cursor_position_camera(xpos, ypos);
|
if (!app->m_window.is_mouse_enable()) {
|
||||||
|
app->m_camera.update_cursor_position_camera(xpos, ypos);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void App::init() {
|
void App::init() {
|
||||||
m_window.init();
|
m_window.init();
|
||||||
@@ -44,7 +48,6 @@ void App::init() {
|
|||||||
Logger::info("Texture Load Success");
|
Logger::info("Texture Load Success");
|
||||||
m_world.init_world();
|
m_world.init_world();
|
||||||
Logger::info("World Init Success");
|
Logger::info("World Init Success");
|
||||||
m_texture_array = m_texture_manager.get_texture_array();
|
|
||||||
|
|
||||||
m_camera.camera_init(&m_world.get_player("TestPlayer"));
|
m_camera.camera_init(&m_world.get_player("TestPlayer"));
|
||||||
|
|
||||||
@@ -53,7 +56,7 @@ void App::init() {
|
|||||||
void App::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
void App::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||||
CUBED_ASSERT_MSG(app, "nullptr");
|
CUBED_ASSERT_MSG(app, "nullptr");
|
||||||
|
auto& input = Input::get_input_state();
|
||||||
switch(key) {
|
switch(key) {
|
||||||
case GLFW_KEY_Q:
|
case GLFW_KEY_Q:
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
@@ -77,7 +80,12 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, in
|
|||||||
break;
|
break;
|
||||||
case GLFW_KEY_R:
|
case GLFW_KEY_R:
|
||||||
if (action == GLFW_PRESS) {
|
if (action == GLFW_PRESS) {
|
||||||
app->m_world.need_gen();
|
app->m_texture_manager.need_reload();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GLFW_KEY_P:
|
||||||
|
if (action == GLFW_PRESS) {
|
||||||
|
app->m_window.toggle_mouse_able();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -153,10 +161,12 @@ void App::update() {
|
|||||||
if (fps_time_count >= 1.0f) {
|
if (fps_time_count >= 1.0f) {
|
||||||
fps = static_cast<int>(frame_count / fps_time_count);
|
fps = static_cast<int>(frame_count / fps_time_count);
|
||||||
std::string title = "Cubed FPS: " + std::to_string(fps);
|
std::string title = "Cubed FPS: " + std::to_string(fps);
|
||||||
|
DebugCollector::get().report("fps", std::string{"FPS: " + std::to_string(fps)});
|
||||||
glfwSetWindowTitle(m_window.get_glfw_window(), title.c_str());
|
glfwSetWindowTitle(m_window.get_glfw_window(), title.c_str());
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
fps_time_count = 0.0f;
|
fps_time_count = 0.0f;
|
||||||
}
|
}
|
||||||
|
m_texture_manager.update();
|
||||||
m_world.update(delta_time);
|
m_world.update(delta_time);
|
||||||
m_camera.update_move_camera();
|
m_camera.update_move_camera();
|
||||||
const auto& player= m_world.get_player("TestPlayer");
|
const auto& player= m_world.get_player("TestPlayer");
|
||||||
|
|||||||
73
src/debug_collector.cpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#include <Cubed/debug_collector.hpp>
|
||||||
|
|
||||||
|
#include <Cubed/tools/system_version.hpp>
|
||||||
|
#include <Cubed/tools/cubed_hash.hpp>
|
||||||
|
|
||||||
|
DebugCollector::DebugCollector() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugCollector& DebugCollector::get() {
|
||||||
|
static DebugCollector instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugCollector::init_text() {
|
||||||
|
Text version_text("version");
|
||||||
|
Text fps_text("fps");
|
||||||
|
Text player_pos_text("player_pos");
|
||||||
|
Text rendered_chunk_text("rendered_chunk");
|
||||||
|
|
||||||
|
version_text
|
||||||
|
.position(0.0f, 100.0f)
|
||||||
|
.scale(0.8f)
|
||||||
|
.color(Color::WHITE)
|
||||||
|
.text("Version: v0.0.1-Debug");
|
||||||
|
fps_text
|
||||||
|
.position(0.0f, 50.0f)
|
||||||
|
.text("FPS: 0");
|
||||||
|
player_pos_text
|
||||||
|
.position(0.0f, 150.0f)
|
||||||
|
.scale(0.8f)
|
||||||
|
.text("x: 0.00 y: 0.00 z: 0.00");
|
||||||
|
rendered_chunk_text
|
||||||
|
.text("Rendered Chunk: 0")
|
||||||
|
.scale(0.8f)
|
||||||
|
.position(0.0, 200.0f);
|
||||||
|
std::string os;
|
||||||
|
|
||||||
|
Text os_text("os");
|
||||||
|
os_text
|
||||||
|
.scale(0.8f)
|
||||||
|
.position(0.0f, 250.0f);
|
||||||
|
if (get_os_version(os)) {
|
||||||
|
os_text
|
||||||
|
.text("OS: " + os);
|
||||||
|
Logger::info("System: {}", os);
|
||||||
|
} else {
|
||||||
|
os_text
|
||||||
|
.text("OS: Unknown");
|
||||||
|
|
||||||
|
}
|
||||||
|
m_texts.insert({version_text.uuid(), std::move(version_text)});
|
||||||
|
m_texts.insert({fps_text.uuid(), std::move(fps_text)});
|
||||||
|
m_texts.insert({player_pos_text.uuid(), std::move(player_pos_text)});
|
||||||
|
m_texts.insert({rendered_chunk_text.uuid(), std::move(rendered_chunk_text)});
|
||||||
|
m_texts.insert({os_text.uuid(), std::move(os_text)});
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_map<std::size_t, Text>& DebugCollector::all_texts() {
|
||||||
|
return m_texts;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text& DebugCollector::text(std::string_view name) {
|
||||||
|
std::size_t id = HASH::str(name);
|
||||||
|
auto it = m_texts.find(id);
|
||||||
|
CUBED_ASSERT_MSG(it != m_texts.end(), "Can't Find Text");
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugCollector::report(std::string_view name, std::string_view content) {
|
||||||
|
auto& t = text(name);
|
||||||
|
t.text(content);
|
||||||
|
}
|
||||||
@@ -216,7 +216,7 @@ void Chunk::init_chunk() {
|
|||||||
for (int x = 0; x < CHUCK_SIZE; x++) {
|
for (int x = 0; x < CHUCK_SIZE; x++) {
|
||||||
for (int y = 0; y < 5; y++) {
|
for (int y = 0; y < 5; y++) {
|
||||||
for (int z = 0; z < CHUCK_SIZE; z++) {
|
for (int z = 0; z < CHUCK_SIZE; z++) {
|
||||||
m_blocks[get_index(x, y, z)] = 1;
|
m_blocks[get_index(x, y, z)] = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -233,10 +233,15 @@ void Chunk::init_chunk() {
|
|||||||
0.125f * PerlinNoise::noise(world_x * 0.04f, world_z * 0.04f, 0.5f);
|
0.125f * PerlinNoise::noise(world_x * 0.04f, world_z * 0.04f, 0.5f);
|
||||||
int y_max = height * noise;
|
int y_max = height * noise;
|
||||||
|
|
||||||
for (int y = 5; y < y_max; y++) {
|
for (int y = 5; y < y_max - 5; y++) {
|
||||||
|
m_blocks[get_index(x, y, z)] = 3;
|
||||||
|
}
|
||||||
|
for (int y = y_max - 5; y < y_max - 1; y++) {
|
||||||
|
m_blocks[get_index(x, y, z)] = 2;
|
||||||
|
}
|
||||||
|
for (int y = y_max - 1; y < y_max; y++) {
|
||||||
m_blocks[get_index(x, y, z)] = 1;
|
m_blocks[get_index(x, y, z)] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include <Cubed/gameplay/player.hpp>
|
#include <Cubed/gameplay/player.hpp>
|
||||||
|
|
||||||
|
#include <Cubed/debug_collector.hpp>
|
||||||
#include <Cubed/gameplay/world.hpp>
|
#include <Cubed/gameplay/world.hpp>
|
||||||
#include <Cubed/map_table.hpp>
|
#include <Cubed/map_table.hpp>
|
||||||
#include <Cubed/tools/cubed_assert.hpp>
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
@@ -138,6 +140,10 @@ void Player::update(float delta_time) {
|
|||||||
update_move(delta_time);
|
update_move(delta_time);
|
||||||
update_lookup_block();
|
update_lookup_block();
|
||||||
check_player_chunk_transition();
|
check_player_chunk_transition();
|
||||||
|
|
||||||
|
std::string player_pos = std::format("x: {:.2f} y: {:.2f} z: {:.2f}", m_player_pos.x, m_player_pos.y, m_player_pos.z);
|
||||||
|
DebugCollector::get().report("player_pos", player_pos);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::update_player_move_state(int key, int action) {
|
void Player::update_player_move_state(int key, int action) {
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include <Cubed/gameplay/world.hpp>
|
#include <Cubed/gameplay/world.hpp>
|
||||||
|
|
||||||
|
#include <Cubed/debug_collector.hpp>
|
||||||
#include <Cubed/gameplay/player.hpp>
|
#include <Cubed/gameplay/player.hpp>
|
||||||
#include <Cubed/map_table.hpp>
|
#include <Cubed/map_table.hpp>
|
||||||
#include <Cubed/tools/cubed_assert.hpp>
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
@@ -128,7 +130,7 @@ void World::init_world() {
|
|||||||
|
|
||||||
void World::render(const glm::mat4& mvp_matrix) {
|
void World::render(const glm::mat4& mvp_matrix) {
|
||||||
Math::extract_frustum_planes(mvp_matrix, m_planes);
|
Math::extract_frustum_planes(mvp_matrix, m_planes);
|
||||||
|
int rendered_sum = 0;
|
||||||
for (const auto& snapshot : m_render_snapshots) {
|
for (const auto& snapshot : m_render_snapshots) {
|
||||||
|
|
||||||
if (is_aabb_in_frustum(snapshot.center, snapshot.half_extents)) {
|
if (is_aabb_in_frustum(snapshot.center, snapshot.half_extents)) {
|
||||||
@@ -143,11 +145,13 @@ void World::render(const glm::mat4& mvp_matrix) {
|
|||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, snapshot.vertex_count);
|
glDrawArrays(GL_TRIANGLES, 0, snapshot.vertex_count);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
rendered_sum++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
DebugCollector::get().report("rendered_chunk", "Rendered Chunk: " + std::to_string(rendered_sum));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,18 @@
|
|||||||
#include <Cubed/tools/cubed_assert.hpp>
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
#include <Cubed/tools/cubed_hash.hpp>
|
#include <Cubed/tools/cubed_hash.hpp>
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
std::unordered_map<unsigned, std::string> MapTable::id_to_name_map;
|
std::unordered_map<unsigned, std::string> MapTable::id_to_name_map;
|
||||||
std::unordered_map<size_t, unsigned> MapTable::name_to_id_map;
|
std::unordered_map<size_t, unsigned> MapTable::name_to_id_map;
|
||||||
|
|
||||||
|
constexpr std::array<std::string_view, MAX_BLOCK_NUM> BLOCK_REISTER{
|
||||||
|
"air",
|
||||||
|
"grass_block",
|
||||||
|
"dirt",
|
||||||
|
"stone"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const std::string& MapTable::get_name_from_id(unsigned id) {
|
const std::string& MapTable::get_name_from_id(unsigned id) {
|
||||||
auto it = id_to_name_map.find(id);
|
auto it = id_to_name_map.find(id);
|
||||||
@@ -17,13 +26,16 @@ const unsigned MapTable::get_id_from_name(const std::string& name) {
|
|||||||
CUBED_ASSERT_MSG(it != name_to_id_map.end(), "Name " + name + " is not exist");
|
CUBED_ASSERT_MSG(it != name_to_id_map.end(), "Name " + name + " is not exist");
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapTable::init_map() {
|
void MapTable::init_map() {
|
||||||
id_to_name_map.reserve(MAX_BLOCK_NUM);
|
id_to_name_map.reserve(MAX_BLOCK_NUM);
|
||||||
name_to_id_map.reserve(MAX_BLOCK_NUM);
|
name_to_id_map.reserve(MAX_BLOCK_NUM);
|
||||||
id_to_name_map[0] = "air";
|
|
||||||
name_to_id_map[HASH::str("air")] = 0;
|
for (int i = 0; i < MAX_BLOCK_NUM; i++) {
|
||||||
id_to_name_map[1] = "grass_block";
|
id_to_name_map[i] = BLOCK_REISTER[i];
|
||||||
name_to_id_map[HASH::str("grass_block")] = 1;
|
name_to_id_map[HASH::str(BLOCK_REISTER[i])] = i;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <Cubed/app.hpp>
|
#include <Cubed/app.hpp>
|
||||||
#include <Cubed/camera.hpp>
|
#include <Cubed/camera.hpp>
|
||||||
#include <Cubed/config.hpp>
|
#include <Cubed/config.hpp>
|
||||||
|
#include <Cubed/debug_collector.hpp>
|
||||||
#include <Cubed/gameplay/player.hpp>
|
#include <Cubed/gameplay/player.hpp>
|
||||||
#include <Cubed/gameplay/world.hpp>
|
#include <Cubed/gameplay/world.hpp>
|
||||||
#include <Cubed/texture_manager.hpp>
|
#include <Cubed/texture_manager.hpp>
|
||||||
@@ -62,7 +63,7 @@ void Renderer::init() {
|
|||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifdef DEBUG_MODE
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* user_param) {
|
glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* user_param) {
|
||||||
Logger::log(Logger::Level::DEBUG, std::source_location::current(),"GL Debug: {}", reinterpret_cast<const char*>(message));
|
Logger::log(Logger::Level::DEBUG, std::source_location::current(),"GL Debug: {}", reinterpret_cast<const char*>(message));
|
||||||
@@ -104,6 +105,8 @@ void Renderer::init() {
|
|||||||
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)* 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(float)* 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
init_text();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Shader& Renderer::get_shader(const std::string& name) const {
|
const Shader& Renderer::get_shader(const std::string& name) const {
|
||||||
@@ -112,6 +115,12 @@ const Shader& Renderer::get_shader(const std::string& name) const {
|
|||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::init_text() {
|
||||||
|
const auto& shader = get_shader("text");
|
||||||
|
Text::set_loc(shader);
|
||||||
|
DebugCollector::get().init_text();
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::render() {
|
void Renderer::render() {
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
@@ -193,14 +202,10 @@ void Renderer::render_text() {
|
|||||||
|
|
||||||
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj));
|
glUniformMatrix4fv(m_proj_loc, 1, GL_FALSE, glm::value_ptr(m_ui_proj));
|
||||||
|
|
||||||
Font::render_text(shader, std::string{"FPS: " + std::to_string(static_cast<int>(App::get_fps()))}, 0.0f, 50.0f, 1.0f, glm::vec3(1.0f, 1.0f, 1.0f));
|
auto& texts = DebugCollector::get().all_texts();
|
||||||
|
for (auto& t : texts) {
|
||||||
Font::render_text(shader, "Version: v0.0.1-Debug", 0.0f, 100.0f, 0.8f, glm::vec3(1.0f, 1.0f, 1.0f));
|
t.second.render();
|
||||||
|
}
|
||||||
const auto& player = m_world.get_player("TestPlayer");
|
|
||||||
const auto& pos = player.get_player_pos();
|
|
||||||
std::string player_pos = std::format("x: {:.2f} y: {:.2f} z: {:.2f}", pos.x, pos.y, pos.z);
|
|
||||||
Font::render_text(shader, player_pos, 0.0f, 150.0f, 0.8f, glm::vec3(1.0f, 1.0f, 1.0f));
|
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ GLuint TextureManager::get_ui_array() const{
|
|||||||
void TextureManager::load_block_status(unsigned id) {
|
void TextureManager::load_block_status(unsigned id) {
|
||||||
|
|
||||||
CUBED_ASSERT_MSG(id < MAX_BLOCK_STATUS, "Exceed the max status sum limit");
|
CUBED_ASSERT_MSG(id < MAX_BLOCK_STATUS, "Exceed the max status sum limit");
|
||||||
std::string path = "assets/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);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, m_block_status_array);
|
||||||
@@ -54,7 +54,7 @@ void TextureManager::load_block_texture(unsigned id) {
|
|||||||
}
|
}
|
||||||
unsigned char* image_data[6];
|
unsigned char* image_data[6];
|
||||||
|
|
||||||
std::string block_texture_path = "assets/texture/block/" + name;
|
std::string block_texture_path = "texture/block/" + name;
|
||||||
image_data[0] = (Tools::load_image_data(block_texture_path + "/front.png"));
|
image_data[0] = (Tools::load_image_data(block_texture_path + "/front.png"));
|
||||||
image_data[1] = (Tools::load_image_data(block_texture_path + "/right.png"));
|
image_data[1] = (Tools::load_image_data(block_texture_path + "/right.png"));
|
||||||
image_data[2] = (Tools::load_image_data(block_texture_path + "/back.png"));
|
image_data[2] = (Tools::load_image_data(block_texture_path + "/back.png"));
|
||||||
@@ -80,7 +80,7 @@ void TextureManager::load_block_texture(unsigned id) {
|
|||||||
void TextureManager::load_ui_texture(unsigned id) {
|
void TextureManager::load_ui_texture(unsigned id) {
|
||||||
CUBED_ASSERT_MSG(id < MAX_UI_NUM, "Exceed the max ui sum limit");
|
CUBED_ASSERT_MSG(id < MAX_UI_NUM, "Exceed the max ui sum limit");
|
||||||
|
|
||||||
std::string path = "assets/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);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, m_ui_array);
|
||||||
@@ -179,3 +179,19 @@ void TextureManager::init_texture() {
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextureManager::update() {
|
||||||
|
if (m_need_reload) {
|
||||||
|
hot_reload();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureManager::need_reload() {
|
||||||
|
m_need_reload = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextureManager::hot_reload() {
|
||||||
|
delet_texture();
|
||||||
|
init_texture();
|
||||||
|
m_need_reload = false;
|
||||||
|
}
|
||||||
@@ -1,18 +1,16 @@
|
|||||||
#include <Cubed/config.hpp>
|
|
||||||
#include <Cubed/shader.hpp>
|
#include <Cubed/shader.hpp>
|
||||||
#include <Cubed/tools/font.hpp>
|
#include <Cubed/tools/font.hpp>
|
||||||
#include <Cubed/tools/log.hpp>
|
#include <Cubed/tools/log.hpp>
|
||||||
#include <Cubed/tools/shader_tools.hpp>
|
#include <Cubed/tools/shader_tools.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Font::Font() {
|
Font::Font() {
|
||||||
|
|
||||||
if (FT_Init_FreeType(&m_ft)) {
|
if (FT_Init_FreeType(&m_ft)) {
|
||||||
Logger::error("FREETYPE: Could not init FreeType Library");
|
Logger::error("FREETYPE: Could not init FreeType Library");
|
||||||
}
|
}
|
||||||
if (FT_New_Face(m_ft, "assets/fonts/IBMPlexSans-Regular.ttf", 0, &m_face)) {
|
if (FT_New_Face(m_ft, ASSETS_PATH "fonts/IBMPlexSans-Regular.ttf", 0, &m_face)) {
|
||||||
Logger::error("FREETYPE: Failed to load font");
|
Logger::error("FREETYPE: Failed to load font");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,9 +22,7 @@ Font::~Font() {
|
|||||||
|
|
||||||
FT_Done_Face(m_face);
|
FT_Done_Face(m_face);
|
||||||
FT_Done_FreeType(m_ft);
|
FT_Done_FreeType(m_ft);
|
||||||
for (const auto& [key, character] : m_characters) {
|
glDeleteTextures(1, &m_text_texture);
|
||||||
glDeleteTextures(1, &m_text_texture);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::load_character(char8_t c) {
|
void Font::load_character(char8_t c) {
|
||||||
@@ -36,6 +32,7 @@ void Font::load_character(char8_t c) {
|
|||||||
}
|
}
|
||||||
const auto& width = m_face->glyph->bitmap.width;
|
const auto& width = m_face->glyph->bitmap.width;
|
||||||
const auto& height = m_face->glyph->bitmap.rows;
|
const auto& height = m_face->glyph->bitmap.rows;
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, m_text_texture);
|
||||||
glTexSubImage3D(
|
glTexSubImage3D(
|
||||||
GL_TEXTURE_2D_ARRAY,
|
GL_TEXTURE_2D_ARRAY,
|
||||||
0,
|
0,
|
||||||
@@ -90,13 +87,9 @@ void Font::setup_font_character() {
|
|||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Vertex2D> Font::vertices(const std::string &text, float x, float y, float scale) {
|
||||||
|
|
||||||
void Font::render_text(const Shader& shader, const std::string& text, float x, float y, float scale, const glm::vec3& color) {
|
|
||||||
static Font font;
|
static Font font;
|
||||||
|
|
||||||
glUniform3f(shader.loc("textColor"), color.x, color.y, color.z);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
std::vector<Vertex2D> vertices;
|
std::vector<Vertex2D> vertices;
|
||||||
|
|
||||||
for (char8_t c : text) {
|
for (char8_t c : text) {
|
||||||
@@ -122,22 +115,10 @@ void Font::render_text(const Shader& shader, const std::string& text, float x, f
|
|||||||
x += (ch.advance >> 6) * scale;
|
x += (ch.advance >> 6) * scale;
|
||||||
|
|
||||||
}
|
}
|
||||||
GLuint vbo;
|
|
||||||
glGenBuffers(1, &vbo);
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex2D), vertices.data(), GL_STATIC_DRAW);
|
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, font.m_text_texture);
|
|
||||||
|
|
||||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
|
return vertices;
|
||||||
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));
|
|
||||||
|
GLuint Font::text_texture() {
|
||||||
glEnableVertexAttribArray(0);
|
return m_text_texture;
|
||||||
glEnableVertexAttribArray(1);
|
|
||||||
glEnableVertexAttribArray(2);
|
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, vertices.size());
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
|
||||||
glDeleteBuffers(1, &vbo);
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,19 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
#include <Cubed/config.hpp>
|
#include <Cubed/config.hpp>
|
||||||
#include <Cubed/tools/cubed_assert.hpp>
|
#include <Cubed/tools/cubed_assert.hpp>
|
||||||
#include <Cubed/tools/shader_tools.hpp>
|
#include <Cubed/tools/shader_tools.hpp>
|
||||||
#include <Cubed/tools/log.hpp>
|
#include <Cubed/tools/log.hpp>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
namespace Tools {
|
namespace Tools {
|
||||||
|
|
||||||
GLuint create_shader_program(const std::string& v_shader_path, const std::string& f_shader_path) {
|
GLuint create_shader_program(const std::string& v_shader_path, const std::string& f_shader_path) {
|
||||||
std::string v_shader_str = Tools::read_shader_source(v_shader_path);
|
|
||||||
std::string f_shader_str = Tools::read_shader_source(f_shader_path);
|
std::string v_shader_str = Tools::read_shader_source(ASSETS_PATH + v_shader_path);
|
||||||
|
std::string f_shader_str = Tools::read_shader_source(ASSETS_PATH + f_shader_path);
|
||||||
const char *v_shader_source = v_shader_str.c_str();
|
const char *v_shader_source = v_shader_str.c_str();
|
||||||
const char *f_shader_source = f_shader_str.c_str();
|
const char *f_shader_source = f_shader_str.c_str();
|
||||||
|
|
||||||
@@ -119,11 +122,12 @@ namespace Tools {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* load_image_data(const std::string& tex_image_path) {
|
unsigned char* load_image_data(const std::string& tex_image_path) {
|
||||||
|
fs::path path = ASSETS_PATH + tex_image_path;
|
||||||
|
CUBED_ASSERT_MSG(fs::is_regular_file(path), path.c_str());
|
||||||
unsigned char* data = nullptr;
|
unsigned char* data = nullptr;
|
||||||
int width, height, channels;
|
int width, height, channels;
|
||||||
data = SOIL_load_image(tex_image_path.c_str(), &width, &height, &channels, SOIL_LOAD_AUTO);
|
data = SOIL_load_image(path.string().c_str(), &width, &height, &channels, SOIL_LOAD_AUTO);
|
||||||
std::string error_info = "Could not load texture " + tex_image_path;
|
CUBED_ASSERT_MSG(data, "Could not load texture" + path.string());
|
||||||
CUBED_ASSERT_MSG(data, error_info.c_str());
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|||||||
119
src/ui/text.cpp
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
#include <Cubed/ui/text.hpp>
|
||||||
|
|
||||||
|
#include <Cubed/shader.hpp>
|
||||||
|
#include <Cubed/tools/cubed_hash.hpp>
|
||||||
|
#include <Cubed/tools/font.hpp>
|
||||||
|
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
Text::Text(std::string_view name) :
|
||||||
|
NAME(name),
|
||||||
|
UUID(HASH::str(name))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::Text(std::string_view name, std::string_view str, glm::vec2 pos, Color color) :
|
||||||
|
NAME(name),
|
||||||
|
UUID(HASH::str(name))
|
||||||
|
{
|
||||||
|
m_text.assign(str);
|
||||||
|
m_pos = pos;
|
||||||
|
m_color = color_value(color);
|
||||||
|
update_vertices();
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::~Text() {
|
||||||
|
if (m_vbo != 0) {
|
||||||
|
glDeleteBuffers(1, &m_vbo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text::Text(Text&& other) noexcept :
|
||||||
|
UUID(other.UUID),
|
||||||
|
NAME(other.NAME),
|
||||||
|
m_scale(other.m_scale),
|
||||||
|
m_vbo(other.m_vbo),
|
||||||
|
m_color(other.m_color),
|
||||||
|
m_model_matrix(other.m_model_matrix),
|
||||||
|
m_pos(other.m_pos),
|
||||||
|
m_text(std::move(other.m_text)),
|
||||||
|
m_vertices(std::move(other.m_vertices))
|
||||||
|
{
|
||||||
|
other.m_vbo = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text& Text::color(Color color) {
|
||||||
|
m_color = color_value(color);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text& Text::position(float x, float y) {
|
||||||
|
m_pos = glm::vec2{x, y};
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Text& Text::scale(float s) {
|
||||||
|
m_scale = s;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Text::uuid() const {
|
||||||
|
return UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::set_loc(const Shader& shader) {
|
||||||
|
m_color_loc = shader.loc("textColor");
|
||||||
|
m_mv_loc = shader.loc("mv_matrix");
|
||||||
|
}
|
||||||
|
|
||||||
|
Text& Text::text(std::string_view str) {
|
||||||
|
m_text.assign(str);
|
||||||
|
update_vertices();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::render() {
|
||||||
|
CUBED_ASSERT_MSG(m_vbo != 0,"VBO not initialized!");
|
||||||
|
CUBED_ASSERT_MSG(!m_vertices.empty(), "Text String Not Set");
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, Font::text_texture());
|
||||||
|
CUBED_ASSERT_MSG(m_color_loc, "m_color_loc is null");
|
||||||
|
|
||||||
|
m_model_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(m_pos.x, m_pos.y, 0.0f)) *
|
||||||
|
glm::scale(glm::mat4(1.0f), glm::vec3(m_scale, m_scale, 1.0f));
|
||||||
|
|
||||||
|
glUniform3f(m_color_loc, m_color.x, m_color.y, m_color.z);
|
||||||
|
glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_model_matrix));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void*)0);
|
||||||
|
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);
|
||||||
|
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::update_vertices() {
|
||||||
|
m_vertices = Font::vertices(m_text);
|
||||||
|
upload_to_gpu();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::upload_to_gpu() {
|
||||||
|
if (m_vbo == 0) {
|
||||||
|
glGenBuffers(1, &m_vbo);
|
||||||
|
}
|
||||||
|
CUBED_ASSERT_MSG(m_vbo, "Vbo Is Not Gen");
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex2D), m_vertices.data(), GL_DYNAMIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Text::operator==(const Text& other) const {
|
||||||
|
return UUID == other.uuid();
|
||||||
|
}
|
||||||
@@ -19,6 +19,10 @@ Window::~Window() {
|
|||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Window::is_mouse_enable() const {
|
||||||
|
return m_mouse_enable;
|
||||||
|
}
|
||||||
|
|
||||||
const GLFWwindow* Window::get_glfw_window() const {
|
const GLFWwindow* Window::get_glfw_window() const {
|
||||||
return m_window;
|
return m_window;
|
||||||
}
|
}
|
||||||
@@ -98,3 +102,13 @@ void Window::toggle_fullscreen() {
|
|||||||
}
|
}
|
||||||
update_viewport();
|
update_viewport();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::toggle_mouse_able() {
|
||||||
|
if (m_mouse_enable) {
|
||||||
|
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
|
m_mouse_enable = false;
|
||||||
|
} else {
|
||||||
|
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
|
m_mouse_enable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||