From 1bee6aed9c7c3861cbeddd50e2378d218be9c690 Mon Sep 17 00:00:00 2001 From: Persson-dev Date: Wed, 16 Jul 2025 12:54:50 +0200 Subject: [PATCH] camera notify --- .gitignore | 4 ++- imgui.ini | 16 ---------- include/td/misc/ObjectNotifier.h | 36 ++++++++++++++++++++++ include/td/render/Camera.h | 11 ++++++- include/td/render/renderer/WorldRenderer.h | 5 ++- src/main.cpp | 5 +-- src/td/render/Camera.cpp | 2 ++ src/td/render/renderer/WorldRenderer.cpp | 14 +++++++-- 8 files changed, 69 insertions(+), 24 deletions(-) delete mode 100644 imgui.ini create mode 100644 include/td/misc/ObjectNotifier.h diff --git a/.gitignore b/.gitignore index fb11540..a08e139 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,6 @@ build/ .DS_Store -.vscode \ No newline at end of file +.vscode + +imgui.ini \ No newline at end of file diff --git a/imgui.ini b/imgui.ini deleted file mode 100644 index c9168d1..0000000 --- a/imgui.ini +++ /dev/null @@ -1,16 +0,0 @@ -[Window][Debug##Default] -Pos=20,60 -Size=400,400 - -[Window][Dear ImGui Demo] -Pos=1116,220 -Size=927,695 - -[Window][Dear ImGui Debug Log] -Pos=60,60 -Size=670,354 - -[Window][Example: Console] -Pos=958,210 -Size=520,600 - diff --git a/include/td/misc/ObjectNotifier.h b/include/td/misc/ObjectNotifier.h new file mode 100644 index 0000000..83e076d --- /dev/null +++ b/include/td/misc/ObjectNotifier.h @@ -0,0 +1,36 @@ +#pragma once + +#include +#include +#include + +namespace td { +namespace utils { + +template +class ObjectNotifier { +protected: + std::vector m_Listeners; + +public: + void BindListener(Listener* listener) { + m_Listeners.push_back(listener); + } + + void UnbindListener(Listener* listener) { + auto iter = std::find(m_Listeners.begin(), m_Listeners.end(), listener); + + if (iter == m_Listeners.end()) return; + + m_Listeners.erase(iter); + } + + template + void NotifyListeners(Func function, Args... args) { + for (Listener* listener : m_Listeners) + std::bind(function, listener, args...)(); + } +}; + +} // namespace utils +} // namespace td diff --git a/include/td/render/Camera.h b/include/td/render/Camera.h index 1f621a1..6cd1907 100644 --- a/include/td/render/Camera.h +++ b/include/td/render/Camera.h @@ -1,11 +1,20 @@ #pragma once #include +#include namespace td { namespace render { -class Camera { +class ICameraListener { + public: + virtual void OnPerspectiveChange() {} + virtual void OnViewChange() {} +}; + +using CameraNotifier = utils::ObjectNotifier; + +class Camera : public CameraNotifier { private: Mat4f m_ViewMatrix; Mat4f m_ProjectionMatrix; diff --git a/include/td/render/renderer/WorldRenderer.h b/include/td/render/renderer/WorldRenderer.h index 61fd3c2..f57662d 100644 --- a/include/td/render/renderer/WorldRenderer.h +++ b/include/td/render/renderer/WorldRenderer.h @@ -8,7 +8,7 @@ namespace td { namespace render { -class WorldRenderer : public Renderer { +class WorldRenderer : public Renderer, public ICameraListener { private: const game::World& m_World; shader::WorldShader m_Shader; @@ -19,6 +19,9 @@ class WorldRenderer : public Renderer { virtual ~WorldRenderer(); virtual void Render() override; + + virtual void OnPerspectiveChange() override; + virtual void OnViewChange() override; }; } // namespace render diff --git a/src/main.cpp b/src/main.cpp index 5dd40b2..ac43d5b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -194,12 +194,13 @@ int main(int argc, char** argv) { td::Display display(1920, 1080, "Tower-Defense 2"); td::render::Camera cam; - cam.SetCamPos({77, 25, 13}); - cam.UpdatePerspective(display.GetAspectRatio()); td::render::RenderPipeline renderer; renderer.AddRenderer(std::make_unique(cam, w)); + cam.SetCamPos({77, 25, 13}); + cam.UpdatePerspective(display.GetAspectRatio()); + while (!display.IsCloseRequested()) { display.PollEvents(); renderer.Render(); diff --git a/src/td/render/Camera.cpp b/src/td/render/Camera.cpp index e1bfe19..0d2a567 100644 --- a/src/td/render/Camera.cpp +++ b/src/td/render/Camera.cpp @@ -8,6 +8,7 @@ namespace render { void Camera::UpdatePerspective(float a_AspectRatio) { m_ProjectionMatrix = maths::Perspective(80.0f / 180.0f * PI, a_AspectRatio, 0.1f, 160.0f); m_InvProjectionMatrix = maths::Inverse(m_ProjectionMatrix); + NotifyListeners(&ICameraListener::OnPerspectiveChange); } void Camera::SetCamPos(const Vec3f& a_NewPos) { @@ -20,6 +21,7 @@ void Camera::SetCamPos(const Vec3f& a_NewPos) { m_CamPos = a_NewPos; m_ViewMatrix = maths::Look(m_CamPos, front, { 0, 1, 0 }); m_InvViewMatrix = maths::Transpose(maths::Inverse(m_ViewMatrix)); // why transpose ? I don't know + NotifyListeners(&ICameraListener::OnViewChange); } } // namespace render diff --git a/src/td/render/renderer/WorldRenderer.cpp b/src/td/render/renderer/WorldRenderer.cpp index 998c02a..f9b55f7 100644 --- a/src/td/render/renderer/WorldRenderer.cpp +++ b/src/td/render/renderer/WorldRenderer.cpp @@ -7,20 +7,28 @@ namespace td { namespace render { -WorldRenderer::WorldRenderer(Camera& a_Camera, const game::World& a_World) : Renderer(a_Camera), m_World(a_World){ +WorldRenderer::WorldRenderer(Camera& a_Camera, const game::World& a_World) : Renderer(a_Camera), m_World(a_World) { m_WorldVao = std::make_unique(std::move(WorldLoader::LoadWorldModel(&a_World))); + a_Camera.BindListener(this); } WorldRenderer::~WorldRenderer() {} void WorldRenderer::Render() { m_Shader.Start(); - m_Shader.SetProjectionMatrix(m_Camera.GetProjectionMatrix()); - m_Shader.SetViewMatrix(m_Camera.GetViewMatrix()); Renderer::Render(*m_WorldVao); ImGui::ShowDemoWindow(); } +void WorldRenderer::OnPerspectiveChange() { + m_Shader.Start(); + m_Shader.SetProjectionMatrix(m_Camera.GetProjectionMatrix()); +} + +void WorldRenderer::OnViewChange() { + m_Shader.Start(); + m_Shader.SetViewMatrix(m_Camera.GetViewMatrix()); +} } // namespace render } // namespace td