From b1d693dbd4cc8a0c3a4e467df59e8758cdf54e00 Mon Sep 17 00:00:00 2001 From: Andrey Zimin Date: Wed, 15 May 2024 10:57:21 +0300 Subject: [PATCH] add opengl --- bin/layers/opengl_panel/opengl_panel.cpp | 61 +++++++++------- bin/layers/opengl_panel/opengl_panel.hpp | 70 ++++++++++++++++++- bin/layers/opengl_panel/shaders/vertes.shader | 3 +- src/application/application.cpp | 11 +-- src/application/application.hpp | 2 + src/glfw/glfw.cpp | 15 +++- src/glfw/glfw.hpp | 1 + src/utils/include.hpp | 1 + src/utils/math.hpp | 10 +-- 9 files changed, 130 insertions(+), 44 deletions(-) diff --git a/bin/layers/opengl_panel/opengl_panel.cpp b/bin/layers/opengl_panel/opengl_panel.cpp index 44d9081..07b6b72 100755 --- a/bin/layers/opengl_panel/opengl_panel.cpp +++ b/bin/layers/opengl_panel/opengl_panel.cpp @@ -55,46 +55,53 @@ namespace sandbox void opengl_panel::render() { - // glm::mat4 view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp); - // glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f); - - cb_1.use(); - // unsigned int viewLoc = glGetUniformLocation(cb_1.get_id(), "view"); - // glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view)); - // unsigned int projLoc = glGetUniformLocation(cb_1.get_id(), "projection"); - // glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection)); + m_cb_1.use(); + m_cam.update(m_cb_1); float r = std::sin(glfwGetTime()); float g = std::cos(glfwGetTime()); - cb_1.set_color(glm::vec4{ 0.85f, 0.45f, 0.95f, 0.f }); // розовый - cb_1.set_scale(1.0f + std::sin(glfwGetTime()) * 0.2f); - cb_1.set_position(glm::vec3{ 0.f, 0.5, 0.f }); - cb_1.render(); + m_cb_1.set_color(glm::vec4{ 0.85f, 0.45f, 0.95f, 0.f }); // розовый + m_cb_1.set_scale(1.0f + std::sin(glfwGetTime()) * 0.2f); + m_cb_1.set_position(glm::vec3{ 0.f, 0.5, 0.f }); + m_cb_1.render(); r = std::cos(glfwGetTime()); g = std::sin(glfwGetTime()); - cb_2.use(); + m_cb_2.use(); - // unsigned int viewLoc_1 = glGetUniformLocation(cb_2.get_id(), "view"); - // glUniformMatrix4fv(viewLoc_1, 1, GL_FALSE, glm::value_ptr(view)); - // unsigned int projLoc_1 = glGetUniformLocation(cb_2.get_id(), "projection"); - // glUniformMatrix4fv(projLoc_1, 1, GL_FALSE, glm::value_ptr(projection)); + m_cam.update(m_cb_2); - cb_2.set_color(glm::vec4{ 0.66f, 0.66f, 0.66f, 0.f }); // серый/белый - cb_2.set_scale(1.0f - std::cos(glfwGetTime()) * 0.2f); - cb_2.set_position(glm::vec3{ r, g, 0.f }); - cb_2.render(); + m_cb_2.set_color(glm::vec4{ 0.66f, 0.66f, 0.66f, 0.f }); // серый/белый + m_cb_2.set_scale(1.0f - std::cos(glfwGetTime()) * 0.2f); + m_cb_2.set_position(glm::vec3{ r, g, 0.f }); + m_cb_2.render(); } void opengl_panel::on_event(VE::event e) { // для событий от перефирии - // if (e.m_type.type() == typeid(VE::event_type)) - // { - // auto t = std::any_cast(e.m_type); - // if (t != VE::event_type::MOUSE_CURSOR_POSITION) - // hack::log()((int)t); - // } + if (e.m_type.type() == typeid(VE::event_type)) + { + auto t = std::any_cast(e.m_type); + if (t == VE::event_type::MOUSE_CURSOR_POSITION) + { + auto [pos_x, pos_y] = std::any_cast>(e.m_data); + m_cam.mouse_callback(pos_x, pos_y); + } + + if (t == VE::event_type::KEY_REPEATE || t == VE::event_type::KEY_PRESSED) + { + auto key = std::any_cast(e.m_data); + if (key == VE::key::W) + m_cam.up(); + if (key == VE::key::S) + m_cam.down(); + if (key == VE::key::A) + m_cam.left(); + if (key == VE::key::D) + m_cam.right(); + } + } if (e.m_type.type() == typeid(test_event)) { diff --git a/bin/layers/opengl_panel/opengl_panel.hpp b/bin/layers/opengl_panel/opengl_panel.hpp index ae3cb03..da2b875 100755 --- a/bin/layers/opengl_panel/opengl_panel.hpp +++ b/bin/layers/opengl_panel/opengl_panel.hpp @@ -19,12 +19,78 @@ namespace sandbox void render(); }; + struct camera + { + // Начальное положение камеры + mt::vec3 m_pos = mt::vec3{ 0.0f, 0.0f, 3.0f }; + mt::vec3 m_front = mt::vec3{ 0.0f, 0.0f, -1.0f }; + mt::vec3 m_up = mt::vec3{ 0.0f, 1.0f, 0.0f }; + float m_speed = 0.05f; + + glm::mat4 m_view, m_projection; + + void up() { m_pos += m_speed * m_front; } + void down() { m_pos -= m_speed * m_front; } + void left() { m_pos -= mt::normalize(mt::cross(m_front, m_up)) * m_speed; } + void right() { m_pos += mt::normalize(mt::cross(m_front, m_up)) * m_speed; } + + template + void update(const T& obj) + { + m_view = glm::lookAt(m_pos, m_pos + m_front, m_up); + m_projection = glm::perspective(glm::radians(45.0f), + static_cast(VE::application::get()->get_glfw()->width()) / VE::application::get()->get_glfw()->height(), + 0.1f, 100.0f); + + glUniformMatrix4fv(glGetUniformLocation(obj.get_id(), "view"), 1, GL_FALSE, mt::value_ptr(m_view)); + glUniformMatrix4fv(glGetUniformLocation(obj.get_id(), "projection"), 1, GL_FALSE, glm::value_ptr(m_projection)); + } + + // Управление камерой через мышь + bool m_first = true; + float m_yaw = -90.0f; + float m_pitch = 0.0f; + float m_last_x = 400, m_last_y = 300; + + void mouse_callback(double xpos, double ypos) + { + if (m_first) + { + m_last_x = xpos; + m_last_y = ypos; + m_first = false; + } + + float x_offset = xpos - m_last_x; + float y_offset = m_last_y - ypos; + m_last_x = xpos; + m_last_y = ypos; + + float sensitivity = 0.1f; + x_offset *= sensitivity; + y_offset *= sensitivity; + + m_yaw += x_offset; + m_pitch += y_offset; + + if (m_pitch > 89.0f) m_pitch = 89.0f; + if (m_pitch < -89.0f) m_pitch = -89.0f; + + mt::vec3 front; + front.x = std::cos(mt::radians(m_yaw)) * std::cos(mt::radians(m_pitch)); + front.y = std::sin(mt::radians(m_pitch)); + front.z = std::sin(mt::radians(m_yaw)) * std::cos(mt::radians(m_pitch)); + m_front = mt::normalize(front); + } + }; + class opengl_panel : public VE::layer { VE_FN_OVERIDE(); - cube cb_1; - cube cb_2; + cube m_cb_1; + cube m_cb_2; + camera m_cam; }; } diff --git a/bin/layers/opengl_panel/shaders/vertes.shader b/bin/layers/opengl_panel/shaders/vertes.shader index 0bfb648..09a6e3f 100644 --- a/bin/layers/opengl_panel/shaders/vertes.shader +++ b/bin/layers/opengl_panel/shaders/vertes.shader @@ -15,8 +15,7 @@ out vec4 v_color; void main() { vec3 p = base_position + position * scale ; - // gl_Position = projection * view * vec4(p, 1.0); - gl_Position = vec4(p, 1.0); + gl_Position = projection * view * vec4(p, 1.0); v_color = color; } diff --git a/src/application/application.cpp b/src/application/application.cpp index d1a3091..9103e3a 100755 --- a/src/application/application.cpp +++ b/src/application/application.cpp @@ -6,6 +6,8 @@ namespace VE { application::application(std::string app_name) : m_glfw{ std::make_unique() } { + m_instance = std::unique_ptr(this); + m_glfw->init(app_name); m_glfw->set_event_fn(VE_EVENT_FN); @@ -14,10 +16,6 @@ namespace VE void application::run() { - glEnable(GL_DEPTH_TEST); - glClearColor(0.07f, 0.13f, 0.17f, 1.0f); - glViewport(0, 0, m_glfw->width(), m_glfw->height()); - while(!glfwWindowShouldClose(m_glfw->get_win())) { m_glfw->clear(); @@ -35,6 +33,11 @@ namespace VE return m_glfw; } + std::unique_ptr& application::get() + { + return m_instance; + } + void application::attach_layers() { for (auto l : m_layers_stack) l->on_attach(); diff --git a/src/application/application.hpp b/src/application/application.hpp index 16b8f93..d6ed44b 100755 --- a/src/application/application.hpp +++ b/src/application/application.hpp @@ -16,9 +16,11 @@ namespace VE std::unique_ptr m_glfw; std::unique_ptr m_gui; layers_stack m_layers_stack; + inline static std::unique_ptr m_instance; public: void run(); + static std::unique_ptr& get(); std::unique_ptr& get_glfw(); public: diff --git a/src/glfw/glfw.cpp b/src/glfw/glfw.cpp index 9a761ff..8bccff0 100755 --- a/src/glfw/glfw.cpp +++ b/src/glfw/glfw.cpp @@ -33,7 +33,7 @@ namespace VE set_key_callback(); set_mouse_callback(); set_window_callback(); - + set_opengl(); } void glfw::set_hint() @@ -122,6 +122,12 @@ namespace VE auto d = static_cast(glfwGetWindowUserPointer(w)); event e{ action, key }; + // HERE + // тут одноврекменно срабатывает только один сигнал + // т.е. если нажада клавиша и удерживается сигнал о повторе идет + // но если нажать одновременно еще, то сигнал о той нажатой пропадает + // нужносамому реализовывать функцию повтора а не полагаться на внутреннюю + // реализацию glfw switch (action) { case GLFW_PRESS: @@ -212,4 +218,11 @@ namespace VE d->execute(e); }); } + + void glfw::set_opengl() + { + glEnable(GL_DEPTH_TEST); + glClearColor(0.07f, 0.13f, 0.17f, 1.0f); + glViewport(0, 0, m_win_data.m_width, m_win_data.m_height); + } } diff --git a/src/glfw/glfw.hpp b/src/glfw/glfw.hpp index 752faf4..a8113ae 100755 --- a/src/glfw/glfw.hpp +++ b/src/glfw/glfw.hpp @@ -50,6 +50,7 @@ namespace VE void set_key_callback(); void set_mouse_callback(); void set_window_callback(); + void set_opengl(); }; } diff --git a/src/utils/include.hpp b/src/utils/include.hpp index 07dc0c6..bdf7368 100755 --- a/src/utils/include.hpp +++ b/src/utils/include.hpp @@ -24,6 +24,7 @@ #include "glad.h" #include "GLFW/glfw3.h" #include "hack/logger/logger.hpp" +#include "hack/utils/singleton.hpp" #include "imgui.h" #include "imgui_impl_glfw.h" #include "imgui_impl_opengl3.h" diff --git a/src/utils/math.hpp b/src/utils/math.hpp index 4ecbc71..38ad75a 100644 --- a/src/utils/math.hpp +++ b/src/utils/math.hpp @@ -4,14 +4,8 @@ namespace mt { - using vec2 = glm::vec2; - using vec3 = glm::vec3; - using vec4 = glm::vec4; - - using mat2 = glm::mat2; - using mat3 = glm::mat3; - using mat4 = glm::mat4; + using namespace glm; template - T convert(glm::vec2& v) { return T{ v.x, v.y }; } + T convert(vec2& v) { return T{ v.x, v.y }; } }