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}
|
||||
src/main.cpp
|
||||
src/app.cpp
|
||||
src/debug_collector.cpp
|
||||
src/camera.cpp
|
||||
src/gameplay/chunk.cpp
|
||||
src/gameplay/player.cpp
|
||||
@@ -94,6 +95,7 @@ add_executable(${PROJECT_NAME}
|
||||
src/tools/font.cpp
|
||||
src/tools/log.cpp
|
||||
src/tools/perlin_noise.cpp
|
||||
src/ui/text.cpp
|
||||
src/window.cpp
|
||||
)
|
||||
|
||||
@@ -109,6 +111,15 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
-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()
|
||||
|
||||
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})
|
||||
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;
|
||||
flat out int tex_layer;
|
||||
uniform mat4 projection;
|
||||
|
||||
uniform mat4 mv_matrix;
|
||||
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;
|
||||
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};
|
||||
|
||||
|
||||
GLuint m_texture_array = 0;
|
||||
|
||||
inline static double last_time = glfwGetTime();
|
||||
inline static double current_time = glfwGetTime();
|
||||
inline static double delta_time = 0.0f;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
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 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;
|
||||
};
|
||||
|
||||
struct KeyState {
|
||||
bool r = false;
|
||||
};
|
||||
|
||||
struct InputState {
|
||||
MoveState move_state;
|
||||
MouseState mouse_state;
|
||||
KeyState key_state;
|
||||
};
|
||||
|
||||
namespace Input {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/shader.hpp>
|
||||
#include <Cubed/ui/text.hpp>
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <glm/glm.hpp>
|
||||
@@ -45,6 +46,9 @@ private:
|
||||
std::unordered_map<std::size_t, Shader> m_shaders;
|
||||
std::vector<GLuint> m_vao;
|
||||
std::vector<Vertex2D> m_ui;
|
||||
|
||||
void init_text();
|
||||
|
||||
void render_outline();
|
||||
void render_sky();
|
||||
void render_text();
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
|
||||
class TextureManager {
|
||||
private:
|
||||
bool m_need_reload = false;
|
||||
GLuint m_block_status_array;
|
||||
GLuint m_texture_array;
|
||||
GLuint m_ui_array;
|
||||
void load_block_status(unsigned status_id);
|
||||
void load_block_texture(unsigned block_id);
|
||||
void load_ui_texture(unsigned id);
|
||||
|
||||
public:
|
||||
TextureManager();
|
||||
~TextureManager();
|
||||
@@ -22,4 +24,8 @@ public:
|
||||
GLuint get_ui_array() const;
|
||||
// Must call after MapTable::init_map() and glfwMakeContextCurrent(window);
|
||||
void init_texture();
|
||||
void hot_reload();
|
||||
void need_reload();
|
||||
void update();
|
||||
|
||||
};
|
||||
@@ -16,10 +16,7 @@ namespace Assert {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define CUBED_ASSERT(cond) ((void)0)
|
||||
#define CUBED_ASSERT_MSG(cond, message) ((void)0)
|
||||
#else
|
||||
#ifdef DEBUG_MODE
|
||||
#define CUBED_ASSERT(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
@@ -32,4 +29,8 @@ namespace Assert {
|
||||
::Assert::msg(#cond, __FILE__, __LINE__, __func__, message); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define CUBED_ASSERT(cond) ((void)0)
|
||||
#define CUBED_ASSERT_MSG(cond, message) ((void)0)
|
||||
#endif
|
||||
@@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
namespace HASH {
|
||||
inline std::size_t str(const std::string& value) {
|
||||
return std::hash<std::string>{}(value);
|
||||
inline std::size_t str(std::string_view value) {
|
||||
return std::hash<std::string_view>{}(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
|
||||
struct Character {
|
||||
glm::vec2 uv_min;
|
||||
glm::vec2 uv_max;
|
||||
@@ -23,8 +25,8 @@ public:
|
||||
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:
|
||||
FT_Library m_ft;
|
||||
FT_Face m_face;
|
||||
@@ -32,7 +34,7 @@ private:
|
||||
float m_texture_width = 64;
|
||||
float m_texture_height = 64;
|
||||
|
||||
GLuint m_text_texture;
|
||||
static inline GLuint m_text_texture;
|
||||
std::unordered_map<char8_t, Character> m_characters;
|
||||
|
||||
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();
|
||||
|
||||
bool is_mouse_enable() const;
|
||||
const GLFWwindow* get_glfw_window() const;
|
||||
GLFWwindow* get_glfw_window();
|
||||
void init();
|
||||
void update_viewport();
|
||||
void toggle_fullscreen();
|
||||
void toggle_mouse_able();
|
||||
|
||||
private:
|
||||
bool m_mouse_enable = false;
|
||||
float m_aspect;
|
||||
GLFWwindow* m_window;
|
||||
int m_width;
|
||||
|
||||
18
src/app.cpp
@@ -1,4 +1,5 @@
|
||||
#include <Cubed/app.hpp>
|
||||
#include <Cubed/debug_collector.hpp>
|
||||
#include <Cubed/gameplay/player.hpp>
|
||||
#include <Cubed/map_table.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
@@ -18,7 +19,10 @@ App::~App() {
|
||||
void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
|
||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||
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() {
|
||||
m_window.init();
|
||||
@@ -44,7 +48,6 @@ void App::init() {
|
||||
Logger::info("Texture Load Success");
|
||||
m_world.init_world();
|
||||
Logger::info("World Init Success");
|
||||
m_texture_array = m_texture_manager.get_texture_array();
|
||||
|
||||
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) {
|
||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||
CUBED_ASSERT_MSG(app, "nullptr");
|
||||
|
||||
auto& input = Input::get_input_state();
|
||||
switch(key) {
|
||||
case GLFW_KEY_Q:
|
||||
if (action == GLFW_PRESS) {
|
||||
@@ -77,7 +80,12 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action, in
|
||||
break;
|
||||
case GLFW_KEY_R:
|
||||
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;
|
||||
|
||||
@@ -153,10 +161,12 @@ void App::update() {
|
||||
if (fps_time_count >= 1.0f) {
|
||||
fps = static_cast<int>(frame_count / fps_time_count);
|
||||
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());
|
||||
frame_count = 0;
|
||||
fps_time_count = 0.0f;
|
||||
}
|
||||
m_texture_manager.update();
|
||||
m_world.update(delta_time);
|
||||
m_camera.update_move_camera();
|
||||
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 y = 0; y < 5; y++) {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <Cubed/gameplay/player.hpp>
|
||||
|
||||
#include <Cubed/debug_collector.hpp>
|
||||
#include <Cubed/gameplay/world.hpp>
|
||||
#include <Cubed/map_table.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
@@ -138,6 +140,10 @@ void Player::update(float delta_time) {
|
||||
update_move(delta_time);
|
||||
update_lookup_block();
|
||||
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) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
#include <Cubed/gameplay/world.hpp>
|
||||
|
||||
#include <Cubed/debug_collector.hpp>
|
||||
#include <Cubed/gameplay/player.hpp>
|
||||
#include <Cubed/map_table.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
@@ -128,7 +130,7 @@ void World::init_world() {
|
||||
|
||||
void World::render(const glm::mat4& mvp_matrix) {
|
||||
Math::extract_frustum_planes(mvp_matrix, m_planes);
|
||||
|
||||
int rendered_sum = 0;
|
||||
for (const auto& snapshot : m_render_snapshots) {
|
||||
|
||||
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);
|
||||
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_hash.hpp>
|
||||
|
||||
#include <array>
|
||||
|
||||
std::unordered_map<unsigned, std::string> MapTable::id_to_name_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) {
|
||||
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");
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void MapTable::init_map() {
|
||||
id_to_name_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;
|
||||
id_to_name_map[1] = "grass_block";
|
||||
name_to_id_map[HASH::str("grass_block")] = 1;
|
||||
|
||||
for (int i = 0; i < MAX_BLOCK_NUM; i++) {
|
||||
id_to_name_map[i] = BLOCK_REISTER[i];
|
||||
name_to_id_map[HASH::str(BLOCK_REISTER[i])] = i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <Cubed/app.hpp>
|
||||
#include <Cubed/camera.hpp>
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/debug_collector.hpp>
|
||||
#include <Cubed/gameplay/player.hpp>
|
||||
#include <Cubed/gameplay/world.hpp>
|
||||
#include <Cubed/texture_manager.hpp>
|
||||
@@ -62,7 +63,7 @@ void Renderer::init() {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef DEBUG_MODE
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
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));
|
||||
@@ -104,6 +105,8 @@ void Renderer::init() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_text_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(float)* 6 * 4, NULL, GL_DYNAMIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
init_text();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void Renderer::init_text() {
|
||||
const auto& shader = get_shader("text");
|
||||
Text::set_loc(shader);
|
||||
DebugCollector::get().init_text();
|
||||
}
|
||||
|
||||
void Renderer::render() {
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
Font::render_text(shader, "Version: v0.0.1-Debug", 0.0f, 100.0f, 0.8f, glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
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));
|
||||
auto& texts = DebugCollector::get().all_texts();
|
||||
for (auto& t : texts) {
|
||||
t.second.render();
|
||||
}
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ GLuint TextureManager::get_ui_array() const{
|
||||
void TextureManager::load_block_status(unsigned id) {
|
||||
|
||||
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;
|
||||
image_data = (Tools::load_image_data(path));
|
||||
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];
|
||||
|
||||
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[1] = (Tools::load_image_data(block_texture_path + "/right.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) {
|
||||
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;
|
||||
image_data = (Tools::load_image_data(path));
|
||||
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/tools/font.hpp>
|
||||
#include <Cubed/tools/log.hpp>
|
||||
#include <Cubed/tools/shader_tools.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
Font::Font() {
|
||||
|
||||
if (FT_Init_FreeType(&m_ft)) {
|
||||
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");
|
||||
}
|
||||
|
||||
@@ -24,9 +22,7 @@ Font::~Font() {
|
||||
|
||||
FT_Done_Face(m_face);
|
||||
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) {
|
||||
@@ -36,6 +32,7 @@ void Font::load_character(char8_t c) {
|
||||
}
|
||||
const auto& width = m_face->glyph->bitmap.width;
|
||||
const auto& height = m_face->glyph->bitmap.rows;
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, m_text_texture);
|
||||
glTexSubImage3D(
|
||||
GL_TEXTURE_2D_ARRAY,
|
||||
0,
|
||||
@@ -90,13 +87,9 @@ void Font::setup_font_character() {
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Font::render_text(const Shader& shader, const std::string& text, float x, float y, float scale, const glm::vec3& color) {
|
||||
std::vector<Vertex2D> Font::vertices(const std::string &text, float x, float y, float scale) {
|
||||
static Font font;
|
||||
|
||||
glUniform3f(shader.loc("textColor"), color.x, color.y, color.z);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
std::vector<Vertex2D> vertices;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
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);
|
||||
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, vertices.size());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
glDeleteBuffers(1, &vbo);
|
||||
return vertices;
|
||||
}
|
||||
|
||||
GLuint Font::text_texture() {
|
||||
return m_text_texture;
|
||||
}
|
||||
@@ -1,16 +1,19 @@
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
#include <Cubed/tools/shader_tools.hpp>
|
||||
#include <Cubed/tools/log.hpp>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Tools {
|
||||
|
||||
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 *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) {
|
||||
fs::path path = ASSETS_PATH + tex_image_path;
|
||||
CUBED_ASSERT_MSG(fs::is_regular_file(path), path.c_str());
|
||||
unsigned char* data = nullptr;
|
||||
int width, height, channels;
|
||||
data = SOIL_load_image(tex_image_path.c_str(), &width, &height, &channels, SOIL_LOAD_AUTO);
|
||||
std::string error_info = "Could not load texture " + tex_image_path;
|
||||
CUBED_ASSERT_MSG(data, error_info.c_str());
|
||||
data = SOIL_load_image(path.string().c_str(), &width, &height, &channels, SOIL_LOAD_AUTO);
|
||||
CUBED_ASSERT_MSG(data, "Could not load texture" + path.string());
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
bool Window::is_mouse_enable() const {
|
||||
return m_mouse_enable;
|
||||
}
|
||||
|
||||
const GLFWwindow* Window::get_glfw_window() const {
|
||||
return m_window;
|
||||
}
|
||||
@@ -98,3 +102,13 @@ void Window::toggle_fullscreen() {
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||