diff options
author | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-11-22 13:54:13 +0100 |
---|---|---|
committer | heavydemon21 <nielsstunnebrink1@gmail.com> | 2024-11-22 13:54:13 +0100 |
commit | 385f19a8c896ec126c569f1e5337d6d370d20517 (patch) | |
tree | bdadcca9c504176ada3ba4ef8e9754df8042e52e | |
parent | ad0dcad1f11d698abf71bf69fb0927c26298d253 (diff) |
working aspect ratio in world units. and add pillarboxing/letterboxing depending on ratio
-rw-r--r-- | src/crepe/api/Camera.h | 4 | ||||
-rw-r--r-- | src/crepe/api/Color.cpp | 2 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.cpp | 98 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 4 | ||||
-rw-r--r-- | src/example/rendering_particle.cpp | 12 |
5 files changed, 87 insertions, 33 deletions
diff --git a/src/crepe/api/Camera.h b/src/crepe/api/Camera.h index d7292ef..c42ed0d 100644 --- a/src/crepe/api/Camera.h +++ b/src/crepe/api/Camera.h @@ -32,10 +32,10 @@ public: Vector2 pos = {0, 0}; //! screen the display size in pixels ( output resolution ) - Vector2 screen = {640, 480}; + Vector2 screen = {1080, 720}; //! viewport is the area of the world visible through the camera (in world units) - Vector2 viewport = {500, 500}; + Vector2 viewport = {2000, 1000}; //! scale scaling factor from world units to pixel coordinates Vector2 scale = {0, 0}; diff --git a/src/crepe/api/Color.cpp b/src/crepe/api/Color.cpp index 29bd77a..dc7c15f 100644 --- a/src/crepe/api/Color.cpp +++ b/src/crepe/api/Color.cpp @@ -2,7 +2,7 @@ using namespace crepe; -const Color Color::WHITE{0xff, 0xff, 0xff}; +const Color Color::WHITE{0xff, 0xff, 0xff, 0xff}; const Color Color::RED{0xff, 0x00, 0x00}; const Color Color::GREEN{0x00, 0xff, 0x00}; const Color Color::BLUE{0x00, 0x00, 0xff}; diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index 74af25f..e187d67 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -5,12 +5,12 @@ #include <SDL2/SDL_render.h> #include <SDL2/SDL_surface.h> #include <SDL2/SDL_video.h> +#include <algorithm> #include <cmath> #include <cstddef> #include <functional> #include <memory> #include <stdexcept> -#include <string> #include "../api/Camera.h" #include "../api/Sprite.h" @@ -94,7 +94,10 @@ void SDLContext::handle_events(bool & running) { */ } -void SDLContext::clear_screen() { SDL_RenderClear(this->game_renderer.get()); } +void SDLContext::clear_screen() { + SDL_SetRenderDrawColor(this->game_renderer.get(), 0, 0, 0, 255); + SDL_RenderClear(this->game_renderer.get()); +} void SDLContext::present_screen() { SDL_RenderPresent(this->game_renderer.get()); } SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const { @@ -108,20 +111,11 @@ SDL_Rect SDLContext::get_src_rect(const Sprite & sprite) const { SDL_Rect SDLContext::get_dst_rect(const Sprite & sprite, const Vector2 & pos, const double & scale, const Camera & cam) const { - Vector2 pixel_coord = (transform.position - cam.pos) * cam.scale; - double pixel_w = sprite.sprite_rect.w * transform.scale * cam.scale.x; - double pixel_h = sprite.sprite_rect.h * transform.scale * cam.scale.y; - - double adjusted_x = (pos.x - cam.x) * cam.zoom; - double adjusted_y = (pos.y - cam.y) * cam.zoom; - double adjusted_w = sprite.sprite_rect.w * scale * cam.zoom; - double adjusted_h = sprite.sprite_rect.h * scale * cam.zoom; - return SDL_Rect{ - .x = static_cast<int>(adjusted_x), - .y = static_cast<int>(adjusted_y), - .w = static_cast<int>(adjusted_w), - .h = static_cast<int>(adjusted_h), + .x = static_cast<int>(sprite.sprite_rect.x - 400 / 2), + .y = static_cast<int>(sprite.sprite_rect.y - 300 / 2), + .w = static_cast<int>(400), + .h = static_cast<int>(300), }; } @@ -153,27 +147,81 @@ void SDLContext::draw(const Sprite & sprite, const Transform & transform, const &dstrect, transform.rotation, NULL, render_flip); } -void SDLContext::set_camera(const Camera & cam) { +void SDLContext::set_camera(Camera & cam) { + if (this->viewport.w != (int)cam.screen.x && this->viewport.h != (int)cam.screen.y) { + SDL_SetWindowSize(this->game_window.get(), (int)cam.screen.x, (int)cam.screen.y); + this->viewport.h = cam.screen.y; + this->viewport.w = cam.screen.x; + } double screen_aspect = cam.screen.x / cam.screen.y; double viewport_aspect = cam.viewport.x / cam.viewport.y; - Vector2 zoomed_viewport = cam.viewport * cam.zoom; + + SDL_Rect view; if (screen_aspect > viewport_aspect) { - cam.scale.x = cam.scale.y = cam.screen.x / zoomed_viewport.x; + view.h = static_cast<int>(cam.screen.y); + view.w = static_cast<int>(cam.screen.y * viewport_aspect); + view.x = static_cast<int>(cam.screen.x - view.w) / 2; + view.y = 0; } else { - cam.scale.y = cam.scale.x = cam.screen.y / zoomed_viewport.y; + view.w = static_cast<int>(cam.screen.x); + view.h = static_cast<int>(cam.screen.x / viewport_aspect); + view.x = 0; + view.y = static_cast<int>(cam.screen.y - view.h) / 2; } + SDL_RenderSetViewport(this->game_renderer.get(), &view); - if (this->viewport.w != cam.screen.x && this->viewport.h != cam.screen.y) { - this->viewport.w = cam.screen.x; - this->viewport.h = cam.screen.y; - SDL_SetWindowSize(this->game_window.get(), cam.screen.x, cam.screen.y); + SDL_RenderSetLogicalSize(this->game_renderer.get(), cam.viewport.x, cam.viewport.y); + SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g, + cam.bg_color.b, cam.bg_color.a); + SDL_Rect bg = { + .x = 0, + .y = 0, + .w = static_cast<int>(cam.viewport.x), + .h = static_cast<int>(cam.viewport.y), + }; + SDL_RenderFillRect(this->game_renderer.get(), &bg); + + /* + float offset_x = 0, offset_y = 0; + + + double scale_factor = min(cam.screen.x / cam.viewport.x, cam.screen.y / cam.viewport.y); + cam.scale.x = scale_factor * cam.viewport.x; + cam.scale.y = scale_factor * cam.viewport.y; + + offset_x = (cam.screen.x - cam.scale.x) / 2; + offset_y = (cam.screen.y - cam.scale.y) / 2; + + float bar_w = cam.screen.x - cam.scale.x; + float bar_h = cam.screen.y - cam.scale.y; + + SDL_SetRenderDrawColor(this->game_renderer.get(), 0, 0, 0, 255); + if (bar_w > 0) { + SDL_Rect left_bar = {0, 0, static_cast<int>(offset_x), static_cast<int>(cam.screen.y)}; + SDL_RenderDrawRect(this->game_renderer.get(), &left_bar); + + SDL_Rect right_bar = {static_cast<int>(offset_x + cam.scale.x), 0, + static_cast<int>(offset_x), static_cast<int>(cam.screen.y)}; + SDL_RenderDrawRect(this->game_renderer.get(), &right_bar); } - SDL_SetRenderDrawColor(this->game_renderer.get(), cam.bg_color.r, cam.bg_color.g, - cam.bg_color.b, cam.bg_color.a); + if (screen_aspect > viewport_aspect) { + // pillarboxing + cam.scale.x = cam.scale.y = cam.screen.x / cam.viewport.x; + offset_y = (cam.screen.y - (cam.viewport.y * cam.scale.y)) / 2; + } else if (screen_aspect < viewport_aspect) { + // lettor boxing + cam.scale.y = cam.scale.x = cam.screen.y / zoomed_viewport.y; + offset_x = (cam.screen.x - (cam.viewport.x * cam.scale.x)) / 2; + } else { + // screen ration is even + offset_y = (cam.screen.y - (cam.viewport.y * cam.scale.y)) / 2; + offset_x = (cam.screen.x - (cam.viewport.x * cam.scale.x)) / 2; + } + */ } uint64_t SDLContext::get_ticks() const { return SDL_GetTicks64(); } diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 841ffc9..45bbda6 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -133,7 +133,7 @@ private: * \brief sets the background of the camera (will be adjusted in future PR) * \param camera Reference to the Camera object. */ - void set_camera(const Camera & camera); + void set_camera(Camera & camera); private: /** @@ -164,7 +164,7 @@ private: std::unique_ptr<SDL_Renderer, std::function<void(SDL_Renderer *)>> game_renderer; //! viewport for the camera window - SDL_Rect viewport = {0, 0, 640, 480}; + SDL_Rect viewport = {0, 0, 1280, 720}; }; } // namespace crepe diff --git a/src/example/rendering_particle.cpp b/src/example/rendering_particle.cpp index 4571afb..96ef3df 100644 --- a/src/example/rendering_particle.cpp +++ b/src/example/rendering_particle.cpp @@ -23,16 +23,18 @@ using namespace std; int main(int argc, char * argv[]) { ComponentManager mgr; - GameObject game_object = mgr.new_object("", "", Vector2{100, 100}, 0, 0.1); + GameObject game_object = mgr.new_object("", "", Vector2{400, 300}, 0, 0.1); RenderSystem sys{mgr}; ParticleSystem psys{mgr}; Color color(255, 255, 255, 255); Sprite & test_sprite = game_object.add_component<Sprite>( - make_shared<Texture>("../asset/texture/img.png"), color, FlipSettings{false, false}); + make_shared<Texture>("asset/texture/test_ap43.png"), color, FlipSettings{false, false}); test_sprite.order_in_layer = 5; + + /* auto & test = game_object.add_component<ParticleEmitter>(ParticleEmitter::Data{ .position = {0, 0}, .max_particles = 10, @@ -52,13 +54,17 @@ int main(int argc, char * argv[]) { }, .sprite = test_sprite, }); + */ + game_object.add_component<Camera>(Color::WHITE); + /* game_object - .add_component<Sprite>(make_shared<Texture>("../asset/texture/img.png"), color, + .add_component<Sprite>(make_shared<Texture>("asset/texture/img.png"), color, FlipSettings{false, false}) .order_in_layer = 6; + */ auto start = std::chrono::steady_clock::now(); while (std::chrono::steady_clock::now() - start < std::chrono::seconds(5)) { |