diff --git a/CMakeLists.txt b/CMakeLists.txt index 408ca6f..2237434 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,16 +46,19 @@ set(INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include) add_executable(${PROJECT_NAME} src/main.cpp + src/app.cpp src/camera.cpp src/gameplay/chunk.cpp src/gameplay/player.cpp src/gameplay/world.cpp src/input.cpp src/map_table.cpp + src/renderer.cpp src/texture_manager.cpp src/tools/math_tools.cpp src/tools/shader_tools.cpp src/tools/log.cpp + src/window.cpp ) #if(CMAKE_BUILD_TYPE STREQUAL "Debug") diff --git a/include/Cubed/app.hpp b/include/Cubed/app.hpp new file mode 100644 index 0000000..464cd70 --- /dev/null +++ b/include/Cubed/app.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +class App { +public: + App(); + ~App(); + static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos); + static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); + static void mouse_button_callback(GLFWwindow* window, int button, int action, int mods); + static void window_reshape_callback(GLFWwindow* window, int new_width, int new_height); + static int start_cubed_application(int argc, char** argv); + + +private: + Camera m_camera; + World m_world; + Renderer m_renderer{m_camera, m_world}; + + Window m_window{m_renderer}; + + + GLuint m_texture_array; + + TextureManager m_texture_manager; + + + void init(); + + auto init_camera(); + auto init_texture(); + auto init_world(); + + void render(); + void run(); + void update(); +}; \ No newline at end of file diff --git a/include/Cubed/config.hpp b/include/Cubed/config.hpp index c991874..e621bc8 100644 --- a/include/Cubed/config.hpp +++ b/include/Cubed/config.hpp @@ -3,10 +3,14 @@ constexpr int WORLD_SIZE_X = 32; constexpr int WORLD_SIZE_Z = 32; constexpr int WORLD_SIZE_Y = 16; constexpr int MAX_BLOCK_NUM = 2; + + constexpr int CHUCK_SIZE = 16; constexpr int DISTANCE = 8; constexpr int MAX_BLOCK_STATUS = 1; + constexpr float FOV = 70.0f; + constexpr float VERTICES_POS[6][6][3] = { // ===== front (z = +1) ===== 0.0f, 0.0f, 1.0f, // bottom left diff --git a/include/Cubed/input.hpp b/include/Cubed/input.hpp index fe20a85..7f42889 100644 --- a/include/Cubed/input.hpp +++ b/include/Cubed/input.hpp @@ -1,5 +1,7 @@ #pragma once +#include + struct MoveState { bool forward = false; bool back = false; @@ -21,4 +23,6 @@ struct InputState { namespace Input { InputState& get_input_state(); + + } \ No newline at end of file diff --git a/include/Cubed/renderer.hpp b/include/Cubed/renderer.hpp new file mode 100644 index 0000000..6198806 --- /dev/null +++ b/include/Cubed/renderer.hpp @@ -0,0 +1,39 @@ +#pragma once +#include +#include +#include + +class Camera; +class World; +class Renderer { +public: + constexpr static int NUM_VAO = 1; + + Renderer(const Camera& camera, World& world); + ~Renderer(); + void init(); + void render(GLuint texture_array); + void update_proj_matrix(float aspect); +private: + + const Camera& m_camera; + World& m_world; + + glm::mat4 m_p_mat, m_v_mat, m_m_mat, m_mv_mat, m_mvp_mat; + + GLuint m_mv_loc; + GLuint m_proj_loc; + + GLuint m_sky_vbo; + GLuint m_outline_indices_vbo; + GLuint m_outline_vbo; + + GLuint m_sky_program; + GLuint m_outline_program; + GLuint m_world_program; + + std::vector m_vao; + + void render_outline(); + void render_sky(); +}; \ No newline at end of file diff --git a/include/Cubed/tools/cubed_assert.hpp b/include/Cubed/tools/cubed_assert.hpp index d76acca..98a0af8 100644 --- a/include/Cubed/tools/cubed_assert.hpp +++ b/include/Cubed/tools/cubed_assert.hpp @@ -3,12 +3,12 @@ namespace Assert { inline void msg(const char* condition, const char* file, int line, const char* func, - const std::string& message = "" + std::string_view message = "" ) { LOG::error("Assertion failed: {} at {}: {} in function {}", condition, file, line, func); - if (!message.empty()) { + if (message.size()) { LOG::error("Message: {}", message); } std::abort(); diff --git a/include/Cubed/window.hpp b/include/Cubed/window.hpp new file mode 100644 index 0000000..e387f12 --- /dev/null +++ b/include/Cubed/window.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +class Renderer; +class Window { +public: + Window(Renderer& renderer); + ~Window(); + + const GLFWwindow* get_glfw_window() const; + GLFWwindow* get_glfw_window(); + void init(); + void update_viewport(); + +private: + float m_aspect; + GLFWwindow* m_window; + int m_width; + int m_height; + Renderer& m_renderer; + +}; \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp new file mode 100644 index 0000000..8fdd7ac --- /dev/null +++ b/src/app.cpp @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include + +#include + +static double last_time = glfwGetTime(); +static double current_time = glfwGetTime(); +static double delta_time = 0.0f; +static double fps_time_count = 0.0f; +static int frame_count = 0; +static int fps; + +App::App() { + +} + +App::~App() { + +} +void App::cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { + App* app = static_cast(glfwGetWindowUserPointer(window)); + CUBED_ASSERT_MSG(app, "nullptr"); + app->m_camera.update_cursor_position_camera(xpos, ypos); +} +void App::init() { + m_window.init(); + glfwSetWindowUserPointer(m_window.get_glfw_window(), this); + + glfwSetWindowSizeCallback(m_window.get_glfw_window(), window_reshape_callback); + glfwSetKeyCallback(m_window.get_glfw_window(), key_callback); + glfwSetCursorPosCallback(m_window.get_glfw_window(), cursor_position_callback); + glfwSetMouseButtonCallback(m_window.get_glfw_window(), mouse_button_callback); + + m_renderer.init(); + m_window.update_viewport(); + MapTable::init_map(); + m_texture_manager.init_texture(); + m_world.init_world(); + m_texture_array = m_texture_manager.get_texture_array(); + m_camera.camera_init(&m_world.get_player("TestPlayer")); + +} + +void App::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { + switch(key) { + case GLFW_KEY_Q: + if (action == GLFW_PRESS) { + + if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } else if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL) { + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + } + break; + case GLFW_KEY_ESCAPE: + if (action == GLFW_PRESS) { + glfwSetWindowShouldClose(window, GLFW_TRUE); + } + + } + App* app = static_cast(glfwGetWindowUserPointer(window)); + CUBED_ASSERT_MSG(app, "nullptr"); + app->m_world.get_player("TestPlayer").update_player_move_state(key, action); +} + +void App::mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { + switch (button) { + case GLFW_MOUSE_BUTTON_LEFT: + if (action == GLFW_PRESS) { + Input::get_input_state().mouse_state.left = true; + } + if (action == GLFW_RELEASE) { + Input::get_input_state().mouse_state.left = false; + } + 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; + } + break; + } +} + +void App::window_reshape_callback(GLFWwindow* window, int new_width, int new_height) { + App* app = static_cast(glfwGetWindowUserPointer(window)); + CUBED_ASSERT_MSG(app, "nullptr"); + app->m_window.update_viewport(); +} + + + +void App::render() { + + m_renderer.render(m_texture_array); + + glfwSwapBuffers(m_window.get_glfw_window()); + +} + +void App::run() { + + while(!glfwWindowShouldClose(m_window.get_glfw_window())) { + + update(); + render(); + + } +} + +void App::update() { + glfwPollEvents(); + current_time = glfwGetTime(); + delta_time = current_time - last_time; + last_time = current_time; + fps_time_count += delta_time; + frame_count++; + if (fps_time_count >= 1.0f) { + fps = static_cast(frame_count / fps_time_count); + std::string title = "Cubed FPS: " + std::to_string(fps); + glfwSetWindowTitle(m_window.get_glfw_window(), title.c_str()); + frame_count = 0; + fps_time_count = 0.0f; + } + m_world.update(delta_time); + m_camera.update_move_camera(); + + +} + +int App::start_cubed_application(int argc, char** argv) { + + App app; + + try { + + app.init(); + app.run(); + + return 0; + } catch (std::exception& e) { + LOG::error("{}", e.what()); + + } catch (...) { + LOG::error("Unkown error"); + + } + return 1; +} \ No newline at end of file diff --git a/src/input.cpp b/src/input.cpp index 3fd33f0..3edfe69 100644 --- a/src/input.cpp +++ b/src/input.cpp @@ -1,9 +1,19 @@ #include - +#include static InputState input_state; namespace Input { + + + + InputState& get_input_state() { return input_state; } + + + + + + } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a527bfe..4aed757 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,289 +1,7 @@ -#include +#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -constexpr int NUM_VAO = 1; - -GLuint world_program, outline_program, sky_program; -GLuint vao[NUM_VAO]; -GLuint mv_loc, proj_loc; -int width ,height; -float aspect; -glm::mat4 p_mat, v_mat, m_mat, mv_mat, mvp_mat; -float inc = 0.01f; -float tf = 0.0f; -double last_time = glfwGetTime(); -double delta_time = 0.0f; -double fps_time_count = 0.0f; -int frame_count = 0; -int fps; -GLuint texture_array; -Camera camera; -TextureManager texture_manager; -World world; - -GLuint outline_vbo, outline_indices_vbo, sky_vbo; - - - -void setup_vertices(void) { - - glGenVertexArrays(NUM_VAO, vao); - glBindVertexArray(vao[0]); - glBindVertexArray(0); - glGenBuffers(1, &outline_vbo); - - glBindBuffer(GL_ARRAY_BUFFER, outline_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VER), CUBE_VER, GL_STATIC_DRAW); - - glGenBuffers(1, &outline_indices_vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, outline_indices_vbo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(OUTLINE_CUBE_INDICES), OUTLINE_CUBE_INDICES, GL_STATIC_DRAW); - - glGenBuffers(1, &sky_vbo); - glBindBuffer(GL_ARRAY_BUFFER, sky_vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_POS), VERTICES_POS, GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - - - -void init(GLFWwindow* window) { - world_program = Shader::create_shader_program("shaders/block_v_shader.glsl", "shaders/block_f_shader.glsl"); - outline_program = Shader::create_shader_program("shaders/outline_v_shader.glsl", "shaders/outline_f_shader.glsl"); - sky_program = Shader::create_shader_program("shaders/sky_v_shader.glsl", "shaders/sky_f_shader.glsl"); - - camera.camera_init(&world.get_player("TestPlayer")); - glfwGetFramebufferSize(window, &width, &height); - aspect = (float)width / (float)height; - glViewport(0, 0, width, height); - p_mat = glm::perspective(glm::radians(FOV), aspect, 0.1f, 1000.0f); - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - - #ifndef NDEBUG - glEnable(GL_DEBUG_OUTPUT); - glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* user_param) { - LOG::info("GL Debug: {}", reinterpret_cast(message)); - }, nullptr); - #endif - - setup_vertices(); - -} - -void window_reshape_callback(GLFWwindow* window, int new_width, int new_height) { - glfwGetFramebufferSize(window, &width, &height); - aspect = (float)width / (float)height; - glViewport(0, 0, width, height); - p_mat = glm::perspective(glm::radians(60.0f), aspect, 0.1f, 1000.0f); -} - - - - -void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) { - camera.update_cursor_position_camera(xpos, ypos); -} - -void render_outline() { - glUseProgram(outline_program); - - mv_loc = glGetUniformLocation(outline_program, "mv_matrix"); - proj_loc = glGetUniformLocation(outline_program, "proj_matrix"); - const auto& block_pos = world.get_look_block_pos("TestPlayer"); - if (block_pos != std::nullopt) { - m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(block_pos.value().pos)); - mv_mat = v_mat * m_mat; - glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_mat)); - glUniformMatrix4fv(proj_loc, 1 ,GL_FALSE, glm::value_ptr(p_mat)); - - glBindBuffer(GL_ARRAY_BUFFER, outline_vbo); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, outline_indices_vbo); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glLineWidth(4.0f); - glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); - } - -} - -void render_sky() { - glUseProgram(sky_program); - - mv_loc = glGetUniformLocation(sky_program, "mv_matrix"); - proj_loc = glGetUniformLocation(sky_program, "proj_matrix"); - - m_mat = glm::translate(glm::mat4(1.0f), camera.get_camera_pos() - glm::vec3(0.5f, 0.5f, 0.5f)); - v_mat = camera.get_camera_lookat(); - mv_mat = v_mat * m_mat; - - glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_mat)); - glUniformMatrix4fv(proj_loc, 1 ,GL_FALSE, glm::value_ptr(p_mat)); - - glBindBuffer(GL_ARRAY_BUFFER, sky_vbo); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); - - glDisable(GL_DEPTH_TEST); - glDrawArrays(GL_TRIANGLES, 0, 36); - glEnable(GL_DEPTH_TEST); - -} - -void display(GLFWwindow* window, double current_time) { - delta_time = current_time - last_time; - last_time = current_time; - fps_time_count += delta_time; - frame_count++; - if (fps_time_count >= 1.0f) { - fps = static_cast(frame_count / fps_time_count); - std::string title = "Cubed FPS: " + std::to_string(fps); - glfwSetWindowTitle(window, title.c_str()); - frame_count = 0; - fps_time_count = 0.0f; - } - world.update(delta_time); - camera.update_move_camera(); - - - glClearColor(0.0, 0.0, 0.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT); - glClear(GL_DEPTH_BUFFER_BIT); - glBindVertexArray(vao[0]); - render_sky(); - glUseProgram(world_program); - - mv_loc = glGetUniformLocation(world_program, "mv_matrix"); - proj_loc = glGetUniformLocation(world_program, "proj_matrix"); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array); - m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); - v_mat = camera.get_camera_lookat(); - mv_mat = v_mat * m_mat; - glUniformMatrix4fv(mv_loc, 1, GL_FALSE, glm::value_ptr(mv_mat)); - glUniformMatrix4fv(proj_loc, 1 ,GL_FALSE, glm::value_ptr(p_mat)); - mvp_mat = p_mat * mv_mat; - world.render(mvp_mat); - - render_outline(); - - - -} - -void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { - switch(key) { - case GLFW_KEY_Q: - if (action == GLFW_PRESS) { - - if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); - } else if (glfwGetInputMode(window, GLFW_CURSOR) == GLFW_CURSOR_NORMAL) { - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - } - } - break; - case GLFW_KEY_ESCAPE: - if (action == GLFW_PRESS) { - glfwSetWindowShouldClose(window, GLFW_TRUE); - } - - } - - world.get_player("TestPlayer").update_player_move_state(key, action); -} - -void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) { - switch (button) { - case GLFW_MOUSE_BUTTON_LEFT: - if (action == GLFW_PRESS) { - Input::get_input_state().mouse_state.left = true; - } - if (action == GLFW_RELEASE) { - Input::get_input_state().mouse_state.left = false; - } - 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; - } - break; - } -} - -int main() { - if (!glfwInit()) { - LOG::error("glfwinit fail"); - exit(EXIT_FAILURE); - } - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - GLFWwindow* window = glfwCreateWindow(800, 600, "Cubed", NULL, NULL); - glfwMakeContextCurrent(window); - - if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { - LOG::error("Failed to initialize glad"); - return -1; - } - - LOG::info("OpenGL Version: {}.{}", GLVersion.major, GLVersion.minor); - LOG::info("Renderer: {}", reinterpret_cast(glGetString(GL_RENDERER))); - - glfwSwapInterval(1); - glfwSetWindowSizeCallback(window, window_reshape_callback); - glfwSetKeyCallback(window, key_callback); - - glfwSetCursorPosCallback(window, cursor_position_callback); - glfwSetMouseButtonCallback(window, mouse_button_callback); - MapTable::init_map(); - texture_manager.init_texture(); - world.init_world(); - texture_array = texture_manager.get_texture_array(); - init(window); - - glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); - - while(!glfwWindowShouldClose(window)) { - display(window, glfwGetTime()); - glfwSwapBuffers(window); - glfwPollEvents(); - } - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &outline_vbo); - glDeleteBuffers(1, &outline_indices_vbo); - glDeleteBuffers(1, &sky_vbo); - glBindVertexArray(0); - glDeleteVertexArrays(NUM_VAO, vao); - glDeleteProgram(world_program); - glDeleteProgram(outline_program); - glDeleteProgram(sky_program); - glfwDestroyWindow(window); - glfwTerminate(); - exit(EXIT_SUCCESS); +int main(int argc, char** argv) { + return App::start_cubed_application(argc, argv); } diff --git a/src/renderer.cpp b/src/renderer.cpp new file mode 100644 index 0000000..0cd60ec --- /dev/null +++ b/src/renderer.cpp @@ -0,0 +1,155 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +Renderer::Renderer(const Camera& camera, World& world): + m_camera(camera), + m_world(world) +{ + +} + +Renderer::~Renderer() { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDeleteBuffers(1, &m_outline_vbo); + glDeleteBuffers(1, &m_outline_indices_vbo); + glDeleteBuffers(1, &m_sky_vbo); + glBindVertexArray(0); + glDeleteVertexArrays(NUM_VAO, m_vao.data()); + glDeleteProgram(m_world_program); + glDeleteProgram(m_outline_program); + glDeleteProgram(m_sky_program); +} + + + +void Renderer::init() { + if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { + LOG::error("Failed to initialize glad"); + exit(EXIT_FAILURE); + } + LOG::info("OpenGL Version: {}.{}", GLVersion.major, GLVersion.minor); + LOG::info("Renderer: {}", reinterpret_cast(glGetString(GL_RENDERER))); + + m_world_program = Shader::create_shader_program("shaders/block_v_shader.glsl", "shaders/block_f_shader.glsl"); + m_outline_program = Shader::create_shader_program("shaders/outline_v_shader.glsl", "shaders/outline_f_shader.glsl"); + m_sky_program = Shader::create_shader_program("shaders/sky_v_shader.glsl", "shaders/sky_f_shader.glsl"); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + + #ifndef NDEBUG + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback([](GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* user_param) { + LOG::info("GL Debug: {}", reinterpret_cast(message)); + }, nullptr); + #endif + + + m_vao.resize(NUM_VAO); + glGenVertexArrays(NUM_VAO, m_vao.data()); + glBindVertexArray(m_vao[0]); + glBindVertexArray(0); + glGenBuffers(1, &m_outline_vbo); + + glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(CUBE_VER), CUBE_VER, GL_STATIC_DRAW); + + glGenBuffers(1, &m_outline_indices_vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(OUTLINE_CUBE_INDICES), OUTLINE_CUBE_INDICES, GL_STATIC_DRAW); + + glGenBuffers(1, &m_sky_vbo); + glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo); + glBufferData(GL_ARRAY_BUFFER, sizeof(VERTICES_POS), VERTICES_POS, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + + + +} + +void Renderer::render(GLuint texture_array) { + glClearColor(0.0, 0.0, 0.0, 1.0); + glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); + glBindVertexArray(m_vao[0]); + render_sky(); + glUseProgram(m_world_program); + + m_mv_loc = glGetUniformLocation(m_world_program, "mv_matrix"); + m_proj_loc = glGetUniformLocation(m_world_program, "proj_matrix"); + glActiveTexture(GL_TEXTURE0); + + glBindTexture(GL_TEXTURE_2D_ARRAY, texture_array); + m_m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.0f)); + m_v_mat = m_camera.get_camera_lookat(); + m_mv_mat = m_v_mat * m_m_mat; + glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); + glUniformMatrix4fv(m_proj_loc, 1 ,GL_FALSE, glm::value_ptr(m_p_mat)); + m_mvp_mat = m_p_mat * m_mv_mat; + m_world.render(m_mvp_mat); + + render_outline(); +} + +void Renderer::render_outline() { + glUseProgram(m_outline_program); + + m_mv_loc = glGetUniformLocation(m_outline_program, "mv_matrix"); + m_proj_loc = glGetUniformLocation(m_outline_program, "proj_matrix"); + + const auto& block_pos = m_world.get_look_block_pos("TestPlayer"); + + if (block_pos != std::nullopt) { + m_m_mat = glm::translate(glm::mat4(1.0f), glm::vec3(block_pos.value().pos)); + m_mv_mat = m_v_mat * m_m_mat; + glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); + glUniformMatrix4fv(m_proj_loc, 1 ,GL_FALSE, glm::value_ptr(m_p_mat)); + + glBindBuffer(GL_ARRAY_BUFFER, m_outline_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_outline_indices_vbo); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glLineWidth(4.0f); + glDrawElements(GL_LINES, 24, GL_UNSIGNED_INT, 0); + } + +} + +void Renderer::render_sky() { + glUseProgram(m_sky_program); + + m_mv_loc = glGetUniformLocation(m_sky_program, "mv_matrix"); + m_proj_loc = glGetUniformLocation(m_sky_program, "proj_matrix"); + + m_m_mat = glm::translate(glm::mat4(1.0f), m_camera.get_camera_pos() - glm::vec3(0.5f, 0.5f, 0.5f)); + m_v_mat = m_camera.get_camera_lookat(); + m_mv_mat = m_v_mat * m_m_mat; + + glUniformMatrix4fv(m_mv_loc, 1, GL_FALSE, glm::value_ptr(m_mv_mat)); + glUniformMatrix4fv(m_proj_loc, 1 ,GL_FALSE, glm::value_ptr(m_p_mat)); + + glBindBuffer(GL_ARRAY_BUFFER, m_sky_vbo); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glDisable(GL_DEPTH_TEST); + glDrawArrays(GL_TRIANGLES, 0, 36); + glEnable(GL_DEPTH_TEST); + +} + +void Renderer::update_proj_matrix(float aspect) { + m_p_mat = glm::perspective(glm::radians(FOV), aspect, 0.1f, 1000.0f); +} \ No newline at end of file diff --git a/src/window.cpp b/src/window.cpp new file mode 100644 index 0000000..bfb4fcc --- /dev/null +++ b/src/window.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +Window::Window(Renderer& renderer) : + m_renderer(renderer) +{ + +} + +Window::~Window() { + glfwDestroyWindow(m_window); + glfwTerminate(); +} + +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); + +} + +void Window::init() { + if (!glfwInit()) { + LOG::error("glfwinit fail"); + exit(EXIT_FAILURE); + } + + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); + m_window = glfwCreateWindow(800, 600, "Cubed", NULL, NULL); + glfwMakeContextCurrent(m_window); + + glfwSwapInterval(1); + + + glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + + //update_viewport(); + +} \ No newline at end of file