mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
Compare commits
4 Commits
2d28488126
...
674c023228
| Author | SHA1 | Date | |
|---|---|---|---|
| 674c023228 | |||
| d00ada1391 | |||
| cb1eb25e7b | |||
| 5712ba0600 |
@@ -1,27 +1,19 @@
|
||||
#pragma once
|
||||
#include "Cubed/audio/audio_engine.hpp"
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/gameplay/network_server.hpp"
|
||||
#include "Cubed/gameplay/server_world.hpp"
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/argument.hpp"
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/dev_panel.hpp"
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/scene/scene_manager.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
#include "Cubed/window.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
class App {
|
||||
public:
|
||||
struct Argument {
|
||||
bool is_client = false;
|
||||
int port = 25530;
|
||||
std::string ip{"127.0.0.1"};
|
||||
std::string player{"Unknown"};
|
||||
bool debug_on = true;
|
||||
};
|
||||
|
||||
App();
|
||||
~App();
|
||||
static void cursor_position_callback(GLFWwindow* window, double xpos,
|
||||
@@ -33,6 +25,8 @@ public:
|
||||
static void window_focus_callback(GLFWwindow* window, int focused);
|
||||
static void window_reshape_callback(GLFWwindow* window, int new_width,
|
||||
int new_height);
|
||||
static void framebuffer_size_callback(GLFWwindow* window, int new_width,
|
||||
int new_height);
|
||||
static void mouse_scroll_callback(GLFWwindow* window, double xoffset,
|
||||
double yoffset);
|
||||
static void cursor_enter_callback(GLFWwindow* window, int entered);
|
||||
@@ -43,12 +37,9 @@ public:
|
||||
static float delta_time();
|
||||
static float get_fps();
|
||||
|
||||
Camera& camera();
|
||||
DevPanel& dev_panel();
|
||||
Renderer& renderer();
|
||||
TextureManager& texture_manager();
|
||||
Window& window();
|
||||
ClientWorld& client_world();
|
||||
ServerWorld& server_world();
|
||||
Config& config();
|
||||
const Argument& argument() const;
|
||||
@@ -56,18 +47,17 @@ public:
|
||||
|
||||
private:
|
||||
Config m_game_config;
|
||||
Camera m_camera;
|
||||
|
||||
TextureManager m_texture_manager;
|
||||
NetworkServer m_server;
|
||||
std::shared_ptr<NetworkClient> m_client;
|
||||
AudioEngine m_audio;
|
||||
ClientWorld m_client_world;
|
||||
|
||||
DevPanel m_dev_panel;
|
||||
Renderer m_renderer;
|
||||
|
||||
Window m_window;
|
||||
|
||||
SceneManager m_scene_manager;
|
||||
|
||||
inline static double last_time = glfwGetTime();
|
||||
inline static double current_time = glfwGetTime();
|
||||
inline static double dt = 0.0f;
|
||||
@@ -86,6 +76,8 @@ private:
|
||||
void render();
|
||||
void run();
|
||||
void update();
|
||||
|
||||
void dispatch_event(const Event& e);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
11
include/Cubed/argument.hpp
Normal file
11
include/Cubed/argument.hpp
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
struct Argument {
|
||||
bool is_client = false;
|
||||
int port = 25530;
|
||||
std::string ip{"127.0.0.1"};
|
||||
std::string player{"Unknown"};
|
||||
bool debug_on = true;
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/input/event.hpp"
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
@@ -28,6 +29,9 @@ private:
|
||||
glm::vec3 camera_collision(glm::vec3 start, glm::vec3 end,
|
||||
float radius = 0.2f);
|
||||
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
bool handle_mouse_move_event(const MouseMoveEvent& e);
|
||||
|
||||
public:
|
||||
Camera();
|
||||
|
||||
@@ -45,6 +49,7 @@ public:
|
||||
glm::vec3 get_camera_front() const;
|
||||
void change_perspective();
|
||||
bool is_first_person() const;
|
||||
bool handle_event(const Event& e);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
class App;
|
||||
class WorldScene;
|
||||
class ClientPlayer;
|
||||
class App;
|
||||
class DevPanel {
|
||||
struct ConfigView {
|
||||
float fov = 70.0f;
|
||||
@@ -32,12 +33,13 @@ class DevPanel {
|
||||
};
|
||||
|
||||
public:
|
||||
DevPanel(App& app);
|
||||
DevPanel(WorldScene& app);
|
||||
void init();
|
||||
void render();
|
||||
|
||||
private:
|
||||
App& m_app;
|
||||
WorldScene& m_world_scene;
|
||||
Config& m_config;
|
||||
ConfigView m_config_view;
|
||||
ClientPlayer* m_player;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/player.hpp"
|
||||
#include "Cubed/input.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
|
||||
#include <absl/container/flat_hash_set.h>
|
||||
#include <glm/glm.hpp>
|
||||
@@ -23,6 +24,14 @@ public:
|
||||
ClientPlayer(ClientWorld& world);
|
||||
~ClientPlayer();
|
||||
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
|
||||
void update_front_vec(float offset_x, float offset_y);
|
||||
bool update_player_move_state(Key key, KeyAction action);
|
||||
bool update_scroll(float yoffset);
|
||||
|
||||
void update_chunk_set(const ChunkPosSet& set);
|
||||
const ChunkPosSet& get_chunk_pos_set() const;
|
||||
ChunkPosSet get_chunk_pos_set();
|
||||
@@ -40,9 +49,6 @@ public:
|
||||
void set_player_pos(const glm::vec3& pos);
|
||||
void set_place_block(unsigned id);
|
||||
void update(float delta_time);
|
||||
void update_front_vec(float offset_x, float offset_y);
|
||||
void update_player_move_state(int key, int action);
|
||||
void update_scroll(double yoffset);
|
||||
|
||||
float& max_walk_speed();
|
||||
float& max_run_speed();
|
||||
@@ -137,11 +143,17 @@ private:
|
||||
|
||||
void update_direction();
|
||||
void update_lookup_block();
|
||||
|
||||
bool place_block(MouseKey key);
|
||||
|
||||
void update_move(float delta_time);
|
||||
|
||||
void update_x_move(glm::vec3& player_pos);
|
||||
void update_y_move(glm::vec3& player_pos);
|
||||
void update_z_move(glm::vec3& player_pos);
|
||||
|
||||
void update_player_chunk();
|
||||
|
||||
void play_walk_sound(float dt);
|
||||
Gait compute_gait() const;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/game_time.hpp"
|
||||
#include "Cubed/gameplay/network_client.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/tools/cubed_random.hpp"
|
||||
#include "Cubed/tools/priority_thread_pool.hpp"
|
||||
|
||||
@@ -41,14 +42,15 @@ struct PlayerRenderData {
|
||||
Gait gait;
|
||||
float angle;
|
||||
};
|
||||
|
||||
class WorldScene;
|
||||
class ClientWorld {
|
||||
public:
|
||||
ClientWorld(AudioEngine& auido, Config& config);
|
||||
ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene);
|
||||
~ClientWorld();
|
||||
void init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client);
|
||||
void update(float delta_time);
|
||||
bool handle_event(const Event& e);
|
||||
const std::optional<LookBlock>& get_look_block_pos() const;
|
||||
ClientPlayer& get_player();
|
||||
const ClientPlayer& get_player() const;
|
||||
@@ -97,6 +99,7 @@ public:
|
||||
static AABB get_block_aabb(const glm::ivec3& pos);
|
||||
AudioEngine& get_audio();
|
||||
Config& get_config();
|
||||
WorldScene& world_scene();
|
||||
template <typename Fn>
|
||||
void register_ticktimer(std::string_view id, TickType threshold, Fn&& f) {
|
||||
m_ticktimers.emplace(
|
||||
@@ -133,6 +136,7 @@ private:
|
||||
ChunkHashMap m_chunks;
|
||||
AudioEngine& m_audio;
|
||||
Config& m_config;
|
||||
WorldScene& m_world_scene;
|
||||
std::vector<glm::vec4> m_planes;
|
||||
std::jthread m_client_thread;
|
||||
|
||||
|
||||
61
include/Cubed/input/event.hpp
Normal file
61
include/Cubed/input/event.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/input/key.hpp"
|
||||
#include "Cubed/input/mouse.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
struct MouseMoveEvent {
|
||||
float xpos;
|
||||
float ypos;
|
||||
|
||||
MouseMoveEvent(float x, float y) : xpos(x), ypos(y) {}
|
||||
};
|
||||
|
||||
struct MouseButtonEvent {
|
||||
MouseKey key;
|
||||
KeyAction action;
|
||||
|
||||
MouseButtonEvent(MouseKey k, KeyAction a) : key(k), action(a) {}
|
||||
};
|
||||
|
||||
struct MouseWheelEvent {
|
||||
float offset;
|
||||
|
||||
MouseWheelEvent(float o) : offset(o) {}
|
||||
};
|
||||
|
||||
struct KeyEvent {
|
||||
Key key;
|
||||
KeyAction action;
|
||||
|
||||
KeyEvent(Key k, KeyAction a) : key(k), action(a) {}
|
||||
};
|
||||
|
||||
struct TextInputEvent {
|
||||
std::string text;
|
||||
|
||||
TextInputEvent(std::string t) : text(std::move(t)) {}
|
||||
};
|
||||
|
||||
struct WindowResizeEvent {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
struct FrameBufferResizeEvent {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
using Event =
|
||||
std::variant<MouseMoveEvent, MouseButtonEvent, MouseWheelEvent, KeyEvent,
|
||||
TextInputEvent, WindowResizeEvent, FrameBufferResizeEvent>;
|
||||
|
||||
template <class... T> struct Overloaded : T... {
|
||||
using T::operator()...;
|
||||
};
|
||||
template <class... T> Overloaded(T...) -> Overloaded<T...>;
|
||||
|
||||
} // namespace Cubed
|
||||
127
include/Cubed/input/key.hpp
Normal file
127
include/Cubed/input/key.hpp
Normal file
@@ -0,0 +1,127 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
enum class Key {
|
||||
// Letter keys
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
E,
|
||||
F,
|
||||
G,
|
||||
H,
|
||||
I,
|
||||
J,
|
||||
K,
|
||||
L,
|
||||
M,
|
||||
N,
|
||||
O,
|
||||
P,
|
||||
Q,
|
||||
R,
|
||||
S,
|
||||
T,
|
||||
U,
|
||||
V,
|
||||
W,
|
||||
X,
|
||||
Y,
|
||||
Z,
|
||||
|
||||
// Digit keys (main keyboard area)
|
||||
DIGIT_0,
|
||||
DIGIT_1,
|
||||
DIGIT_2,
|
||||
DIGIT_3,
|
||||
DIGIT_4,
|
||||
DIGIT_5,
|
||||
DIGIT_6,
|
||||
DIGIT_7,
|
||||
DIGIT_8,
|
||||
DIGIT_9,
|
||||
|
||||
// Function keys
|
||||
F1,
|
||||
F2,
|
||||
F3,
|
||||
F4,
|
||||
F5,
|
||||
F6,
|
||||
F7,
|
||||
F8,
|
||||
F9,
|
||||
F10,
|
||||
F11,
|
||||
F12,
|
||||
|
||||
// Control keys
|
||||
BACKSPACE,
|
||||
TAB,
|
||||
ENTER,
|
||||
ESCAPE,
|
||||
SPACE,
|
||||
CAPS_LOCK,
|
||||
NUM_LOCK,
|
||||
SCROLL_LOCK,
|
||||
|
||||
// Modifier keys
|
||||
LEFT_SHIFT,
|
||||
RIGHT_SHIFT,
|
||||
LEFT_CTRL,
|
||||
RIGHT_CTRL,
|
||||
LEFT_ALT,
|
||||
RIGHT_ALT,
|
||||
LEFT_SUPER,
|
||||
RIGHT_SUPER, // Windows / Command 键
|
||||
|
||||
// Navigation keys
|
||||
INSERT,
|
||||
DELETE,
|
||||
HOME,
|
||||
END,
|
||||
PAGE_UP,
|
||||
PAGE_DOWN,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
UP,
|
||||
DOWN,
|
||||
|
||||
// Lock and system keys
|
||||
PRINT_SCREEN,
|
||||
PAUSE,
|
||||
|
||||
// Main keyboard area symbol keys
|
||||
GRAVE_ACCENT, // `
|
||||
MINUS, // -
|
||||
EQUALS, // =
|
||||
LEFT_BRACKET, // [
|
||||
RIGHT_BRACKET, // ]
|
||||
BACKSLASH, // \ /
|
||||
SEMICOLON, // ;
|
||||
APOSTROPHE, // '
|
||||
COMMA, // ,
|
||||
PERIOD, // .
|
||||
SLASH, // /
|
||||
|
||||
// Numpad area
|
||||
NUMPAD_0,
|
||||
NUMPAD_1,
|
||||
NUMPAD_2,
|
||||
NUMPAD_3,
|
||||
NUMPAD_4,
|
||||
NUMPAD_5,
|
||||
NUMPAD_6,
|
||||
NUMPAD_7,
|
||||
NUMPAD_8,
|
||||
NUMPAD_9,
|
||||
NUMPAD_ADD, // +
|
||||
NUMPAD_SUBTRACT, // -
|
||||
NUMPAD_MULTIPLY, // *
|
||||
NUMPAD_DIVIDE, // /
|
||||
NUMPAD_DECIMAL, // .
|
||||
NUMPAD_ENTER
|
||||
};
|
||||
enum class KeyAction { PRESS, RELEASE, REPEAT };
|
||||
} // namespace Cubed
|
||||
25
include/Cubed/input/mouse.hpp
Normal file
25
include/Cubed/input/mouse.hpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
enum class MouseKey {
|
||||
LEFT_BUTTON,
|
||||
RIGHT_BUTTON,
|
||||
MIDDLE_BUTTON,
|
||||
|
||||
BACK_BUTTON, // Side button back
|
||||
FORWARD_BUTTON, // Side button forward
|
||||
|
||||
WHEEL_UP,
|
||||
WHEEL_DOWN,
|
||||
WHEEL_LEFT,
|
||||
WHEEL_RIGHT,
|
||||
|
||||
EXTRA_BUTTON_1, // Additional programmable buttons
|
||||
EXTRA_BUTTON_2,
|
||||
EXTRA_BUTTON_3,
|
||||
EXTRA_BUTTON_4,
|
||||
EXTRA_BUTTON_5
|
||||
};
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <glad/glad.h>
|
||||
|
||||
namespace Cubed {
|
||||
class ClientWorld;
|
||||
class Renderer;
|
||||
class PlayerRenderer {
|
||||
public:
|
||||
@@ -12,8 +13,9 @@ public:
|
||||
PlayerRenderer(Renderer& renderer);
|
||||
~PlayerRenderer();
|
||||
void init();
|
||||
void render(const Shader& shader);
|
||||
void shadow_render(const Shader& shader, glm::mat4& light_matrix);
|
||||
void render(const Shader& shader, ClientWorld& world);
|
||||
void shadow_render(const Shader& shader, glm::mat4& light_matrix,
|
||||
ClientWorld& world);
|
||||
|
||||
private:
|
||||
struct PlayerVertex {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/constants.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
#include "Cubed/render/player_renderer.hpp"
|
||||
#include "Cubed/render/shader_manager.hpp"
|
||||
@@ -15,8 +16,6 @@
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
|
||||
class Camera;
|
||||
class TextureManager;
|
||||
class ClientWorld;
|
||||
class DevPanel;
|
||||
@@ -24,22 +23,23 @@ class Renderer {
|
||||
public:
|
||||
constexpr static int NUM_VAO = 7;
|
||||
|
||||
Renderer(const Camera& camera, ClientWorld& world,
|
||||
const TextureManager& texture_manager, DevPanel& dev_panel,
|
||||
Config& config);
|
||||
Renderer(TextureManager& texture_manager, Config& config);
|
||||
~Renderer();
|
||||
void hot_reload();
|
||||
void init(bool debug_on);
|
||||
const Shader& get_shader(const std::string& name) const;
|
||||
void render();
|
||||
|
||||
void begin_frame();
|
||||
void end_frame();
|
||||
void render_world(ClientWorld& world);
|
||||
void render_lable(const Label& label);
|
||||
void render_image(const Image& image);
|
||||
|
||||
void begin_render_ui();
|
||||
void end_render_ui();
|
||||
|
||||
void update(float delta_time);
|
||||
void update_fov(float fov);
|
||||
void update_proj_matrix(float aspect, float width, float height);
|
||||
void updata_framebuffer(int width, int height);
|
||||
|
||||
float& ambient_strength();
|
||||
|
||||
bool& discard_transparent();
|
||||
@@ -63,24 +63,23 @@ public:
|
||||
float& underwater_fog_density();
|
||||
float& water_density();
|
||||
|
||||
const Camera& camera() const;
|
||||
const ClientWorld& world() const;
|
||||
ClientWorld& world();
|
||||
const glm::mat4& world_proj_matrix() const;
|
||||
const TextureManager& texture_mamger() const;
|
||||
float delta_time() const;
|
||||
|
||||
float height() const;
|
||||
float width() const;
|
||||
float window_height() const;
|
||||
float window_width() const;
|
||||
float frame_height() const;
|
||||
float frame_width() const;
|
||||
const glm::mat4& p_mat() const;
|
||||
|
||||
const std::vector<VertexArray>& vao() const;
|
||||
void render_dev_panel(DevPanel& dev_panel);
|
||||
|
||||
bool handle_event(const Event& e);
|
||||
|
||||
private:
|
||||
const Camera& m_camera;
|
||||
DevPanel& m_dev_panel;
|
||||
const TextureManager& m_texture_manager;
|
||||
ClientWorld& m_world;
|
||||
TextureManager& m_texture_manager;
|
||||
|
||||
bool m_init = false;
|
||||
|
||||
@@ -89,8 +88,11 @@ private:
|
||||
|
||||
float m_delta_time = 0.0f;
|
||||
|
||||
float m_width = 0.0f;
|
||||
float m_height = 0.0f;
|
||||
float m_frame_width = 0.0f;
|
||||
float m_frame_height = 0.0f;
|
||||
|
||||
float m_window_width = 0.0f;
|
||||
float m_window_height = 0.0f;
|
||||
|
||||
glm::mat4 m_world_proj_matrix;
|
||||
|
||||
@@ -101,8 +103,6 @@ private:
|
||||
std::unique_ptr<VertexBuffer> m_player_vbo;
|
||||
std::unique_ptr<VertexBuffer> m_quad_vbo;
|
||||
|
||||
std::unique_ptr<Image> m_crosshair_image;
|
||||
|
||||
glm::mat4 m_ui_proj_matrix;
|
||||
ShaderManager m_shaders;
|
||||
|
||||
@@ -118,16 +118,12 @@ private:
|
||||
|
||||
WorldRenderer m_world_renderer;
|
||||
Config& m_config;
|
||||
|
||||
bool handle_window_resize_event(const WindowResizeEvent& e);
|
||||
bool handle_frame_buffer_resize_event(const FrameBufferResizeEvent& e);
|
||||
void updata_framebuffer(int width, int height);
|
||||
void init_quad();
|
||||
void init_text();
|
||||
|
||||
void day_night_calculation();
|
||||
|
||||
void render_sky();
|
||||
|
||||
void render_ui();
|
||||
void render_crosshair();
|
||||
void render_dev_panel();
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -35,6 +35,7 @@ enum TextureFormat : GLenum {
|
||||
RGBA16F = GL_RGBA16F,
|
||||
RED = GL_RED,
|
||||
RGBA = GL_RGBA,
|
||||
R8 = GL_R8,
|
||||
RGB = GL_RGB,
|
||||
RGBA8 = GL_RGBA8,
|
||||
|
||||
@@ -60,12 +61,12 @@ public:
|
||||
|
||||
void tex_image_2d(TextureFormat internalformat, TextureFormat format,
|
||||
GLenum type, const void* data, GLsizei width,
|
||||
GLsizei height, GLint level = 0, GLint border = 0) const;
|
||||
GLsizei height, GLint level = 0, GLint border = 0);
|
||||
|
||||
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;
|
||||
GLint border = 0);
|
||||
|
||||
void tex_sub_image_3d(TextureFormat format, GLenum type, const void* data,
|
||||
GLint xoffset, GLint yoffset, GLint zoffset,
|
||||
@@ -84,9 +85,13 @@ public:
|
||||
void set_clamp_to_edge(bool r = true, bool s = true, bool t = true) const;
|
||||
|
||||
TextureType type() const;
|
||||
float width() const;
|
||||
float height() const;
|
||||
|
||||
private:
|
||||
GLuint m_id = 0;
|
||||
float m_width = 0;
|
||||
float m_height = 0;
|
||||
const TextureType M_TYPE;
|
||||
GLenum get_gl_texture_type() const;
|
||||
};
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
WorldRenderer& operator=(const WorldRenderer&) = delete;
|
||||
WorldRenderer& operator=(WorldRenderer&&) = delete;
|
||||
void init();
|
||||
void render();
|
||||
void render(ClientWorld& world);
|
||||
void updata_framebuffer(int width, int height);
|
||||
|
||||
float& ambient_strength();
|
||||
@@ -121,27 +121,26 @@ private:
|
||||
|
||||
glm::mat4 view_matrix;
|
||||
|
||||
ClientWorld& m_world;
|
||||
const Camera& m_camera;
|
||||
const TextureManager& m_texture_manager;
|
||||
void day_night_calculation();
|
||||
void day_night_calculation(ClientWorld& world);
|
||||
|
||||
void render_sky();
|
||||
void render_sky(ClientWorld& world);
|
||||
|
||||
void render_world();
|
||||
void render_world(ClientWorld& world);
|
||||
|
||||
void shadow_map_generate();
|
||||
void shadow_map_generate(ClientWorld& world);
|
||||
|
||||
void render_underwater();
|
||||
void render_outline();
|
||||
void render_player();
|
||||
void render_underwater(ClientWorld& world);
|
||||
void render_outline(ClientWorld& world);
|
||||
void render_player(ClientWorld& world);
|
||||
|
||||
void render_normal_block(const glm::mat4& model_mat,
|
||||
const glm::mat4& mv_mat,
|
||||
const glm::mat4& norm_mat);
|
||||
const glm::mat4& mv_mat, const glm::mat4& norm_mat,
|
||||
ClientWorld& world);
|
||||
|
||||
void render_transparent_block(const glm::mat4& mv_mat,
|
||||
const glm::mat4& norm_mat);
|
||||
const glm::mat4& norm_mat,
|
||||
ClientWorld& world);
|
||||
|
||||
glm::vec3 quantize_sun_direction(const glm::vec3& sundir,
|
||||
float angle_step_deg) const;
|
||||
|
||||
@@ -1,11 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/input/event.hpp"
|
||||
namespace Cubed {
|
||||
class Renderer;
|
||||
|
||||
enum class SceneType { MAIN_MENU, WORLD };
|
||||
|
||||
class Scene {
|
||||
public:
|
||||
Scene() = default;
|
||||
|
||||
Scene(const Scene&) = delete;
|
||||
Scene(Scene&&) = delete;
|
||||
Scene& operator=(const Scene&) = delete;
|
||||
Scene& operator=(Scene&&) = delete;
|
||||
|
||||
virtual ~Scene() = default;
|
||||
virtual void update(float dt) = 0;
|
||||
virtual void render() = 0;
|
||||
virtual void render(Renderer& renderer) = 0;
|
||||
virtual bool handle_event(const Event& e) = 0;
|
||||
virtual void on_enter() {};
|
||||
virtual void on_leave() {};
|
||||
};
|
||||
} // namespace Cubed
|
||||
47
include/Cubed/scene/scene_manager.hpp
Normal file
47
include/Cubed/scene/scene_manager.hpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
#include "Cubed/scene/scene.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
class App;
|
||||
class SceneManager {
|
||||
public:
|
||||
SceneManager(const SceneManager&) = delete;
|
||||
SceneManager(SceneManager&&) = delete;
|
||||
SceneManager& operator=(const SceneManager&) = delete;
|
||||
SceneManager& operator=(SceneManager&&) = delete;
|
||||
SceneManager(App& app);
|
||||
~SceneManager();
|
||||
|
||||
void update(float dt);
|
||||
void render(Renderer& renderer);
|
||||
|
||||
bool handle_event(const Event& e);
|
||||
|
||||
void request_change(SceneType type);
|
||||
void request_push(SceneType type);
|
||||
void request_pop();
|
||||
|
||||
App& app();
|
||||
|
||||
private:
|
||||
enum class OperationType { PUSH, POP, CHANGE };
|
||||
struct SceneOperation {
|
||||
OperationType type;
|
||||
std::optional<SceneType> scene;
|
||||
};
|
||||
|
||||
App& m_app;
|
||||
std::vector<std::unique_ptr<Scene>> m_pending_delete_scene;
|
||||
std::optional<SceneOperation> m_operation;
|
||||
std::stack<std::unique_ptr<Scene>> m_scenes;
|
||||
void process_operation();
|
||||
void change(SceneType type);
|
||||
void push(SceneType type);
|
||||
void pop();
|
||||
|
||||
std::unique_ptr<Scene> create_scene(SceneType);
|
||||
};
|
||||
} // namespace Cubed
|
||||
39
include/Cubed/scene/world_scene.hpp
Normal file
39
include/Cubed/scene/world_scene.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "Cubed/argument.hpp"
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/dev_panel.hpp"
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/scene/scene.hpp"
|
||||
#include "Cubed/ui/world_ui_manager.hpp"
|
||||
namespace Cubed {
|
||||
class SceneManager;
|
||||
class WorldScene : public Scene {
|
||||
public:
|
||||
WorldScene(const WorldScene&) = delete;
|
||||
WorldScene(WorldScene&&) = delete;
|
||||
WorldScene& operator=(const WorldScene&) = delete;
|
||||
WorldScene& operator=(WorldScene&&) = delete;
|
||||
|
||||
WorldScene(SceneManager& scene_manager);
|
||||
~WorldScene();
|
||||
|
||||
void update(float dt) override;
|
||||
void render(Renderer& renderer) override;
|
||||
bool handle_event(const Event& e) override;
|
||||
void on_enter() override;
|
||||
void on_leave() override;
|
||||
|
||||
Camera& camera();
|
||||
SceneManager& scene_manager();
|
||||
ClientWorld& client_world();
|
||||
|
||||
private:
|
||||
SceneManager& m_scene_manager;
|
||||
DevPanel m_dev_panel;
|
||||
Camera m_camera;
|
||||
std::shared_ptr<NetworkClient> m_client;
|
||||
ClientWorld m_client_world;
|
||||
WorldUIManager m_ui_manager;
|
||||
const Argument& m_argument;
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/gameplay/block.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/render/texture.hpp"
|
||||
|
||||
#include <glad/glad.h>
|
||||
@@ -15,10 +16,10 @@ private:
|
||||
std::unique_ptr<Texture> m_block_status_array;
|
||||
std::unique_ptr<Texture> m_texture_array;
|
||||
std::unique_ptr<Texture> m_cross_plane_array;
|
||||
std::unique_ptr<Texture> m_ui_array;
|
||||
std::unique_ptr<Texture> m_normal_texture_array;
|
||||
std::unique_ptr<Texture> m_skin;
|
||||
std::vector<std::unique_ptr<Texture>> m_item_textures;
|
||||
std::unordered_map<std::string, std::unique_ptr<Texture>> m_ui_map;
|
||||
GLfloat m_max_aniso = 0.0f;
|
||||
Config& m_config;
|
||||
int m_aniso = 1;
|
||||
@@ -27,7 +28,7 @@ private:
|
||||
void load_block_texture(unsigned block_id);
|
||||
void load_block_item_texture(unsigned id);
|
||||
void load_cross_plane_texture(unsigned id);
|
||||
void load_ui_texture(unsigned id);
|
||||
const Texture* load_image_texture(const std::string& path);
|
||||
void load_pbr_texture(unsigned id);
|
||||
void init_item();
|
||||
void init_block();
|
||||
@@ -35,6 +36,7 @@ private:
|
||||
void init_block_status();
|
||||
void init_skin();
|
||||
void hot_reload();
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
|
||||
public:
|
||||
TextureManager(Config& config);
|
||||
@@ -44,7 +46,7 @@ public:
|
||||
const Texture* get_block_status_array() const;
|
||||
const Texture* get_texture_array() const;
|
||||
const Texture* get_cross_plane_array() const;
|
||||
const Texture* get_ui_array() const;
|
||||
const Texture* get_image_texture(const std::string& path);
|
||||
const Texture* get_pbr_texture() const;
|
||||
const std::vector<std::unique_ptr<Texture>>& item_textures() const;
|
||||
const Texture* get_skin() const;
|
||||
@@ -54,6 +56,7 @@ public:
|
||||
void need_reload();
|
||||
void update();
|
||||
int max_aniso() const;
|
||||
bool handle_event(const Event& e);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
19
include/Cubed/ui/button.hpp
Normal file
19
include/Cubed/ui/button.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/ui/widget.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Cubed {
|
||||
class Button : public Widget {
|
||||
public:
|
||||
Button();
|
||||
|
||||
template <typename F> Button& set_clicked(F&& f) {
|
||||
m_clicked = std::move(f);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_clicked;
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -4,24 +4,21 @@
|
||||
#include "Cubed/ui/widget.hpp"
|
||||
#include "glm/ext/vector_float2.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace Cubed {
|
||||
class TextureManager;
|
||||
class Image : public Widget {
|
||||
public:
|
||||
Image();
|
||||
void update(float dt) override;
|
||||
void render(Renderer& renderer) override;
|
||||
|
||||
Image& set_image(std::filesystem::path path);
|
||||
Image& set_image(const std::string& path, TextureManager& texture_manager);
|
||||
float width() const;
|
||||
float height() const;
|
||||
const Texture& texture() const;
|
||||
const Texture* texture() const;
|
||||
|
||||
private:
|
||||
Texture m_texture;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
const Texture* m_texture = nullptr;
|
||||
glm::vec2 m_pos{0.0f, 0.0f};
|
||||
float m_scale = 1.0f;
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ public:
|
||||
virtual Widget& set_scale(float scale);
|
||||
virtual const glm::vec2& pos() const;
|
||||
virtual float scale() const;
|
||||
|
||||
template <typename T, typename... Args> T& add_child(Args&&... args) {
|
||||
auto widget = std::make_unique<T>(std::forward<Args>(args)...);
|
||||
T& ref = *widget;
|
||||
|
||||
34
include/Cubed/ui/world_ui_manager.hpp
Normal file
34
include/Cubed/ui/world_ui_manager.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/input/event.hpp"
|
||||
#include "Cubed/ui/widget.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
namespace Cubed {
|
||||
class WorldScene;
|
||||
class WorldUIManager {
|
||||
public:
|
||||
WorldUIManager(const WorldUIManager&) = delete;
|
||||
WorldUIManager(WorldUIManager&&) = delete;
|
||||
WorldUIManager& operator=(const WorldUIManager&) = delete;
|
||||
WorldUIManager& operator=(WorldUIManager&&) = delete;
|
||||
|
||||
WorldUIManager(WorldScene& scene);
|
||||
~WorldUIManager();
|
||||
|
||||
void init();
|
||||
void update(float dt);
|
||||
void render(Renderer& renderer);
|
||||
bool handle_event(const Event& e);
|
||||
|
||||
private:
|
||||
WorldScene& m_scene;
|
||||
std::unordered_map<std::string, std::unique_ptr<Widget>> m_widgets;
|
||||
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
bool handle_window_resize_event(const WindowResizeEvent& e);
|
||||
bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/input/event.hpp"
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
namespace Cubed {
|
||||
|
||||
class Camera;
|
||||
class Renderer;
|
||||
class Window {
|
||||
public:
|
||||
Window(Renderer& renderer, Config& config);
|
||||
Window(Config& config);
|
||||
~Window();
|
||||
|
||||
bool is_mouse_enable() const;
|
||||
@@ -17,22 +18,29 @@ public:
|
||||
GLFWwindow* get_glfw_window();
|
||||
void init();
|
||||
void imgui_init();
|
||||
void update_viewport();
|
||||
|
||||
// end of frame to reload!
|
||||
bool handle_event(const Event& e);
|
||||
|
||||
void hot_reload();
|
||||
|
||||
void toggle_fullscreen();
|
||||
void toggle_mouse_able();
|
||||
|
||||
void set_camera(Camera* camera);
|
||||
Camera* camera();
|
||||
|
||||
private:
|
||||
bool m_mouse_enable = false;
|
||||
bool m_imgui_init = false;
|
||||
float m_aspect;
|
||||
GLFWwindow* m_window;
|
||||
int m_width;
|
||||
int m_height;
|
||||
Renderer& m_renderer;
|
||||
int m_window_width;
|
||||
int m_window_height;
|
||||
Config& m_config;
|
||||
Camera* m_camera = nullptr;
|
||||
bool handle_key_event(const KeyEvent& e);
|
||||
bool handle_window_resize_event(const WindowResizeEvent& e);
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e);
|
||||
};
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -62,4 +62,8 @@ target_sources(${PROJECT_NAME}
|
||||
ui/label.cpp
|
||||
ui/ui_vertex_data.cpp
|
||||
ui/image.cpp
|
||||
ui/button.cpp
|
||||
scene/world_scene.cpp
|
||||
scene/scene_manager.cpp
|
||||
ui/world_ui_manager.cpp
|
||||
)
|
||||
541
src/app.cpp
541
src/app.cpp
@@ -1,5 +1,6 @@
|
||||
#include "Cubed/app.hpp"
|
||||
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/debug_collector.hpp"
|
||||
#include "Cubed/tools/arg_parser.hpp"
|
||||
@@ -16,16 +17,10 @@ App::App()
|
||||
|
||||
: m_game_config(ASSETS_PATH "config.toml"),
|
||||
m_texture_manager(m_game_config), m_audio(m_game_config),
|
||||
m_client_world(m_audio, m_game_config), m_dev_panel(*this),
|
||||
m_renderer(m_camera, m_client_world, m_texture_manager, m_dev_panel,
|
||||
m_game_config),
|
||||
m_window(m_renderer, m_game_config) {}
|
||||
m_renderer(m_texture_manager, m_game_config), m_window(m_game_config),
|
||||
m_scene_manager(*this) {}
|
||||
|
||||
App::~App() {
|
||||
if (m_client) {
|
||||
m_client->stop();
|
||||
}
|
||||
}
|
||||
App::~App() {}
|
||||
void App::cursor_position_callback(GLFWwindow* window, double xpos,
|
||||
double ypos) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -38,7 +33,8 @@ void App::cursor_position_callback(GLFWwindow* window, double xpos,
|
||||
return;
|
||||
}
|
||||
if (!app->m_window.is_mouse_enable()) {
|
||||
app->m_camera.update_cursor_position_camera(xpos, ypos);
|
||||
app->m_scene_manager.handle_event(
|
||||
MouseMoveEvent{static_cast<float>(xpos), static_cast<float>(ypos)});
|
||||
}
|
||||
}
|
||||
void App::init(int argc, char** argv) {
|
||||
@@ -60,6 +56,8 @@ void App::init(int argc, char** argv) {
|
||||
window_focus_callback);
|
||||
glfwSetWindowSizeCallback(m_window.get_glfw_window(),
|
||||
window_reshape_callback);
|
||||
glfwSetFramebufferSizeCallback(m_window.get_glfw_window(),
|
||||
framebuffer_size_callback);
|
||||
glfwSetKeyCallback(m_window.get_glfw_window(), key_callback);
|
||||
glfwSetScrollCallback(m_window.get_glfw_window(), mouse_scroll_callback);
|
||||
glfwSetCursorEnterCallback(m_window.get_glfw_window(),
|
||||
@@ -72,7 +70,6 @@ void App::init(int argc, char** argv) {
|
||||
BlockManager::init();
|
||||
m_renderer.init(m_argument.debug_on);
|
||||
Logger::info("Renderer Init Success");
|
||||
m_window.update_viewport();
|
||||
// MapTable::init_map();
|
||||
m_texture_manager.init_texture();
|
||||
Logger::info("Texture Load Success");
|
||||
@@ -80,16 +77,19 @@ void App::init(int argc, char** argv) {
|
||||
m_server.start_server(m_argument.port);
|
||||
}
|
||||
|
||||
m_client = std::make_shared<NetworkClient>(m_client_world);
|
||||
m_scene_manager.request_push(SceneType::WORLD);
|
||||
|
||||
m_client->start(m_argument.ip, m_argument.port);
|
||||
// init will send packet
|
||||
m_client_world.init(m_argument.player, m_client);
|
||||
{
|
||||
int w, h;
|
||||
glfwGetWindowSize(m_window.get_glfw_window(), &w, &h);
|
||||
window_reshape_callback(m_window.get_glfw_window(), w, h);
|
||||
}
|
||||
|
||||
Logger::info("World Init Success");
|
||||
|
||||
m_camera.camera_init(&m_client_world.get_player());
|
||||
m_dev_panel.init();
|
||||
{
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(m_window.get_glfw_window(), &w, &h);
|
||||
framebuffer_size_callback(m_window.get_glfw_window(), w, h);
|
||||
}
|
||||
}
|
||||
|
||||
void App::handle_argument(int argc, char** argv) {
|
||||
@@ -179,49 +179,357 @@ void App::key_callback(GLFWwindow* window, int key, int scancode, int action,
|
||||
// ImGui_ImplGlfw_CursorEnterCallback(window,
|
||||
// !app->m_window.is_mouse_enable());
|
||||
if (io.WantCaptureKeyboard && app->m_window.is_mouse_enable()) {
|
||||
if ((key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_ESCAPE) &&
|
||||
action == GLFW_PRESS) {
|
||||
app->m_window.toggle_mouse_able();
|
||||
app->m_camera.reset_camera();
|
||||
if ((key == GLFW_KEY_LEFT_ALT) && action == GLFW_PRESS) {
|
||||
app->dispatch_event(KeyEvent{Key::LEFT_ALT, KeyAction::PRESS});
|
||||
return;
|
||||
}
|
||||
ImGui_ImplGlfw_KeyCallback(window, key, scancode, action, mods);
|
||||
return;
|
||||
}
|
||||
Key pkey;
|
||||
KeyAction act;
|
||||
switch (key) {
|
||||
// Letter keys
|
||||
case GLFW_KEY_A:
|
||||
pkey = Key::A;
|
||||
break;
|
||||
case GLFW_KEY_B:
|
||||
pkey = Key::B;
|
||||
break;
|
||||
case GLFW_KEY_C:
|
||||
pkey = Key::C;
|
||||
break;
|
||||
case GLFW_KEY_D:
|
||||
pkey = Key::D;
|
||||
break;
|
||||
case GLFW_KEY_E:
|
||||
pkey = Key::E;
|
||||
break;
|
||||
case GLFW_KEY_F:
|
||||
pkey = Key::F;
|
||||
break;
|
||||
case GLFW_KEY_G:
|
||||
pkey = Key::G;
|
||||
break;
|
||||
case GLFW_KEY_H:
|
||||
pkey = Key::H;
|
||||
break;
|
||||
case GLFW_KEY_I:
|
||||
pkey = Key::I;
|
||||
break;
|
||||
case GLFW_KEY_J:
|
||||
pkey = Key::J;
|
||||
break;
|
||||
case GLFW_KEY_K:
|
||||
pkey = Key::K;
|
||||
break;
|
||||
case GLFW_KEY_L:
|
||||
pkey = Key::L;
|
||||
break;
|
||||
case GLFW_KEY_M:
|
||||
pkey = Key::M;
|
||||
break;
|
||||
case GLFW_KEY_N:
|
||||
pkey = Key::N;
|
||||
break;
|
||||
case GLFW_KEY_O:
|
||||
pkey = Key::O;
|
||||
break;
|
||||
case GLFW_KEY_P:
|
||||
pkey = Key::P;
|
||||
break;
|
||||
case GLFW_KEY_Q:
|
||||
if (action == GLFW_PRESS) {
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_ESCAPE:
|
||||
if (action == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, GLFW_TRUE);
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_F11:
|
||||
if (action == GLFW_PRESS) {
|
||||
app->m_window.toggle_fullscreen();
|
||||
}
|
||||
pkey = Key::Q;
|
||||
break;
|
||||
case GLFW_KEY_R:
|
||||
if (action == GLFW_PRESS) {
|
||||
app->m_texture_manager.need_reload();
|
||||
}
|
||||
pkey = Key::R;
|
||||
break;
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
if (action == GLFW_PRESS) {
|
||||
app->m_window.toggle_mouse_able();
|
||||
app->m_camera.reset_camera();
|
||||
}
|
||||
case GLFW_KEY_S:
|
||||
pkey = Key::S;
|
||||
break;
|
||||
case GLFW_KEY_T:
|
||||
pkey = Key::T;
|
||||
break;
|
||||
case GLFW_KEY_U:
|
||||
pkey = Key::U;
|
||||
break;
|
||||
case GLFW_KEY_V:
|
||||
pkey = Key::V;
|
||||
break;
|
||||
case GLFW_KEY_W:
|
||||
pkey = Key::W;
|
||||
break;
|
||||
case GLFW_KEY_X:
|
||||
pkey = Key::X;
|
||||
break;
|
||||
case GLFW_KEY_Y:
|
||||
pkey = Key::Y;
|
||||
break;
|
||||
case GLFW_KEY_Z:
|
||||
pkey = Key::Z;
|
||||
break;
|
||||
|
||||
// Digit keys (main keyboard area)
|
||||
case GLFW_KEY_0:
|
||||
pkey = Key::DIGIT_0;
|
||||
break;
|
||||
case GLFW_KEY_1:
|
||||
pkey = Key::DIGIT_1;
|
||||
break;
|
||||
case GLFW_KEY_2:
|
||||
pkey = Key::DIGIT_2;
|
||||
break;
|
||||
case GLFW_KEY_3:
|
||||
pkey = Key::DIGIT_3;
|
||||
break;
|
||||
case GLFW_KEY_4:
|
||||
pkey = Key::DIGIT_4;
|
||||
break;
|
||||
case GLFW_KEY_5:
|
||||
pkey = Key::DIGIT_5;
|
||||
break;
|
||||
case GLFW_KEY_6:
|
||||
pkey = Key::DIGIT_6;
|
||||
break;
|
||||
case GLFW_KEY_7:
|
||||
pkey = Key::DIGIT_7;
|
||||
break;
|
||||
case GLFW_KEY_8:
|
||||
pkey = Key::DIGIT_8;
|
||||
break;
|
||||
case GLFW_KEY_9:
|
||||
pkey = Key::DIGIT_9;
|
||||
break;
|
||||
|
||||
// Function keys
|
||||
case GLFW_KEY_F1:
|
||||
pkey = Key::F1;
|
||||
break;
|
||||
case GLFW_KEY_F2:
|
||||
pkey = Key::F2;
|
||||
break;
|
||||
case GLFW_KEY_F3:
|
||||
pkey = Key::F3;
|
||||
break;
|
||||
case GLFW_KEY_F4:
|
||||
pkey = Key::F4;
|
||||
break;
|
||||
case GLFW_KEY_F5:
|
||||
if (action == GLFW_PRESS) {
|
||||
app->m_camera.change_perspective();
|
||||
}
|
||||
pkey = Key::F5;
|
||||
break;
|
||||
case GLFW_KEY_F6:
|
||||
pkey = Key::F6;
|
||||
break;
|
||||
case GLFW_KEY_F7:
|
||||
pkey = Key::F7;
|
||||
break;
|
||||
case GLFW_KEY_F8:
|
||||
pkey = Key::F8;
|
||||
break;
|
||||
case GLFW_KEY_F9:
|
||||
pkey = Key::F9;
|
||||
break;
|
||||
case GLFW_KEY_F10:
|
||||
pkey = Key::F10;
|
||||
break;
|
||||
case GLFW_KEY_F11:
|
||||
pkey = Key::F11;
|
||||
break;
|
||||
case GLFW_KEY_F12:
|
||||
pkey = Key::F12;
|
||||
break;
|
||||
|
||||
// Control keys
|
||||
case GLFW_KEY_BACKSPACE:
|
||||
pkey = Key::BACKSPACE;
|
||||
break;
|
||||
case GLFW_KEY_TAB:
|
||||
pkey = Key::TAB;
|
||||
break;
|
||||
case GLFW_KEY_ENTER:
|
||||
pkey = Key::ENTER;
|
||||
break;
|
||||
case GLFW_KEY_ESCAPE:
|
||||
pkey = Key::ESCAPE;
|
||||
break;
|
||||
case GLFW_KEY_SPACE:
|
||||
pkey = Key::SPACE;
|
||||
break;
|
||||
case GLFW_KEY_CAPS_LOCK:
|
||||
pkey = Key::CAPS_LOCK;
|
||||
break;
|
||||
case GLFW_KEY_NUM_LOCK:
|
||||
pkey = Key::NUM_LOCK;
|
||||
break;
|
||||
case GLFW_KEY_SCROLL_LOCK:
|
||||
pkey = Key::SCROLL_LOCK;
|
||||
break;
|
||||
|
||||
// Modifier keys
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
pkey = Key::LEFT_SHIFT;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_SHIFT:
|
||||
pkey = Key::RIGHT_SHIFT;
|
||||
break;
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
pkey = Key::LEFT_CTRL;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_CONTROL:
|
||||
pkey = Key::RIGHT_CTRL;
|
||||
break;
|
||||
case GLFW_KEY_LEFT_ALT:
|
||||
pkey = Key::LEFT_ALT;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_ALT:
|
||||
pkey = Key::RIGHT_ALT;
|
||||
break;
|
||||
case GLFW_KEY_LEFT_SUPER:
|
||||
pkey = Key::LEFT_SUPER;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_SUPER:
|
||||
pkey = Key::RIGHT_SUPER;
|
||||
break;
|
||||
|
||||
// Navigation keys
|
||||
case GLFW_KEY_INSERT:
|
||||
pkey = Key::INSERT;
|
||||
break;
|
||||
case GLFW_KEY_DELETE:
|
||||
pkey = Key::DELETE;
|
||||
break;
|
||||
case GLFW_KEY_HOME:
|
||||
pkey = Key::HOME;
|
||||
break;
|
||||
case GLFW_KEY_END:
|
||||
pkey = Key::END;
|
||||
break;
|
||||
case GLFW_KEY_PAGE_UP:
|
||||
pkey = Key::PAGE_UP;
|
||||
break;
|
||||
case GLFW_KEY_PAGE_DOWN:
|
||||
pkey = Key::PAGE_DOWN;
|
||||
break;
|
||||
case GLFW_KEY_LEFT:
|
||||
pkey = Key::LEFT;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT:
|
||||
pkey = Key::RIGHT;
|
||||
break;
|
||||
case GLFW_KEY_UP:
|
||||
pkey = Key::UP;
|
||||
break;
|
||||
case GLFW_KEY_DOWN:
|
||||
pkey = Key::DOWN;
|
||||
break;
|
||||
|
||||
// Lock and system keys
|
||||
case GLFW_KEY_PRINT_SCREEN:
|
||||
pkey = Key::PRINT_SCREEN;
|
||||
break;
|
||||
case GLFW_KEY_PAUSE:
|
||||
pkey = Key::PAUSE;
|
||||
break;
|
||||
|
||||
// Main keyboard area symbol keys
|
||||
case GLFW_KEY_GRAVE_ACCENT:
|
||||
pkey = Key::GRAVE_ACCENT;
|
||||
break;
|
||||
case GLFW_KEY_MINUS:
|
||||
pkey = Key::MINUS;
|
||||
break;
|
||||
case GLFW_KEY_EQUAL:
|
||||
pkey = Key::EQUALS;
|
||||
break;
|
||||
case GLFW_KEY_LEFT_BRACKET:
|
||||
pkey = Key::LEFT_BRACKET;
|
||||
break;
|
||||
case GLFW_KEY_RIGHT_BRACKET:
|
||||
pkey = Key::RIGHT_BRACKET;
|
||||
break;
|
||||
case GLFW_KEY_BACKSLASH:
|
||||
pkey = Key::BACKSLASH;
|
||||
break;
|
||||
case GLFW_KEY_SEMICOLON:
|
||||
pkey = Key::SEMICOLON;
|
||||
break;
|
||||
case GLFW_KEY_APOSTROPHE:
|
||||
pkey = Key::APOSTROPHE;
|
||||
break;
|
||||
case GLFW_KEY_COMMA:
|
||||
pkey = Key::COMMA;
|
||||
break;
|
||||
case GLFW_KEY_PERIOD:
|
||||
pkey = Key::PERIOD;
|
||||
break;
|
||||
case GLFW_KEY_SLASH:
|
||||
pkey = Key::SLASH;
|
||||
break;
|
||||
|
||||
// Numpad area
|
||||
case GLFW_KEY_KP_0:
|
||||
pkey = Key::NUMPAD_0;
|
||||
break;
|
||||
case GLFW_KEY_KP_1:
|
||||
pkey = Key::NUMPAD_1;
|
||||
break;
|
||||
case GLFW_KEY_KP_2:
|
||||
pkey = Key::NUMPAD_2;
|
||||
break;
|
||||
case GLFW_KEY_KP_3:
|
||||
pkey = Key::NUMPAD_3;
|
||||
break;
|
||||
case GLFW_KEY_KP_4:
|
||||
pkey = Key::NUMPAD_4;
|
||||
break;
|
||||
case GLFW_KEY_KP_5:
|
||||
pkey = Key::NUMPAD_5;
|
||||
break;
|
||||
case GLFW_KEY_KP_6:
|
||||
pkey = Key::NUMPAD_6;
|
||||
break;
|
||||
case GLFW_KEY_KP_7:
|
||||
pkey = Key::NUMPAD_7;
|
||||
break;
|
||||
case GLFW_KEY_KP_8:
|
||||
pkey = Key::NUMPAD_8;
|
||||
break;
|
||||
case GLFW_KEY_KP_9:
|
||||
pkey = Key::NUMPAD_9;
|
||||
break;
|
||||
case GLFW_KEY_KP_ADD:
|
||||
pkey = Key::NUMPAD_ADD;
|
||||
break;
|
||||
case GLFW_KEY_KP_SUBTRACT:
|
||||
pkey = Key::NUMPAD_SUBTRACT;
|
||||
break;
|
||||
case GLFW_KEY_KP_MULTIPLY:
|
||||
pkey = Key::NUMPAD_MULTIPLY;
|
||||
break;
|
||||
case GLFW_KEY_KP_DIVIDE:
|
||||
pkey = Key::NUMPAD_DIVIDE;
|
||||
break;
|
||||
case GLFW_KEY_KP_DECIMAL:
|
||||
pkey = Key::NUMPAD_DECIMAL;
|
||||
break;
|
||||
case GLFW_KEY_KP_ENTER:
|
||||
pkey = Key::NUMPAD_ENTER;
|
||||
break;
|
||||
|
||||
default:
|
||||
Logger::error("Unknown Key {}", key);
|
||||
return;
|
||||
}
|
||||
|
||||
app->m_client_world.get_player().update_player_move_state(key, action);
|
||||
if (action == GLFW_PRESS) {
|
||||
act = KeyAction::PRESS;
|
||||
} else if (action == GLFW_RELEASE) {
|
||||
act = KeyAction::RELEASE;
|
||||
} else {
|
||||
act = KeyAction::REPEAT;
|
||||
}
|
||||
|
||||
app->dispatch_event(KeyEvent{pkey, act});
|
||||
}
|
||||
|
||||
void App::mouse_button_callback(GLFWwindow* window, int button, int action,
|
||||
@@ -233,30 +541,46 @@ void App::mouse_button_callback(GLFWwindow* window, int button, int action,
|
||||
ImGui_ImplGlfw_MouseButtonCallback(window, button, action, mods);
|
||||
return;
|
||||
}
|
||||
MouseKey key;
|
||||
KeyAction act;
|
||||
switch (button) {
|
||||
case GLFW_MOUSE_BUTTON_LEFT:
|
||||
if (action == GLFW_PRESS) {
|
||||
if (app->m_window.is_mouse_enable()) {
|
||||
app->m_window.toggle_mouse_able();
|
||||
app->m_camera.reset_camera();
|
||||
break;
|
||||
;
|
||||
}
|
||||
Input::get_input_state().mouse_state.left = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
Input::get_input_state().mouse_state.left = false;
|
||||
}
|
||||
key = MouseKey::LEFT_BUTTON;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_RIGHT:
|
||||
if (action == GLFW_PRESS) {
|
||||
Input::get_input_state().mouse_state.right = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
Input::get_input_state().mouse_state.right = false;
|
||||
}
|
||||
key = MouseKey::RIGHT_BUTTON;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_MIDDLE:
|
||||
key = MouseKey::MIDDLE_BUTTON;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_4:
|
||||
key = MouseKey::BACK_BUTTON;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_5:
|
||||
key = MouseKey::FORWARD_BUTTON;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_6:
|
||||
key = MouseKey::EXTRA_BUTTON_1;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_7:
|
||||
key = MouseKey::EXTRA_BUTTON_2;
|
||||
break;
|
||||
case GLFW_MOUSE_BUTTON_8:
|
||||
key = MouseKey::EXTRA_BUTTON_3;
|
||||
break;
|
||||
default:
|
||||
Logger::error("Unknown Mouse Button {}", button);
|
||||
return;
|
||||
}
|
||||
if (action == GLFW_PRESS) {
|
||||
act = KeyAction::PRESS;
|
||||
} else if (action == GLFW_RELEASE) {
|
||||
act = KeyAction::RELEASE;
|
||||
} else {
|
||||
act = KeyAction::REPEAT;
|
||||
}
|
||||
|
||||
app->dispatch_event(MouseButtonEvent{key, act});
|
||||
}
|
||||
|
||||
void App::window_focus_callback(GLFWwindow* window, int focused) {
|
||||
@@ -268,17 +592,29 @@ void App::window_focus_callback(GLFWwindow* window, int focused) {
|
||||
return;
|
||||
}
|
||||
if (focused) {
|
||||
app->m_camera.reset_camera();
|
||||
auto camera = app->m_window.camera();
|
||||
if (camera) {
|
||||
camera->reset_camera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void App::window_reshape_callback(GLFWwindow* window, int, int) {
|
||||
void App::window_reshape_callback(GLFWwindow* window, int width, int height) {
|
||||
|
||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||
ASSERT_MSG(app, "nullptr");
|
||||
app->m_window.update_viewport();
|
||||
}
|
||||
|
||||
app->dispatch_event(WindowResizeEvent{width, height});
|
||||
|
||||
Logger::info("Window Reshape W: {} H: {}", width, height);
|
||||
}
|
||||
void App::framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||
App* app = static_cast<App*>(glfwGetWindowUserPointer(window));
|
||||
ASSERT_MSG(app, "nullptr");
|
||||
app->dispatch_event(FrameBufferResizeEvent{width, height});
|
||||
|
||||
Logger::info("Frame Buffer Reshape W: {} H: {}", width, height);
|
||||
}
|
||||
void App::mouse_scroll_callback(GLFWwindow* window, double xoffset,
|
||||
double yoffset) {
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -289,8 +625,7 @@ void App::mouse_scroll_callback(GLFWwindow* window, double xoffset,
|
||||
ImGui_ImplGlfw_ScrollCallback(window, xoffset, yoffset);
|
||||
return;
|
||||
}
|
||||
auto& player = app->m_client_world.get_player();
|
||||
player.update_scroll(yoffset);
|
||||
app->dispatch_event(MouseWheelEvent(static_cast<float>(yoffset)));
|
||||
}
|
||||
|
||||
void App::cursor_enter_callback(GLFWwindow* window, int entered) {
|
||||
@@ -318,8 +653,9 @@ void App::render() {
|
||||
ImGui_ImplGlfw_Sleep(10);
|
||||
return;
|
||||
}
|
||||
m_renderer.render();
|
||||
|
||||
m_renderer.begin_frame();
|
||||
m_scene_manager.render(m_renderer);
|
||||
m_renderer.end_frame();
|
||||
glfwSwapBuffers(m_window.get_glfw_window());
|
||||
}
|
||||
|
||||
@@ -327,20 +663,28 @@ void App::run() {
|
||||
|
||||
last_time = glfwGetTime();
|
||||
while (!glfwWindowShouldClose(m_window.get_glfw_window())) {
|
||||
if (m_client_world.is_receive_exit()) {
|
||||
break;
|
||||
}
|
||||
// if (m_client_world.is_receive_exit()) {
|
||||
// break;
|
||||
// }
|
||||
update();
|
||||
render();
|
||||
}
|
||||
m_client_world.request_exit();
|
||||
|
||||
if (!m_argument.is_client) {
|
||||
m_server.server_world().stop();
|
||||
}
|
||||
}
|
||||
static Gait player_gait = Gait::WALK;
|
||||
// static Gait player_gait = Gait::WALK;
|
||||
void App::update() {
|
||||
glfwPollEvents();
|
||||
|
||||
int w, h;
|
||||
glfwGetFramebufferSize(m_window.get_glfw_window(), &w, &h);
|
||||
|
||||
if (w != m_renderer.frame_width() || h != m_renderer.frame_height()) {
|
||||
dispatch_event(FrameBufferResizeEvent{w, h});
|
||||
}
|
||||
|
||||
current_time = glfwGetTime();
|
||||
dt = current_time - last_time;
|
||||
last_time = current_time;
|
||||
@@ -359,24 +703,30 @@ void App::update() {
|
||||
std::format("RSS: {}mb", Tools::get_current_rss() / (1024 * 1024)));
|
||||
}
|
||||
m_texture_manager.update();
|
||||
m_client_world.update(dt);
|
||||
m_camera.update_move_camera();
|
||||
const auto& player = m_client_world.get_player();
|
||||
if (player_gait != player.get_gait()) {
|
||||
player_gait = player.get_gait();
|
||||
float fov = m_game_config.get("player.fov", 70.0f);
|
||||
if (player_gait == Gait::WALK) {
|
||||
m_renderer.update_fov(fov);
|
||||
}
|
||||
if (player_gait == Gait::RUN) {
|
||||
m_renderer.update_fov(fov + 5.0f);
|
||||
}
|
||||
}
|
||||
m_audio.update_listener(m_camera.get_camera_pos(),
|
||||
m_camera.get_camera_front(), glm::vec3(0, 1, 0));
|
||||
|
||||
m_audio.update();
|
||||
DebugCollector::get().get_widget().update(dt);
|
||||
m_renderer.update(dt);
|
||||
|
||||
m_scene_manager.update(dt);
|
||||
}
|
||||
|
||||
void App::dispatch_event(const Event& e) {
|
||||
if (m_window.handle_event(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_texture_manager.handle_event(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_renderer.handle_event(e)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_scene_manager.handle_event(e)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int App::start_cubed_application(int argc, char** argv) {
|
||||
@@ -402,14 +752,11 @@ float App::delta_time() { return dt; }
|
||||
|
||||
float App::get_fps() { return fps; }
|
||||
|
||||
Camera& App::camera() { return m_camera; }
|
||||
DevPanel& App::dev_panel() { return m_dev_panel; }
|
||||
Renderer& App::renderer() { return m_renderer; }
|
||||
TextureManager& App::texture_manager() { return m_texture_manager; }
|
||||
Window& App::window() { return m_window; }
|
||||
ClientWorld& App::client_world() { return m_client_world; }
|
||||
ServerWorld& App::server_world() { return m_server.server_world(); }
|
||||
Config& App::config() { return m_game_config; }
|
||||
const App::Argument& App::argument() const { return m_argument; }
|
||||
const Argument& App::argument() const { return m_argument; }
|
||||
AudioEngine& App::audio() { return m_audio; }
|
||||
} // namespace Cubed
|
||||
@@ -115,6 +115,32 @@ bool Camera::is_first_person() const {
|
||||
return m_perspective == Perspective::FIRST_PERSON;
|
||||
}
|
||||
|
||||
bool Camera::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[this](const MouseMoveEvent& e) {
|
||||
if (handle_mouse_move_event(e)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[](const MouseButtonEvent&) { return false; },
|
||||
[](const MouseWheelEvent&) { return false; },
|
||||
[this](const KeyEvent& e) {
|
||||
if (handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[](const WindowResizeEvent&) { return false; },
|
||||
[](const FrameBufferResizeEvent&) { return false; }
|
||||
|
||||
} // namespace Cubed
|
||||
,
|
||||
e);
|
||||
}
|
||||
|
||||
glm::vec3 Camera::camera_collision(glm::vec3 start, glm::vec3 end,
|
||||
float radius) {
|
||||
constexpr float STEP = 0.05f;
|
||||
@@ -136,4 +162,20 @@ glm::vec3 Camera::camera_collision(glm::vec3 start, glm::vec3 end,
|
||||
return end;
|
||||
}
|
||||
|
||||
bool Camera::handle_key_event(const KeyEvent& e) {
|
||||
if (e.key == Key::LEFT_ALT && e.action == KeyAction::PRESS) {
|
||||
reset_camera();
|
||||
return true;
|
||||
}
|
||||
if (e.key == Key::F5 && e.action == KeyAction::PRESS) {
|
||||
change_perspective();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool Camera::handle_mouse_move_event(const MouseMoveEvent& e) {
|
||||
update_cursor_position_camera(e.xpos, e.ypos);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "Cubed/gameplay/cave_path.hpp"
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/river.path.hpp"
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
#include "Cubed/tools/log.hpp"
|
||||
|
||||
#include <imgui.h>
|
||||
@@ -46,10 +47,12 @@ constexpr float DELTA_ANGLE_MAX = 30.0f;
|
||||
constexpr int PATH_STEP_MIN = 1;
|
||||
constexpr int PATH_STEP_MAX = 1000;
|
||||
|
||||
DevPanel::DevPanel(App& app) : m_app(app), m_config(app.config()) {}
|
||||
DevPanel::DevPanel(WorldScene& world_scene)
|
||||
: m_app(world_scene.scene_manager().app()), m_world_scene(world_scene),
|
||||
m_config(m_app.config()) {}
|
||||
|
||||
void DevPanel::init() {
|
||||
m_player = &m_app.client_world().get_player();
|
||||
m_player = &m_world_scene.client_world().get_player();
|
||||
update_config_view();
|
||||
update_player_profile();
|
||||
}
|
||||
@@ -383,7 +386,7 @@ void DevPanel::show_settings_tab_item() {
|
||||
128)) {
|
||||
m_config.set("world.rendering_distance",
|
||||
m_config_view.rendering_distance);
|
||||
m_app.client_world().hot_reload();
|
||||
m_world_scene.client_world().hot_reload();
|
||||
}
|
||||
if (ImGui::Checkbox("Fullscreen", &m_config_view.fullscreen)) {
|
||||
m_config.set("window.fullscreen", m_config_view.fullscreen);
|
||||
@@ -551,20 +554,23 @@ void DevPanel::show_server_world_table_bar() {
|
||||
}
|
||||
void DevPanel::show_client_world_table_bar() {
|
||||
|
||||
static int rendering_distance = m_app.client_world().rendering_distance();
|
||||
static int rendering_distance =
|
||||
m_world_scene.client_world().rendering_distance();
|
||||
if (ImGui::SliderInt("Render Distance", &rendering_distance, 2, 128)) {
|
||||
m_app.client_world().rendering_distance(rendering_distance);
|
||||
m_world_scene.client_world().rendering_distance(rendering_distance);
|
||||
// Config::get().set("world.rendering_distance", rendering_distance);
|
||||
}
|
||||
if (ImGui::Button("Rebuild World")) {
|
||||
m_app.client_world().rebuild_world();
|
||||
m_world_scene.client_world().rebuild_world();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Spawn Point")) {
|
||||
m_player->set_player_pos({0.0f, 255.0f, 0.0f});
|
||||
}
|
||||
ImGui::Text("Chunk Task Id %d", m_app.client_world().get_chunk_task_id());
|
||||
ImGui::Text("Client World Chunk %d", m_app.client_world().chunk_size());
|
||||
ImGui::Text("Chunk Task Id %d",
|
||||
m_world_scene.client_world().get_chunk_task_id());
|
||||
ImGui::Text("Client World Chunk %d",
|
||||
m_world_scene.client_world().chunk_size());
|
||||
}
|
||||
|
||||
void DevPanel::show_player_tab_item() {
|
||||
|
||||
@@ -141,48 +141,42 @@ void ClientPlayer::update(float delta_time) {
|
||||
DebugCollector::get().report("speed",
|
||||
std::format("Speed: {:.2} m/s", m_xz_speed));
|
||||
}
|
||||
void ClientPlayer::update_player_move_state(int key, int action) {
|
||||
switch (key) {
|
||||
case GLFW_KEY_W:
|
||||
if (action == GLFW_PRESS) {
|
||||
bool ClientPlayer::update_player_move_state(Key key, KeyAction action) {
|
||||
if (key == Key::W) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.forward = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.forward = false;
|
||||
|
||||
m_sprinting = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_S:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::S) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.back = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.back = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_A:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::A) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.left = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.left = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_D:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::D) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.right = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.right = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_SPACE:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::SPACE) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.up = true;
|
||||
if (space_on) {
|
||||
if (m_game_mode == CREATIVE) {
|
||||
is_fly = !is_fly ? true : false;
|
||||
is_fly = !is_fly;
|
||||
m_y_speed = 0.0f;
|
||||
}
|
||||
space_on = false;
|
||||
@@ -191,35 +185,39 @@ void ClientPlayer::update_player_move_state(int key, int action) {
|
||||
space_on = true;
|
||||
}
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.up = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_LEFT_SHIFT:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::LEFT_SHIFT) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_move_state.down = true;
|
||||
}
|
||||
if (action == GLFW_RELEASE) {
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_move_state.down = false;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_LEFT_CONTROL:
|
||||
if (action == GLFW_PRESS) {
|
||||
} else if (key == Key::LEFT_CTRL) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
m_sprinting = true;
|
||||
}
|
||||
break;
|
||||
case GLFW_KEY_F4:
|
||||
if (action == GLFW_PRESS) {
|
||||
/*
|
||||
if (action == KeyAction::RELEASE) {
|
||||
m_sprinting = false;
|
||||
}*/
|
||||
} else if (key == Key::F4) {
|
||||
if (action == KeyAction::PRESS) {
|
||||
if (m_game_mode == CREATIVE) {
|
||||
change_mode(SPECTATOR);
|
||||
} else {
|
||||
change_mode(CREATIVE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_moving = m_move_state.forward || m_move_state.back || m_move_state.left ||
|
||||
m_move_state.right;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_front_vec(float offset_x, float offset_y) {
|
||||
@@ -275,28 +273,32 @@ void ClientPlayer::update_lookup_block() {
|
||||
} else {
|
||||
m_look_block = std::nullopt;
|
||||
}
|
||||
}
|
||||
bool ClientPlayer::place_block(MouseKey key) {
|
||||
|
||||
if (m_look_block != std::nullopt) {
|
||||
if (Input::get_input_state().mouse_state.left) {
|
||||
if (m_world.is_solid(m_look_block->pos)) {
|
||||
m_world.report_block_change(m_look_block->pos, 0);
|
||||
}
|
||||
Input::get_input_state().mouse_state.left = false;
|
||||
}
|
||||
if (Input::get_input_state().mouse_state.right) {
|
||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||
if (!m_world.is_solid(near_pos)) {
|
||||
AABB block_box = ClientWorld::get_block_aabb(near_pos);
|
||||
AABB player_box = get_aabb(get_player_pos());
|
||||
if (!player_box.intersects(block_box)) {
|
||||
m_world.report_block_change(near_pos, m_place_block);
|
||||
}
|
||||
}
|
||||
Input::get_input_state().mouse_state.right = false;
|
||||
if (m_look_block == std::nullopt) {
|
||||
return false;
|
||||
}
|
||||
bool placeed = false;
|
||||
if (key == MouseKey::LEFT_BUTTON) {
|
||||
if (m_world.is_solid(m_look_block->pos)) {
|
||||
m_world.report_block_change(m_look_block->pos, 0);
|
||||
placeed = true;
|
||||
}
|
||||
}
|
||||
if (key == MouseKey::RIGHT_BUTTON) {
|
||||
glm::ivec3 near_pos = m_look_block->pos + m_look_block->normal;
|
||||
if (!m_world.is_solid(near_pos)) {
|
||||
AABB block_box = ClientWorld::get_block_aabb(near_pos);
|
||||
AABB player_box = get_aabb(get_player_pos());
|
||||
if (!player_box.intersects(block_box)) {
|
||||
m_world.report_block_change(near_pos, m_place_block);
|
||||
placeed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return placeed;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_move(float delta_time) {
|
||||
// if frame rate less than 1 frame per second, don't update
|
||||
if (delta_time > 1.0f) {
|
||||
@@ -523,7 +525,7 @@ Gait ClientPlayer::compute_gait() const {
|
||||
return Gait::WALK;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_scroll(double yoffset) {
|
||||
bool ClientPlayer::update_scroll(float yoffset) {
|
||||
if (m_game_mode == SPECTATOR) {
|
||||
if (yoffset > 0) {
|
||||
if (m_max_speed < 500.0f) {
|
||||
@@ -548,6 +550,28 @@ void ClientPlayer::update_scroll(double yoffset) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ClientPlayer::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||
if (e.action == KeyAction::PRESS) {
|
||||
return place_block(e.key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ClientPlayer::handle_key_event(const KeyEvent& e) {
|
||||
if (update_player_move_state(e.key, e.action)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
bool ClientPlayer::handle_mouse_wheel_event(const MouseWheelEvent& e) {
|
||||
if (update_scroll(e.offset)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClientPlayer::update_chunk_set(const ChunkPosSet& set) {
|
||||
|
||||
@@ -21,8 +21,8 @@ struct ChunkRenderData {
|
||||
};
|
||||
} // namespace
|
||||
|
||||
ClientWorld::ClientWorld(AudioEngine& auido, Config& config)
|
||||
: m_player(*this), m_audio(auido), m_config(config) {}
|
||||
ClientWorld::ClientWorld(AudioEngine& auido, Config& config, WorldScene& scene)
|
||||
: m_player(*this), m_audio(auido), m_config(config), m_world_scene(scene) {}
|
||||
|
||||
ClientWorld::~ClientWorld() {
|
||||
m_client->close();
|
||||
@@ -718,6 +718,7 @@ AABB ClientWorld::get_block_aabb(const glm::ivec3& pos) {
|
||||
|
||||
AudioEngine& ClientWorld::get_audio() { return m_audio; }
|
||||
Config& ClientWorld::get_config() { return m_config; }
|
||||
WorldScene& ClientWorld::world_scene() { return m_world_scene; }
|
||||
|
||||
void ClientWorld::request_exit() {
|
||||
if (m_receive_exit) {
|
||||
@@ -905,6 +906,36 @@ void ClientWorld::update(float delta_time) {
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientWorld::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[this](const MouseButtonEvent& e) {
|
||||
if (m_player.handle_mouse_button_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const MouseMoveEvent&) { return false; },
|
||||
[this](const MouseWheelEvent& e) {
|
||||
if (m_player.handle_mouse_wheel_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[this](const KeyEvent& e) {
|
||||
if (m_player.handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[](const WindowResizeEvent&) { return false; },
|
||||
[](const FrameBufferResizeEvent&) { return false; }
|
||||
|
||||
},
|
||||
e);
|
||||
}
|
||||
|
||||
glm::vec3 ClientWorld::sunlight_dir() const {
|
||||
float altitude = sin((m_day_tick - 6 * PER_HOUR) /
|
||||
static_cast<float>(DAY_TIME / 2) * std::numbers::pi) *
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
@@ -188,24 +189,24 @@ void PlayerRenderer::init() {
|
||||
m_inited = true;
|
||||
}
|
||||
|
||||
void PlayerRenderer::render(const Shader& shader) {
|
||||
void PlayerRenderer::render(const Shader& shader, ClientWorld& world) {
|
||||
if (!m_inited) {
|
||||
Logger::error("Player Renderer isn't init");
|
||||
return;
|
||||
}
|
||||
auto& m_camera = m_renderer.camera();
|
||||
auto& m_world = m_renderer.world();
|
||||
auto& m_player = m_world.get_player();
|
||||
glm::mat4 m_v_mat = m_camera.get_camera_lookat();
|
||||
|
||||
auto& camera = world.world_scene().camera();
|
||||
auto& m_player = world.get_player();
|
||||
glm::mat4 m_v_mat = camera.get_camera_lookat();
|
||||
glm::mat4 m_p_mat = m_renderer.world_proj_matrix();
|
||||
|
||||
auto& players = m_world.render_player_data();
|
||||
auto& players = world.render_player_data();
|
||||
shader.set_loc("proj_matrix", m_p_mat);
|
||||
|
||||
for (auto& player : players) {
|
||||
|
||||
if (player.uuid == m_player.get_uuid()) {
|
||||
if (m_camera.is_first_person()) {
|
||||
if (camera.is_first_person()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -302,15 +303,15 @@ void PlayerRenderer::render(const Shader& shader) {
|
||||
}
|
||||
|
||||
void PlayerRenderer::shadow_render(const Shader& shader,
|
||||
glm::mat4& light_matrix) {
|
||||
glm::mat4& light_matrix,
|
||||
ClientWorld& world) {
|
||||
if (!m_inited) {
|
||||
Logger::error("Player Renderer isn't init");
|
||||
return;
|
||||
}
|
||||
shader.use();
|
||||
shader.set_loc("lightSpaceMatrix", light_matrix);
|
||||
auto& m_world = m_renderer.world();
|
||||
auto& players = m_world.render_player_data();
|
||||
auto& players = world.render_player_data();
|
||||
|
||||
for (auto& player : players) {
|
||||
glm::mat4 model(1.0f);
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/config.hpp"
|
||||
#include "Cubed/debug_collector.hpp"
|
||||
#include "Cubed/dev_panel.hpp"
|
||||
#include "Cubed/gameplay/client_player.hpp"
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/primitive_data.hpp"
|
||||
#include "Cubed/render/renderer_constants.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
@@ -19,12 +16,9 @@
|
||||
|
||||
namespace Cubed {
|
||||
|
||||
Renderer::Renderer(const Camera& camera, ClientWorld& world,
|
||||
const TextureManager& texture_manager, DevPanel& dev_panel,
|
||||
Config& config)
|
||||
: m_camera(camera), m_dev_panel(dev_panel),
|
||||
m_texture_manager(texture_manager), m_world(world),
|
||||
m_world_renderer(*this), m_config(config) {}
|
||||
Renderer::Renderer(TextureManager& texture_manager, Config& config)
|
||||
: m_texture_manager(texture_manager), m_world_renderer(*this),
|
||||
m_config(config) {}
|
||||
|
||||
Renderer::~Renderer() {
|
||||
if (m_init) {
|
||||
@@ -120,12 +114,6 @@ void Renderer::init(bool debug_on) {
|
||||
VertexArray::unbind();
|
||||
VertexBuffer::unbind();
|
||||
|
||||
m_crosshair_image = std::make_unique<Image>();
|
||||
m_crosshair_image->set_image("texture/ui/0.png");
|
||||
m_crosshair_image
|
||||
->set_position(m_width / 2 + m_crosshair_image->width() / 2,
|
||||
m_height / 2 + m_crosshair_image->height() / 2)
|
||||
.set_scale(3.0f);
|
||||
m_init = true;
|
||||
}
|
||||
|
||||
@@ -148,24 +136,24 @@ void Renderer::init_text() {
|
||||
|
||||
DebugCollector::get().init_text();
|
||||
}
|
||||
|
||||
void Renderer::render() {
|
||||
void Renderer::begin_frame() {
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
// clear screen
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
}
|
||||
void Renderer::end_frame() {}
|
||||
|
||||
m_world_renderer.render();
|
||||
|
||||
void Renderer::begin_render_ui() {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
void Renderer::end_render_ui() { glEnable(GL_DEPTH_TEST); }
|
||||
|
||||
render_ui();
|
||||
|
||||
render_dev_panel();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
void Renderer::render_world(ClientWorld& world) {
|
||||
m_world_renderer.render(world);
|
||||
}
|
||||
|
||||
void Renderer::render_lable(const Label& label) {
|
||||
@@ -194,6 +182,10 @@ void Renderer::render_lable(const Label& label) {
|
||||
}
|
||||
|
||||
void Renderer::render_image(const Image& image) {
|
||||
if (!image.texture()) {
|
||||
Logger::error("Image id {} not set image!", image.id());
|
||||
return;
|
||||
}
|
||||
const auto& shader = get_shader("image");
|
||||
shader.use();
|
||||
auto& pos = image.pos();
|
||||
@@ -206,20 +198,12 @@ void Renderer::render_image(const Image& image) {
|
||||
shader.set_loc("proj_matrix", m_ui_proj_matrix);
|
||||
|
||||
m_vao[3].bind();
|
||||
image.texture().bind(0);
|
||||
|
||||
image.texture()->bind(0);
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
Tools::check_opengl_error();
|
||||
}
|
||||
|
||||
void Renderer::render_ui() {
|
||||
|
||||
auto& widget = DebugCollector::get().get_widget();
|
||||
widget.render(*this);
|
||||
render_crosshair();
|
||||
}
|
||||
|
||||
void Renderer::render_crosshair() { m_crosshair_image->render(*this); }
|
||||
|
||||
void Renderer::update(float delta_time) { m_delta_time = delta_time; }
|
||||
|
||||
void Renderer::update_fov(float fov) {
|
||||
@@ -229,19 +213,6 @@ void Renderer::update_fov(float fov) {
|
||||
glm::perspective(glm::radians(fov), m_aspect, NEAR_PLANE, FAR_PLANE);
|
||||
}
|
||||
|
||||
void Renderer::update_proj_matrix(float aspect, float width, float height) {
|
||||
m_aspect = aspect;
|
||||
|
||||
m_world_proj_matrix =
|
||||
glm::perspective(glm::radians(m_fov), aspect, NEAR_PLANE, FAR_PLANE);
|
||||
|
||||
m_ui_proj_matrix = glm::ortho(0.0f, width, height, 0.0f, -1.0f, 1.0f);
|
||||
// scale and then translate
|
||||
m_crosshair_image->set_position(
|
||||
width / 2.0f + m_crosshair_image->width() / 2,
|
||||
height / 2.0f + m_crosshair_image->height() / 2);
|
||||
}
|
||||
|
||||
void Renderer::updata_framebuffer(int width, int height) {
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
@@ -249,18 +220,55 @@ void Renderer::updata_framebuffer(int width, int height) {
|
||||
m_world_renderer.updata_framebuffer(width, height);
|
||||
|
||||
FrameBuffer::unbind();
|
||||
|
||||
m_width = width;
|
||||
m_height = height;
|
||||
}
|
||||
|
||||
void Renderer::render_dev_panel() {
|
||||
|
||||
void Renderer::render_dev_panel(DevPanel& dev_panel) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
m_dev_panel.render();
|
||||
dev_panel.render();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
bool Renderer::handle_event(const Event& e) {
|
||||
return std::visit(Overloaded{[](const MouseMoveEvent&) { return false; },
|
||||
[](const MouseButtonEvent&) { return false; },
|
||||
[](const MouseWheelEvent&) { return false; },
|
||||
[](const KeyEvent&) { return false; },
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[this](const WindowResizeEvent& e) {
|
||||
handle_window_resize_event(e);
|
||||
return false;
|
||||
},
|
||||
[this](const FrameBufferResizeEvent& e) {
|
||||
handle_frame_buffer_resize_event(e);
|
||||
return false;
|
||||
}
|
||||
|
||||
},
|
||||
e);
|
||||
}
|
||||
bool Renderer::handle_window_resize_event(const WindowResizeEvent& e) {
|
||||
m_window_width = static_cast<float>(e.width);
|
||||
m_window_height = static_cast<float>(e.height);
|
||||
m_ui_proj_matrix =
|
||||
glm::ortho(0.0f, m_window_width, m_window_height, 0.0f, -1.0f, 1.0f);
|
||||
return false;
|
||||
}
|
||||
bool Renderer::handle_frame_buffer_resize_event(
|
||||
const FrameBufferResizeEvent& e) {
|
||||
int frame_height = e.height;
|
||||
int frame_width = e.width;
|
||||
m_frame_width = static_cast<float>(e.width);
|
||||
m_frame_height = static_cast<float>(e.height);
|
||||
m_aspect = m_frame_width / m_frame_height;
|
||||
glViewport(0, 0, frame_width, frame_height);
|
||||
m_world_proj_matrix =
|
||||
glm::perspective(glm::radians(m_fov), m_aspect, NEAR_PLANE, FAR_PLANE);
|
||||
updata_framebuffer(frame_width, frame_height);
|
||||
return false;
|
||||
}
|
||||
|
||||
float& Renderer::ambient_strength() {
|
||||
return m_world_renderer.ambient_strength();
|
||||
}
|
||||
@@ -298,9 +306,6 @@ float& Renderer::underwater_fog_density() {
|
||||
}
|
||||
float& Renderer::water_density() { return m_world_renderer.water_density(); }
|
||||
|
||||
const Camera& Renderer::camera() const { return m_camera; }
|
||||
const ClientWorld& Renderer::world() const { return m_world; }
|
||||
ClientWorld& Renderer::world() { return m_world; }
|
||||
const glm::mat4& Renderer::world_proj_matrix() const {
|
||||
return m_world_proj_matrix;
|
||||
}
|
||||
@@ -310,8 +315,10 @@ const TextureManager& Renderer::texture_mamger() const {
|
||||
|
||||
float Renderer::delta_time() const { return m_delta_time; }
|
||||
|
||||
float Renderer::height() const { return m_height; }
|
||||
float Renderer::width() const { return m_width; }
|
||||
float Renderer::window_height() const { return m_window_height; }
|
||||
float Renderer::window_width() const { return m_window_width; }
|
||||
float Renderer::frame_height() const { return m_frame_height; }
|
||||
float Renderer::frame_width() const { return m_frame_width; }
|
||||
const glm::mat4& Renderer::p_mat() const { return m_world_proj_matrix; }
|
||||
const std::vector<VertexArray>& Renderer::vao() const { return m_vao; }
|
||||
} // namespace Cubed
|
||||
@@ -48,8 +48,10 @@ void Texture::parameterfv(TexturePname pname, const float* param) const {
|
||||
}
|
||||
void Texture::tex_image_2d(TextureFormat internalformat, TextureFormat format,
|
||||
GLenum type, const void* data, GLsizei width,
|
||||
GLsizei height, GLint level, GLint border) const {
|
||||
GLsizei height, GLint level, GLint border) {
|
||||
bind();
|
||||
m_width = static_cast<float>(width);
|
||||
m_height = static_cast<float>(height);
|
||||
glTexImage2D(get_gl_texture_type(), level,
|
||||
std::to_underlying(internalformat), width, height, border,
|
||||
std::to_underlying(format), type, data);
|
||||
@@ -58,8 +60,10 @@ void Texture::tex_image_2d(TextureFormat internalformat, TextureFormat format,
|
||||
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 {
|
||||
GLint border) {
|
||||
bind();
|
||||
m_width = static_cast<float>(width);
|
||||
m_height = static_cast<float>(height);
|
||||
glTexImage3D(get_gl_texture_type(), level,
|
||||
std::to_underlying(internalformat), width, height, depth,
|
||||
border, std::to_underlying(format), type, data);
|
||||
@@ -135,7 +139,8 @@ void Texture::set_clamp_to_edge(bool r, bool s, bool t) const {
|
||||
}
|
||||
|
||||
TextureType Texture::type() const { return M_TYPE; }
|
||||
|
||||
float Texture::width() const { return m_width; }
|
||||
float Texture::height() const { return m_height; }
|
||||
void Texture::unbind() {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glBindTexture(GL_TEXTURE_2D_ARRAY, 0);
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
#include "Cubed/gameplay/client_world.hpp"
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/render/renderer_constants.hpp"
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
#include "Cubed/tools/math_tools.hpp"
|
||||
namespace Cubed {
|
||||
WorldRenderer::WorldRenderer(Renderer& renderer)
|
||||
: m_renderer(renderer), m_player_renderer(renderer),
|
||||
m_world(renderer.world()), m_camera(renderer.camera()),
|
||||
m_texture_manager(renderer.texture_mamger()) {}
|
||||
WorldRenderer::~WorldRenderer() {
|
||||
m_accum_texture.reset();
|
||||
@@ -30,21 +30,21 @@ WorldRenderer::~WorldRenderer() {
|
||||
|
||||
void WorldRenderer::init() { m_player_renderer.init(); }
|
||||
|
||||
void WorldRenderer::render() {
|
||||
void WorldRenderer::render(ClientWorld& world) {
|
||||
// update view matrix;
|
||||
view_matrix = m_renderer.camera().get_camera_lookat();
|
||||
view_matrix = world.world_scene().camera().get_camera_lookat();
|
||||
|
||||
m_world_fbo->bind();
|
||||
// clear world framebuffer
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
day_night_calculation();
|
||||
day_night_calculation(world);
|
||||
|
||||
render_sky();
|
||||
render_world();
|
||||
render_outline();
|
||||
render_player();
|
||||
render_sky(world);
|
||||
render_world(world);
|
||||
render_outline(world);
|
||||
render_player(world);
|
||||
|
||||
FrameBuffer::unbind();
|
||||
|
||||
@@ -55,13 +55,13 @@ void WorldRenderer::render() {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
render_underwater();
|
||||
render_underwater(world);
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
}
|
||||
|
||||
void WorldRenderer::day_night_calculation() {
|
||||
void WorldRenderer::day_night_calculation(ClientWorld& world) {
|
||||
|
||||
m_parallel_light.sundir = glm::normalize(m_renderer.world().sunlight_dir());
|
||||
m_parallel_light.sundir = glm::normalize(world.sunlight_dir());
|
||||
m_parallel_light.sun_height = (-m_parallel_light.sundir).y;
|
||||
m_parallel_light.lightdir = m_parallel_light.sundir;
|
||||
|
||||
@@ -92,7 +92,9 @@ void WorldRenderer::day_night_calculation() {
|
||||
m_ambient_strength = glm::mix(0.45f, 0.25f, day_factor);
|
||||
}
|
||||
|
||||
void WorldRenderer::render_sky() {
|
||||
void WorldRenderer::render_sky(ClientWorld& world) {
|
||||
|
||||
auto& camera = world.world_scene().camera();
|
||||
|
||||
glm::vec3 zenith = {0.20f, 0.45f, 0.95f};
|
||||
|
||||
@@ -142,9 +144,8 @@ void WorldRenderer::render_sky() {
|
||||
|
||||
sky_shader.use();
|
||||
|
||||
glm::mat4 model_mat =
|
||||
glm::translate(glm::mat4(1.0f),
|
||||
m_camera.get_camera_pos() - glm::vec3(0.5f, 0.5f, 0.5f));
|
||||
glm::mat4 model_mat = glm::translate(
|
||||
glm::mat4(1.0f), camera.get_camera_pos() - glm::vec3(0.5f, 0.5f, 0.5f));
|
||||
|
||||
glm::mat4 mv_mat = view_matrix * model_mat;
|
||||
|
||||
@@ -195,25 +196,27 @@ void WorldRenderer::render_sky() {
|
||||
glDrawArrays(GL_TRIANGLES, 0, 6);
|
||||
};
|
||||
// draw sun
|
||||
glm::vec3 sun_pos = m_camera.get_camera_pos() +
|
||||
normalize(-m_world.sunlight_dir()) * (FAR_PLANE * 0.9f);
|
||||
glm::vec3 sun_pos =
|
||||
camera.get_camera_pos() +
|
||||
normalize(-m_parallel_light.sundir) * (FAR_PLANE * 0.9f);
|
||||
billboard_drawer(sun_pos, SUN_SIZE, SUN_COLOR);
|
||||
|
||||
// draw moon
|
||||
|
||||
glm::vec3 moon_pos = m_camera.get_camera_pos() +
|
||||
normalize(m_world.sunlight_dir()) * (FAR_PLANE * 0.9f);
|
||||
glm::vec3 moon_pos =
|
||||
camera.get_camera_pos() +
|
||||
normalize(m_parallel_light.sundir) * (FAR_PLANE * 0.9f);
|
||||
billboard_drawer(moon_pos, MOON_SIZE, MOON_COLOR);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
||||
void WorldRenderer::render_world() {
|
||||
void WorldRenderer::render_world(ClientWorld& world) {
|
||||
|
||||
// shader map
|
||||
|
||||
auto m_height = m_renderer.height();
|
||||
auto m_width = m_renderer.width();
|
||||
auto height = m_renderer.frame_height();
|
||||
auto width = m_renderer.frame_width();
|
||||
|
||||
glm::mat4 model_mat =
|
||||
glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
@@ -223,22 +226,22 @@ void WorldRenderer::render_world() {
|
||||
glm::mat4 norm_mat = glm::transpose(glm::inverse(mv_mat));
|
||||
|
||||
if (m_shader_on) {
|
||||
shadow_map_generate();
|
||||
shadow_map_generate(world);
|
||||
}
|
||||
|
||||
m_world_fbo->bind();
|
||||
|
||||
glCullFace(GL_BACK);
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
render_normal_block(model_mat, mv_mat, norm_mat);
|
||||
render_normal_block(model_mat, mv_mat, norm_mat, world);
|
||||
|
||||
// copy depth buffer
|
||||
m_world_fbo->bind(FrameBufferType::READ_FRAMEBUFFER);
|
||||
|
||||
m_oit_fbo->bind(FrameBufferType::DRAW_FRAMEBUFFER);
|
||||
|
||||
glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height,
|
||||
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_DEPTH_BUFFER_BIT, GL_NEAREST);
|
||||
m_oit_fbo->bind(FrameBufferType::DRAW_FRAMEBUFFER);
|
||||
|
||||
@@ -256,14 +259,14 @@ void WorldRenderer::render_world() {
|
||||
glBlendFunci(0, GL_ONE, GL_ONE);
|
||||
|
||||
glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||||
render_transparent_block(mv_mat, norm_mat);
|
||||
render_transparent_block(mv_mat, norm_mat, world);
|
||||
}
|
||||
|
||||
void WorldRenderer::render_outline() {
|
||||
void WorldRenderer::render_outline(ClientWorld& world) {
|
||||
const auto& shader = m_renderer.get_shader("outline");
|
||||
shader.use();
|
||||
|
||||
const auto& block_pos = m_renderer.world().get_look_block_pos();
|
||||
const auto& block_pos = world.get_look_block_pos();
|
||||
|
||||
if (block_pos != std::nullopt) {
|
||||
|
||||
@@ -285,24 +288,24 @@ void WorldRenderer::render_outline() {
|
||||
}
|
||||
}
|
||||
|
||||
void WorldRenderer::shadow_map_generate() {
|
||||
void WorldRenderer::shadow_map_generate(ClientWorld& world) {
|
||||
float texels_per_unit = 0.0f;
|
||||
const auto& lightdir = m_parallel_light.lightdir;
|
||||
|
||||
auto m_delta_time = m_renderer.delta_time();
|
||||
|
||||
auto& camera = world.world_scene().camera();
|
||||
// shader map
|
||||
glm::mat4& light_space_matrix = m_parallel_light.light_space_matrix;
|
||||
|
||||
auto& m_render_snapshots = m_world.render_snapshots();
|
||||
auto& camera_pos = m_camera.get_camera_pos();
|
||||
auto& m_render_snapshots = world.render_snapshots();
|
||||
auto& camera_pos = camera.get_camera_pos();
|
||||
|
||||
const auto& depth_shader = m_renderer.get_shader("depth_shader");
|
||||
|
||||
depth_shader.use();
|
||||
|
||||
glm::vec3 cam_pos = m_camera.get_camera_pos();
|
||||
glm::vec3 cam_fwd = m_camera.get_camera_front();
|
||||
glm::vec3 cam_pos = camera.get_camera_pos();
|
||||
glm::vec3 cam_fwd = camera.get_camera_front();
|
||||
float half_extent = 128.0f;
|
||||
|
||||
glm::vec3 center = cam_pos + cam_fwd * (half_extent * 0.5f);
|
||||
@@ -389,13 +392,13 @@ void WorldRenderer::shadow_map_generate() {
|
||||
}
|
||||
// player
|
||||
auto& player_shadow = m_renderer.get_shader("player_depth");
|
||||
m_player_renderer.shadow_render(player_shadow, light_space_matrix);
|
||||
m_player_renderer.shadow_render(player_shadow, light_space_matrix, world);
|
||||
}
|
||||
|
||||
void WorldRenderer::render_underwater() {
|
||||
void WorldRenderer::render_underwater(ClientWorld& world) {
|
||||
|
||||
const auto& shader = m_renderer.get_shader("under_water");
|
||||
|
||||
auto& camera = world.world_scene().camera();
|
||||
shader.use();
|
||||
|
||||
auto& m_vao = m_renderer.vao();
|
||||
@@ -406,10 +409,10 @@ void WorldRenderer::render_underwater() {
|
||||
|
||||
shader.set_loc("u_sceneTexture", 0);
|
||||
shader.set_loc("u_time", static_cast<float>(glfwGetTime()));
|
||||
shader.set_loc("u_underwater", m_camera.is_under_water());
|
||||
shader.set_loc("u_underwater", camera.is_under_water());
|
||||
shader.set_loc("u_waterColor", glm::vec3(0.1f, 0.25f, 0.35f));
|
||||
shader.set_loc("u_fogDensity", m_underwater_fog_density);
|
||||
shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||
shader.set_loc("cameraPos", camera.get_camera_pos());
|
||||
shader.set_loc("sunDir", -m_parallel_light.sundir);
|
||||
shader.set_loc("waterDensity", m_water_density);
|
||||
shader.set_loc("InverseViewProjection",
|
||||
@@ -427,13 +430,14 @@ void WorldRenderer::render_underwater() {
|
||||
|
||||
void WorldRenderer::render_normal_block(const glm::mat4& model_mat,
|
||||
const glm::mat4& mv_mat,
|
||||
const glm::mat4& norm_mat) {
|
||||
const glm::mat4& norm_mat,
|
||||
ClientWorld& world) {
|
||||
|
||||
// shader map
|
||||
glm::mat4& light_space_matrix = m_parallel_light.light_space_matrix;
|
||||
|
||||
auto& m_render_snapshots = m_world.render_snapshots();
|
||||
auto& camera_pos = m_camera.get_camera_pos();
|
||||
auto& camera = world.world_scene().camera();
|
||||
auto& m_render_snapshots = world.render_snapshots();
|
||||
auto& camera_pos = camera.get_camera_pos();
|
||||
|
||||
const auto& lightdir = m_parallel_light.lightdir;
|
||||
|
||||
@@ -467,14 +471,14 @@ void WorldRenderer::render_normal_block(const glm::mat4& model_mat,
|
||||
normal_block_shader.set_loc("maxRadius", m_max_radius);
|
||||
normal_block_shader.set_loc("samples", m_samples);
|
||||
normal_block_shader.set_loc("specularStrength", m_specular_strength);
|
||||
normal_block_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||
normal_block_shader.set_loc("cameraPos", camera.get_camera_pos());
|
||||
normal_block_shader.set_loc("flipY", m_flip_y);
|
||||
normal_block_shader.set_loc("renderDistance", m_world.rendering_distance());
|
||||
normal_block_shader.set_loc("renderDistance", world.rendering_distance());
|
||||
normal_block_shader.set_loc("skyColor", m_sky_uniform.sky_top);
|
||||
|
||||
glm::mat4 mvp_mat = proj_mat * mv_mat;
|
||||
|
||||
auto& m_planes = m_world.planes();
|
||||
auto& m_planes = world.planes();
|
||||
|
||||
Math::extract_frustum_planes(mvp_mat, m_planes);
|
||||
|
||||
@@ -545,10 +549,11 @@ void WorldRenderer::render_normal_block(const glm::mat4& model_mat,
|
||||
}
|
||||
|
||||
void WorldRenderer::render_transparent_block(const glm::mat4& mv_mat,
|
||||
const glm::mat4& norm_mat) {
|
||||
|
||||
auto& m_render_snapshots = m_world.render_snapshots();
|
||||
const glm::mat4& norm_mat,
|
||||
ClientWorld& world) {
|
||||
|
||||
auto& m_render_snapshots = world.render_snapshots();
|
||||
auto& camera = world.world_scene().camera();
|
||||
const auto& lightdir = m_parallel_light.lightdir;
|
||||
glm::vec3 light_dir_view =
|
||||
glm::normalize(glm::mat3(view_matrix) * lightdir);
|
||||
@@ -573,11 +578,11 @@ void WorldRenderer::render_transparent_block(const glm::mat4& mv_mat,
|
||||
accum_shader.use();
|
||||
|
||||
set_accum_loc(accum_shader);
|
||||
accum_shader.set_loc("cameraPos", m_camera.get_camera_pos());
|
||||
accum_shader.set_loc("cameraPos", camera.get_camera_pos());
|
||||
|
||||
m_texture_manager.get_texture_array()->bind(0);
|
||||
|
||||
auto& m_planes = m_world.planes();
|
||||
auto& m_planes = world.planes();
|
||||
|
||||
for (const auto& snapshot : m_render_snapshots) {
|
||||
if (!snapshot) {
|
||||
@@ -619,7 +624,7 @@ void WorldRenderer::render_transparent_block(const glm::mat4& mv_mat,
|
||||
water_shader.set_loc("cloudWhiteMix", m_sky_uniform.cloud_white_mix);
|
||||
water_shader.set_loc("cloudThresholdLow", m_cloud_threshold_low);
|
||||
water_shader.set_loc("cloudThresholdHigh", m_cloud_threshold_high);
|
||||
water_shader.set_loc("underwater", m_camera.is_under_water());
|
||||
water_shader.set_loc("underwater", camera.is_under_water());
|
||||
water_shader.set_loc("refractStrength", m_refract_strength);
|
||||
water_shader.set_loc("enablePerturb", m_water_perturb);
|
||||
water_shader.set_loc("enableDepthFade", m_water_depth_fade);
|
||||
@@ -670,7 +675,7 @@ void WorldRenderer::render_transparent_block(const glm::mat4& mv_mat,
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void WorldRenderer::render_player() {
|
||||
void WorldRenderer::render_player(ClientWorld& world) {
|
||||
auto& shader = m_renderer.get_shader("player");
|
||||
shader.use();
|
||||
glm::vec3 light_dir_view =
|
||||
@@ -692,7 +697,7 @@ void WorldRenderer::render_player() {
|
||||
// shader.set_loc("skyColor", m_sky_uniform.sky_top);
|
||||
|
||||
m_depth_map_texture->bind(0);
|
||||
m_player_renderer.render(shader);
|
||||
m_player_renderer.render(shader, world);
|
||||
}
|
||||
|
||||
glm::vec3 WorldRenderer::quantize_sun_direction(const glm::vec3& lightdir,
|
||||
|
||||
99
src/scene/scene_manager.cpp
Normal file
99
src/scene/scene_manager.cpp
Normal file
@@ -0,0 +1,99 @@
|
||||
#include "Cubed/scene/scene_manager.hpp"
|
||||
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
|
||||
namespace Cubed {
|
||||
SceneManager::SceneManager(App& app) : m_app(app) {}
|
||||
SceneManager::~SceneManager() {}
|
||||
|
||||
void SceneManager::update(float dt) {
|
||||
m_pending_delete_scene.clear();
|
||||
|
||||
if (!m_scenes.empty()) {
|
||||
m_scenes.top()->update(dt);
|
||||
}
|
||||
process_operation();
|
||||
}
|
||||
void SceneManager::render(Renderer& renderer) {
|
||||
if (m_scenes.empty()) {
|
||||
return;
|
||||
}
|
||||
m_scenes.top()->render(renderer);
|
||||
}
|
||||
|
||||
bool SceneManager::handle_event(const Event& e) {
|
||||
if (m_scenes.empty()) {
|
||||
return false;
|
||||
}
|
||||
return m_scenes.top()->handle_event(e);
|
||||
}
|
||||
|
||||
void SceneManager::request_change(SceneType type) {
|
||||
ASSERT(!m_operation.has_value());
|
||||
m_operation = {OperationType::CHANGE, type};
|
||||
}
|
||||
void SceneManager::request_push(SceneType type) {
|
||||
ASSERT(!m_operation.has_value());
|
||||
m_operation = {OperationType::PUSH, type};
|
||||
}
|
||||
void SceneManager::request_pop() {
|
||||
ASSERT(!m_operation.has_value());
|
||||
m_operation = {OperationType::POP, std::nullopt};
|
||||
}
|
||||
|
||||
void SceneManager::process_operation() {
|
||||
while (m_operation) {
|
||||
auto op = std::move(*m_operation);
|
||||
m_operation.reset();
|
||||
|
||||
switch (op.type) {
|
||||
case OperationType::PUSH:
|
||||
push(*op.scene);
|
||||
break;
|
||||
case OperationType::POP:
|
||||
pop();
|
||||
break;
|
||||
case OperationType::CHANGE:
|
||||
change(*op.scene);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneManager::change(SceneType type) {
|
||||
if (!m_scenes.empty()) {
|
||||
pop();
|
||||
}
|
||||
|
||||
push(type);
|
||||
}
|
||||
void SceneManager::push(SceneType type) {
|
||||
auto scene = create_scene(type);
|
||||
scene->on_enter();
|
||||
m_scenes.push(std::move(scene));
|
||||
}
|
||||
void SceneManager::pop() {
|
||||
if (m_scenes.empty()) {
|
||||
return;
|
||||
}
|
||||
auto scene = std::move(m_scenes.top());
|
||||
m_scenes.pop();
|
||||
scene->on_leave();
|
||||
m_pending_delete_scene.push_back(std::move(scene));
|
||||
}
|
||||
|
||||
std::unique_ptr<Scene> SceneManager::create_scene(SceneType type) {
|
||||
switch (type) {
|
||||
case SceneType::WORLD:
|
||||
return std::make_unique<WorldScene>(*this);
|
||||
case SceneType::MAIN_MENU:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string err = std::format("Unknown Scene");
|
||||
ASSERT_MSG(false, err);
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
|
||||
App& SceneManager::app() { return m_app; }
|
||||
} // namespace Cubed
|
||||
85
src/scene/world_scene.cpp
Normal file
85
src/scene/world_scene.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
|
||||
#include "Cubed/app.hpp"
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/scene/scene_manager.hpp"
|
||||
namespace Cubed {
|
||||
WorldScene::WorldScene(SceneManager& scene_manager)
|
||||
: m_scene_manager(scene_manager), m_dev_panel(*this),
|
||||
m_client_world(scene_manager.app().audio(), scene_manager.app().config(),
|
||||
*this),
|
||||
m_ui_manager(*this), m_argument(scene_manager.app().argument()) {}
|
||||
|
||||
WorldScene::~WorldScene() {
|
||||
if (m_client) {
|
||||
m_client->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void WorldScene::update(float dt) {
|
||||
m_client_world.update(dt);
|
||||
m_camera.update_move_camera();
|
||||
m_client_world.get_audio().update_listener(m_camera.get_camera_pos(),
|
||||
m_camera.get_camera_front(),
|
||||
glm::vec3(0, 1, 0));
|
||||
|
||||
/*
|
||||
const auto& player = m_client_world.get_player();
|
||||
if (player_gait != player.get_gait()) {
|
||||
player_gait = player.get_gait();
|
||||
float fov = m_client_world.get("player.fov", 70.0f);
|
||||
if (player_gait == Gait::WALK) {
|
||||
m_renderer.update_fov(fov);
|
||||
}
|
||||
if (player_gait == Gait::RUN) {
|
||||
m_renderer.update_fov(fov + 5.0f);
|
||||
}
|
||||
}*/
|
||||
m_ui_manager.update(dt);
|
||||
}
|
||||
|
||||
void WorldScene::render(Renderer& renderer) {
|
||||
|
||||
renderer.render_world(m_client_world);
|
||||
|
||||
renderer.render_dev_panel(m_dev_panel);
|
||||
|
||||
m_ui_manager.render(renderer);
|
||||
}
|
||||
bool WorldScene::handle_event(const Event& e) {
|
||||
if (m_ui_manager.handle_event(e)) {
|
||||
return true;
|
||||
}
|
||||
if (m_camera.handle_event(e)) {
|
||||
return true;
|
||||
}
|
||||
// world event needs to be processed last
|
||||
if (m_client_world.handle_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void WorldScene::on_enter() {
|
||||
|
||||
m_client = std::make_shared<NetworkClient>(m_client_world);
|
||||
|
||||
m_client->start(m_argument.ip, m_argument.port);
|
||||
// init will send packet
|
||||
m_client_world.init(m_argument.player, m_client);
|
||||
|
||||
Logger::info("World Init Success");
|
||||
m_camera.camera_init(&m_client_world.get_player());
|
||||
m_scene_manager.app().window().set_camera(&m_camera);
|
||||
m_dev_panel.init();
|
||||
m_ui_manager.init();
|
||||
}
|
||||
void WorldScene::on_leave() {
|
||||
m_client_world.request_exit();
|
||||
|
||||
m_scene_manager.app().window().set_camera(nullptr);
|
||||
}
|
||||
|
||||
Camera& WorldScene::camera() { return m_camera; }
|
||||
SceneManager& WorldScene::scene_manager() { return m_scene_manager; }
|
||||
ClientWorld& WorldScene::client_world() { return m_client_world; }
|
||||
} // namespace Cubed
|
||||
@@ -11,7 +11,6 @@ constexpr int BLOCK_SIZE = 16;
|
||||
constexpr int BLOCK_NORMAL_SIZE = 128;
|
||||
constexpr int CROSS_PLANE_SIZE = 16;
|
||||
constexpr int BLOCK_ITEM_SIZE = 16;
|
||||
constexpr int UI_SIZE = 16;
|
||||
constexpr int BLOCK_STATUS_SIZE = 16;
|
||||
constexpr int SKIN_SIZE = 64;
|
||||
|
||||
@@ -58,7 +57,13 @@ const Texture* TextureManager::get_texture_array() const {
|
||||
const Texture* TextureManager::get_cross_plane_array() const {
|
||||
return m_cross_plane_array.get();
|
||||
}
|
||||
const Texture* TextureManager::get_ui_array() const { return m_ui_array.get(); }
|
||||
const Texture* TextureManager::get_image_texture(const std::string& path) {
|
||||
auto it = m_ui_map.find(path);
|
||||
if (it != m_ui_map.end()) {
|
||||
return it->second.get();
|
||||
}
|
||||
return load_image_texture(path);
|
||||
}
|
||||
|
||||
const Texture* TextureManager::get_pbr_texture() const {
|
||||
return m_normal_texture_array.get();
|
||||
@@ -146,13 +151,19 @@ void TextureManager::load_cross_plane_texture(unsigned id) {
|
||||
CROSS_PLANE_SIZE, CROSS_PLANE_SIZE);
|
||||
}
|
||||
|
||||
void TextureManager::load_ui_texture(unsigned id) {
|
||||
ASSERT_MSG(id < MAX_UI_NUM, "Exceed the max ui sum limit");
|
||||
const Texture* TextureManager::load_image_texture(const std::string& path) {
|
||||
|
||||
std::string path = "texture/ui/" + std::to_string(id) + ".png";
|
||||
auto image_data = (Tools::load_image_data(path));
|
||||
m_ui_array->tex_sub_image_3d(TextureFormat::RGBA, GL_UNSIGNED_BYTE,
|
||||
image_data.data, 0, 0, id, UI_SIZE, UI_SIZE);
|
||||
std::unique_ptr<Texture> image =
|
||||
std::make_unique<Texture>(TextureType::TEXTURE_2D);
|
||||
image->tex_image_2d(RGBA, RGBA, GL_UNSIGNED_BYTE, image_data.data,
|
||||
image_data.width, image_data.height);
|
||||
image->set_nearest();
|
||||
auto [it, inserted] = m_ui_map.try_emplace(path, std::move(image));
|
||||
if (!inserted) {
|
||||
Logger::error("Path {} already exist!", path);
|
||||
}
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
void TextureManager::load_pbr_texture(unsigned id) {
|
||||
@@ -232,17 +243,7 @@ void TextureManager::init_block() {
|
||||
|
||||
Logger::info("Block Texture Load Success");
|
||||
}
|
||||
void TextureManager::init_ui() {
|
||||
m_ui_array = std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
|
||||
m_ui_array->tex_image_3d(TextureFormat::RGBA, TextureFormat::RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr, UI_SIZE, UI_SIZE,
|
||||
MAX_UI_NUM);
|
||||
for (int i = 0; i < MAX_UI_NUM; i++) {
|
||||
load_ui_texture(i);
|
||||
}
|
||||
|
||||
m_ui_array->set_nearest();
|
||||
}
|
||||
void TextureManager::init_ui() {}
|
||||
|
||||
void TextureManager::init_skin() {
|
||||
m_skin = std::make_unique<Texture>(TextureType::TEXTURE_2D);
|
||||
@@ -304,4 +305,31 @@ void TextureManager::hot_reload() {
|
||||
|
||||
int TextureManager::max_aniso() const { return static_cast<int>(m_max_aniso); }
|
||||
|
||||
bool TextureManager::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[](const MouseMoveEvent&) { return false; },
|
||||
[](const MouseButtonEvent&) { return false; },
|
||||
[](const MouseWheelEvent&) { return false; },
|
||||
[this](const KeyEvent& e) {
|
||||
if (handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[](const WindowResizeEvent&) { return false; },
|
||||
[](const FrameBufferResizeEvent&) { return false; }
|
||||
|
||||
},
|
||||
e);
|
||||
}
|
||||
|
||||
bool TextureManager::handle_key_event(const KeyEvent& e) {
|
||||
if (e.key == Key::R && e.action == KeyAction::PRESS) {
|
||||
need_reload();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace Cubed
|
||||
@@ -38,9 +38,9 @@ void Font::load_character(char8_t c) {
|
||||
static_cast<int>(c), width, height);
|
||||
|
||||
Character character = {
|
||||
glm::vec2{0.0f, 0.0f},
|
||||
glm::vec2{static_cast<float>(width) / m_texture_width,
|
||||
static_cast<float>(height) / m_texture_height},
|
||||
glm::vec2{0.5f / m_texture_width, 0.5f / m_texture_height},
|
||||
glm::vec2{(width - 0.5f) / m_texture_width,
|
||||
(height - 0.5f) / m_texture_height},
|
||||
glm::ivec2(m_face->glyph->bitmap.width, m_face->glyph->bitmap.rows),
|
||||
glm::ivec2(m_face->glyph->bitmap_left, m_face->glyph->bitmap_top),
|
||||
static_cast<GLuint>(m_face->glyph->advance.x)};
|
||||
@@ -51,7 +51,7 @@ void Font::load_character(char8_t c) {
|
||||
void Font::setup_font_character() {
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
m_text_texture = std::make_unique<Texture>(TextureType::TEXTURE_2D_ARRAY);
|
||||
m_text_texture->tex_image_3d(TextureFormat::RED, TextureFormat::RED,
|
||||
m_text_texture->tex_image_3d(TextureFormat::R8, TextureFormat::RED,
|
||||
GL_UNSIGNED_BYTE, nullptr, m_texture_width,
|
||||
m_texture_height, MAX_CHARACTER);
|
||||
|
||||
|
||||
0
src/ui/button.cpp
Normal file
0
src/ui/button.cpp
Normal file
@@ -1,27 +1,35 @@
|
||||
#include "Cubed/ui/image.hpp"
|
||||
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/tools/shader_tools.hpp"
|
||||
#include "Cubed/texture_manager.hpp"
|
||||
|
||||
namespace Cubed {
|
||||
Image::Image() : m_texture(TextureType::TEXTURE_2D) {}
|
||||
Image::Image() {}
|
||||
void Image::update(float dt) { (void)dt; }
|
||||
void Image::render(Renderer& renderer) { renderer.render_image(*this); }
|
||||
|
||||
Image& Image::set_image(std::filesystem::path path) {
|
||||
auto data = Tools::load_image_data(path);
|
||||
m_texture.tex_image_2d(RGBA, RGBA, GL_UNSIGNED_BYTE, data.data, data.width,
|
||||
data.height);
|
||||
m_height = data.height;
|
||||
m_width = data.width;
|
||||
m_texture.set_nearest();
|
||||
Image& Image::set_image(const std::string& path,
|
||||
TextureManager& texture_manager) {
|
||||
m_texture = texture_manager.get_image_texture(path);
|
||||
return *this;
|
||||
}
|
||||
|
||||
float Image::height() const { return m_height; }
|
||||
float Image::height() const {
|
||||
if (!m_texture) {
|
||||
Logger::error("Image id {} not set image!", m_id);
|
||||
return 0.0f;
|
||||
}
|
||||
return m_texture->height();
|
||||
}
|
||||
|
||||
float Image::width() const { return m_width; }
|
||||
float Image::width() const {
|
||||
if (!m_texture) {
|
||||
Logger::error("Image id {} not set image!", m_id);
|
||||
return 0.0f;
|
||||
}
|
||||
return m_texture->width();
|
||||
}
|
||||
|
||||
const Texture& Image::texture() const { return m_texture; }
|
||||
const Texture* Image::texture() const { return m_texture; }
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -28,7 +28,7 @@ void UIVertexData::upload() {
|
||||
m_vbo->buffer_data(m_vertices.data(), m_vertices.size() * sizeof(Vertex2D),
|
||||
BufferUsage::DYNAMIC_DRAW);
|
||||
|
||||
m_vao->attribute(0, 3, GL_FLOAT, sizeof(Vertex2D), (void*)0);
|
||||
m_vao->attribute(0, 2, GL_FLOAT, sizeof(Vertex2D), (void*)0);
|
||||
m_vao->attribute(1, 2, GL_FLOAT, sizeof(Vertex2D),
|
||||
(void*)offsetof(Vertex2D, s));
|
||||
m_vao->attribute(2, 1, GL_FLOAT, sizeof(Vertex2D),
|
||||
|
||||
88
src/ui/world_ui_manager.cpp
Normal file
88
src/ui/world_ui_manager.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include "Cubed/ui/world_ui_manager.hpp"
|
||||
|
||||
#include "Cubed/app.hpp"
|
||||
#include "Cubed/debug_collector.hpp"
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/scene/scene_manager.hpp"
|
||||
#include "Cubed/scene/world_scene.hpp"
|
||||
namespace Cubed {
|
||||
|
||||
WorldUIManager::WorldUIManager(WorldScene& scene) : m_scene(scene) {}
|
||||
WorldUIManager::~WorldUIManager() {}
|
||||
|
||||
void WorldUIManager::init() {
|
||||
auto crosshair = std::make_unique<Image>();
|
||||
|
||||
crosshair->set_image("texture/ui/0.png",
|
||||
m_scene.scene_manager().app().texture_manager());
|
||||
auto& renderer = m_scene.scene_manager().app().renderer();
|
||||
crosshair
|
||||
->set_position(renderer.window_width() / 2 + crosshair->width() / 2,
|
||||
renderer.window_height() / 2 + crosshair->height() / 2)
|
||||
.set_scale(3.0f);
|
||||
m_widgets.try_emplace("crosshair", std::move(crosshair));
|
||||
}
|
||||
void WorldUIManager::update(float) {}
|
||||
void WorldUIManager::render(Renderer& renderer) {
|
||||
renderer.begin_render_ui();
|
||||
|
||||
auto& widget = DebugCollector::get().get_widget();
|
||||
widget.render(renderer);
|
||||
for (auto& widget : m_widgets) {
|
||||
widget.second->render(renderer);
|
||||
}
|
||||
|
||||
renderer.end_render_ui();
|
||||
}
|
||||
bool WorldUIManager::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[](const MouseMoveEvent&) { return false; },
|
||||
[this](const MouseButtonEvent& e) {
|
||||
if (handle_mouse_button_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[this](const MouseWheelEvent& e) {
|
||||
if (handle_mouse_wheel_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[this](const KeyEvent& e) {
|
||||
if (handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[this](const WindowResizeEvent& e) {
|
||||
handle_window_resize_event(e);
|
||||
return false;
|
||||
},
|
||||
[](const FrameBufferResizeEvent&) { return false; }
|
||||
|
||||
},
|
||||
e);
|
||||
}
|
||||
|
||||
bool WorldUIManager::handle_mouse_button_event(const MouseButtonEvent&) {
|
||||
return false;
|
||||
}
|
||||
bool WorldUIManager::handle_window_resize_event(const WindowResizeEvent& e) {
|
||||
auto it = m_widgets.find("crosshair");
|
||||
if (it != m_widgets.end()) {
|
||||
auto* crosshair = dynamic_cast<Image*>(it->second.get());
|
||||
if (crosshair) {
|
||||
crosshair->set_position(e.width / 2 + crosshair->width() / 2,
|
||||
e.height / 2 + crosshair->height() / 2);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool WorldUIManager::handle_mouse_wheel_event(const MouseWheelEvent&) {
|
||||
return false;
|
||||
}
|
||||
bool WorldUIManager::handle_key_event(const KeyEvent&) { return false; }
|
||||
|
||||
} // namespace Cubed
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "Cubed/window.hpp"
|
||||
|
||||
#include "Cubed/render/renderer.hpp"
|
||||
#include "Cubed/camera.hpp"
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
#include "Cubed/tools/font.hpp"
|
||||
#include "Cubed/tools/log.hpp"
|
||||
@@ -14,8 +14,7 @@ namespace Cubed {
|
||||
static int windowed_xpos = 0, windowed_ypos = 0;
|
||||
static int windowed_width = 800, windowed_height = 600;
|
||||
|
||||
Window::Window(Renderer& renderer, Config& config)
|
||||
: m_renderer(renderer), m_config(config) {}
|
||||
Window::Window(Config& config) : m_config(config) {}
|
||||
|
||||
Window::~Window() {
|
||||
if (m_imgui_init) {
|
||||
@@ -41,14 +40,64 @@ const GLFWwindow* Window::get_glfw_window() const { return m_window; }
|
||||
|
||||
GLFWwindow* Window::get_glfw_window() { return m_window; }
|
||||
|
||||
void Window::update_viewport() {
|
||||
glfwGetFramebufferSize(m_window, &m_width, &m_height);
|
||||
m_aspect = (float)m_width / (float)m_height;
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
m_renderer.update_proj_matrix(m_aspect, m_width, m_height);
|
||||
m_renderer.updata_framebuffer(m_width, m_height);
|
||||
m_config.set("window.width", windowed_width);
|
||||
m_config.set("window.height", windowed_height);
|
||||
bool Window::handle_event(const Event& e) {
|
||||
return std::visit(
|
||||
Overloaded{[](const MouseMoveEvent&) { return false; },
|
||||
[this](const MouseButtonEvent& e) {
|
||||
if (handle_mouse_button_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const MouseWheelEvent&) { return false; },
|
||||
[this](const KeyEvent& e) {
|
||||
if (handle_key_event(e)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
[](const TextInputEvent&) { return false; },
|
||||
[this](const WindowResizeEvent& e) {
|
||||
handle_window_resize_event(e);
|
||||
return false;
|
||||
},
|
||||
[](const FrameBufferResizeEvent&) { return false; }
|
||||
|
||||
},
|
||||
e);
|
||||
}
|
||||
|
||||
bool Window::handle_key_event(const KeyEvent& e) {
|
||||
if (e.key == Key::F11 && e.action == KeyAction::PRESS) {
|
||||
toggle_fullscreen();
|
||||
return true;
|
||||
}
|
||||
if (e.key == Key::ESCAPE && e.action == KeyAction::PRESS) {
|
||||
glfwSetWindowShouldClose(m_window, GLFW_TRUE);
|
||||
return true;
|
||||
}
|
||||
if (e.key == Key::LEFT_ALT && e.action == KeyAction::PRESS) {
|
||||
toggle_mouse_able();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Window::handle_window_resize_event(const WindowResizeEvent& e) {
|
||||
m_window_height = e.height;
|
||||
m_window_width = e.width;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Window::handle_mouse_button_event(const MouseButtonEvent& e) {
|
||||
if (e.key == MouseKey::LEFT_BUTTON && e.action == KeyAction::PRESS) {
|
||||
if (is_mouse_enable()) {
|
||||
toggle_mouse_able();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Window::init() {
|
||||
@@ -60,15 +109,18 @@ void Window::init() {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
|
||||
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
|
||||
m_width = m_config.get("window.width", 800);
|
||||
m_height = m_config.get("window.height", 600);
|
||||
|
||||
m_window_width = m_config.get("window.width", 800);
|
||||
m_window_height = m_config.get("window.height", 600);
|
||||
|
||||
if (m_config.get("window.fullscreen", false)) {
|
||||
GLFWmonitor* primary_monitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode* mode = glfwGetVideoMode(primary_monitor);
|
||||
m_window = glfwCreateWindow(mode->width, mode->height, "Cubed",
|
||||
primary_monitor, NULL);
|
||||
} else {
|
||||
m_window = glfwCreateWindow(m_width, m_height, "Cubed", NULL, NULL);
|
||||
m_window = glfwCreateWindow(m_window_width, m_window_height, "Cubed",
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(m_window);
|
||||
@@ -121,12 +173,13 @@ void Window::hot_reload() {
|
||||
Logger::error("Can't Find Monitor");
|
||||
}
|
||||
}
|
||||
update_viewport();
|
||||
if (!m_mouse_enable) {
|
||||
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
} else {
|
||||
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
m_config.set("window.width", windowed_width);
|
||||
m_config.set("window.height", windowed_height);
|
||||
}
|
||||
|
||||
void Window::toggle_fullscreen() {
|
||||
@@ -148,7 +201,8 @@ void Window::toggle_fullscreen() {
|
||||
GL_DONT_CARE);
|
||||
m_config.set("window.fullscreen", true);
|
||||
}
|
||||
update_viewport();
|
||||
m_config.set("window.width", windowed_width);
|
||||
m_config.set("window.height", windowed_height);
|
||||
}
|
||||
|
||||
void Window::toggle_mouse_able() {
|
||||
@@ -166,8 +220,13 @@ void Window::toggle_mouse_able() {
|
||||
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
m_mouse_enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_camera) {
|
||||
m_camera->reset_camera();
|
||||
}
|
||||
}
|
||||
void Window::set_camera(Camera* camera) { m_camera = camera; }
|
||||
Camera* Window::camera() { return m_camera; }
|
||||
void Window::imgui_init() {
|
||||
float dpi_scale_x, dpi_scale_y;
|
||||
glfwGetWindowContentScale(m_window, &dpi_scale_x, &dpi_scale_y);
|
||||
|
||||
Reference in New Issue
Block a user