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)) { |