diff --git a/libopenage/gamestate/game.cpp b/libopenage/gamestate/game.cpp index e63499d769..c3d169a52b 100644 --- a/libopenage/gamestate/game.cpp +++ b/libopenage/gamestate/game.cpp @@ -54,6 +54,7 @@ const std::shared_ptr &Game::get_state() const { void Game::attach_renderer(const std::shared_ptr &render_factory) { this->universe->attach_renderer(render_factory); + this->state->get_map()->set_camera_render_entity(render_factory->add_camera_render_entity()); this->state->get_map()->get_terrain()->attach_renderer(render_factory); } diff --git a/libopenage/gamestate/map.cpp b/libopenage/gamestate/map.cpp index 88578fabdb..07e1ffd40c 100644 --- a/libopenage/gamestate/map.cpp +++ b/libopenage/gamestate/map.cpp @@ -5,6 +5,7 @@ #include #include "gamestate/api/terrain.h" +#include "gamestate/definitions.h" #include "gamestate/game_state.h" #include "gamestate/terrain.h" #include "gamestate/terrain_chunk.h" @@ -13,6 +14,7 @@ #include "pathfinding/pathfinder.h" #include "pathfinding/sector.h" +#include "renderer/camera/definitions.h" namespace openage::gamestate { Map::Map(const std::shared_ptr &state, @@ -78,4 +80,22 @@ path::grid_id_t Map::get_grid_id(const nyan::fqon_t &path_grid) const { return this->grid_lookup.at(path_grid); } + +const void Map::set_camera_render_entity(std::shared_ptr renderer_entity, + const std::optional &boundaries, + const time::time_t time) { + this->camera_render_entity = renderer_entity; + this->upadate_camera_render_entity(boundaries, time); +} + +const void Map::upadate_camera_render_entity(const std::optional &boundaries, const time::time_t time) { + if (this->camera_render_entity) { + if (boundaries.has_value()) + this->camera_render_entity->update(boundaries.value(), time); + else + this->camera_render_entity->update(openage::renderer::camera::DEFAULT_CAM_BOUNDARIES, time); // TODO: caluclate bounds, from origin and map size + } +} + + } // namespace openage::gamestate diff --git a/libopenage/gamestate/map.h b/libopenage/gamestate/map.h index 2817f74457..cad9ce9a27 100644 --- a/libopenage/gamestate/map.h +++ b/libopenage/gamestate/map.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include @@ -10,6 +11,9 @@ #include "pathfinding/types.h" #include "util/vector.h" +#include "renderer/render_factory.h" +#include "renderer/stages/camera/render_entity.h" + namespace openage { namespace path { @@ -65,6 +69,12 @@ class Map { */ path::grid_id_t get_grid_id(const nyan::fqon_t &path_grid) const; + const void set_camera_render_entity(std::shared_ptr renderer_entity, + const std::optional &boundaries = std::nullopt, + const time::time_t time = time::TIME_ZERO); + + const void upadate_camera_render_entity(const std::optional &boundaries, const time::time_t time); + private: /** * Terrain. @@ -80,6 +90,8 @@ class Map { * Lookup table for mapping path grid objects in nyan to grid indices. */ std::unordered_map grid_lookup; + + std::shared_ptr camera_render_entity; }; } // namespace gamestate diff --git a/libopenage/renderer/camera/boundaries.cpp b/libopenage/renderer/camera/boundaries.cpp index ca77344c7e..5f7e1178cf 100644 --- a/libopenage/renderer/camera/boundaries.cpp +++ b/libopenage/renderer/camera/boundaries.cpp @@ -1,9 +1,14 @@ // Copyright 2024-2024 the openage authors. See copying.md for legal info. +#include + #include "boundaries.h" namespace openage::renderer::camera { +bool CameraBoundaries::operator==(const CameraBoundaries &rhs) { + return (std::tie(x_min, x_max, y_min, y_max, z_min, z_max) == std::tie(rhs.x_min, rhs.x_max, rhs.y_min, rhs.y_max, rhs.z_min, rhs.z_max)); +} } // namespace openage::renderer::camera diff --git a/libopenage/renderer/camera/boundaries.h b/libopenage/renderer/camera/boundaries.h index 484a398455..4af99ff872 100644 --- a/libopenage/renderer/camera/boundaries.h +++ b/libopenage/renderer/camera/boundaries.h @@ -20,6 +20,8 @@ struct CameraBoundaries { float z_min; /// The maximum boundary for the camera's Z-coordinate. float z_max; + + bool operator==(const CameraBoundaries &rhs); }; } // namespace openage::renderer::camera diff --git a/libopenage/renderer/render_factory.cpp b/libopenage/renderer/render_factory.cpp index 3dee6dd6ae..6b6b5d8c6c 100644 --- a/libopenage/renderer/render_factory.cpp +++ b/libopenage/renderer/render_factory.cpp @@ -3,6 +3,7 @@ #include "render_factory.h" #include "coord/phys.h" +#include "renderer/stages/camera/manager.h" #include "renderer/stages/terrain/render_entity.h" #include "renderer/stages/terrain/render_stage.h" #include "renderer/stages/world/render_entity.h" @@ -30,4 +31,10 @@ std::shared_ptr RenderFactory::add_world_render_entity() { return entity; } +std::shared_ptr RenderFactory::add_camera_render_entity() { + auto entity = std::make_shared(); + this->camera_manager->add_render_entity(entity); + return entity; +} + } // namespace openage::renderer diff --git a/libopenage/renderer/render_factory.h b/libopenage/renderer/render_factory.h index a211e3edf4..10d605ba1d 100644 --- a/libopenage/renderer/render_factory.h +++ b/libopenage/renderer/render_factory.h @@ -19,6 +19,12 @@ class WorldRenderStage; class RenderEntity; } // namespace world +namespace camera { +class CameraManager; +class RenderEntity; +} // namespace camera + + /** * Creates render entities that push animation updates from the * engine to the renderer. Also registers the render entities with @@ -57,6 +63,10 @@ class RenderFactory { */ std::shared_ptr add_world_render_entity(); + + std::shared_ptr add_camera_render_entity(); + + private: /** * Render stage for terrain drawing. @@ -67,6 +77,12 @@ class RenderFactory { * Render stage for game entity drawing. */ std::shared_ptr world_renderer; + + + /** + * Render stage for camera entity drawing. + */ + std::shared_ptr camera_manager; }; } // namespace openage::renderer diff --git a/libopenage/renderer/stages/camera/CMakeLists.txt b/libopenage/renderer/stages/camera/CMakeLists.txt index 359967eda0..e2b1d536b2 100644 --- a/libopenage/renderer/stages/camera/CMakeLists.txt +++ b/libopenage/renderer/stages/camera/CMakeLists.txt @@ -1,3 +1,4 @@ add_sources(libopenage manager.cpp + render_entity.cpp ) diff --git a/libopenage/renderer/stages/camera/manager.cpp b/libopenage/renderer/stages/camera/manager.cpp index d3cbd3f3b2..ab9739a070 100644 --- a/libopenage/renderer/stages/camera/manager.cpp +++ b/libopenage/renderer/stages/camera/manager.cpp @@ -28,6 +28,7 @@ CameraManager::CameraManager(const std::shared_ptr &ca void CameraManager::update() { this->update_motion(); this->update_uniforms(); + this->poll_render_entity(); // should we need to this every update? } void CameraManager::move_frame(MoveDirection direction, float speed) { @@ -72,6 +73,13 @@ void CameraManager::set_camera_boundaries(const CameraBoundaries &camera_boundar this->camera_boundaries = camera_boundaries; } +void CameraManager::poll_render_entity() { + if (this->render_entity->is_changed()) [[unlikely]] { + this->set_camera_boundaries(this->render_entity->get_camera_boundaries()); + this->render_entity->clear_changed_flag(); + } +} + void CameraManager::update_motion() { if (this->move_motion_directions != static_cast(MoveDirection::NONE)) { Eigen::Vector3f move_dir{0.0f, 0.0f, 0.0f}; @@ -141,4 +149,10 @@ void CameraManager::set_zoom_motion_speed(float speed) { this->zoom_motion_speed = speed; } +void CameraManager::add_render_entity(const std::shared_ptr entity) { + // std::unique_lock lock{this->mutex}; + this->render_entity = entity; +} + + } // namespace openage::renderer::camera diff --git a/libopenage/renderer/stages/camera/manager.h b/libopenage/renderer/stages/camera/manager.h index 36d605e959..615e5f2d88 100644 --- a/libopenage/renderer/stages/camera/manager.h +++ b/libopenage/renderer/stages/camera/manager.h @@ -6,6 +6,7 @@ #include #include "renderer/camera/camera.h" +#include "renderer/stages/camera/render_entity.h" namespace openage::renderer { class UniformBufferInput; @@ -114,6 +115,10 @@ class CameraManager { */ void set_camera_boundaries(const CameraBoundaries &camera_boundaries); + void add_render_entity(const std::shared_ptr entity); + + void poll_render_entity(); + private: /** * Update the camera parameters. @@ -159,6 +164,8 @@ class CameraManager { * Camera boundaries for X and Z movement. Contains minimum and maximum values for each axes. */ CameraBoundaries camera_boundaries; + + std::shared_ptr render_entity; }; } // namespace camera diff --git a/libopenage/renderer/stages/camera/render_entity.cpp b/libopenage/renderer/stages/camera/render_entity.cpp new file mode 100644 index 0000000000..cf40be91d2 --- /dev/null +++ b/libopenage/renderer/stages/camera/render_entity.cpp @@ -0,0 +1,21 @@ +// Copyright 2024-2025 the openage authors. See copying.md for legal info. + +#pragma once + +#include "render_entity.h" + +namespace openage::renderer::camera { + +void RenderEntity::update(const CameraBoundaries& boundaries, const time::time_t time) +{ + std::unique_lock lock{this->mutex}; + + this->camera_boundaries = camera_boundaries; + this->last_update = time; + this->changed = true; +} + +const CameraBoundaries &RenderEntity::get_camera_boundaries() { + return this->camera_boundaries; +} +} \ No newline at end of file diff --git a/libopenage/renderer/stages/camera/render_entity.h b/libopenage/renderer/stages/camera/render_entity.h new file mode 100644 index 0000000000..625ceb349f --- /dev/null +++ b/libopenage/renderer/stages/camera/render_entity.h @@ -0,0 +1,26 @@ +// Copyright 2024-2025 the openage authors. See copying.md for legal info. + +#pragma once + +#include "renderer/camera/boundaries.h" +#include "gamestate/definitions.h" +#include "renderer/stages/render_entity.h" + + +namespace openage::renderer::camera { + +class RenderEntity final : public renderer::RenderEntity { +public: + RenderEntity() = default; + ~RenderEntity() = default; + + void update(const CameraBoundaries &camera_boundaries, const time::time_t time = 0.0); + + const CameraBoundaries &get_camera_boundaries(); + + +private: + CameraBoundaries camera_boundaries; +}; + +} \ No newline at end of file