From 2d0a41dc0a53915153ceccda914d59affd388864 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 20 Dec 2013 06:59:48 +0100 Subject: [PATCH] simple zoom --- src/app/Application.cpp | 19 +++++++++++++------ src/graphics/Camera.cpp | 15 ++++++++++++++- src/graphics/Camera.h | 25 +++++++++++++++++++++++-- src/graphics/primitive.cpp | 36 ++++++++++++++++++++++++++++++++++++ src/graphics/primitive.h | 6 ++++++ src/math/Vector.h | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 124 insertions(+), 9 deletions(-) diff --git a/src/app/Application.cpp b/src/app/Application.cpp index b2ef916..9ebc261 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -87,6 +87,12 @@ void Application::OnKeyDown(const SDL_KeyboardEvent &e) { case SDLK_d: control.x += 1; break; + case SDLK_z: + cam.DoubleZoom(); + break; + case SDLK_x: + cam.HalfZoom(); + break; default: break; } @@ -127,6 +133,7 @@ void Application::OnKeyUp(const SDL_KeyboardEvent &e) { void Application::Update(int dt) { const float delta = dt / 1e3; controlled->acc = Vector(control * 10); + cam.Update(delta); univ.Update(delta); focus.Update(delta); } @@ -140,17 +147,17 @@ void Application::Render() { constexpr Color focusColor(0xFA, 0xFA, 0x00); SDL_Surface *dst = screen.Screen(); - const Vector begin = cam.Offset(); + const Vector begin = cam.ToScreen(Vector(0, 0)); const Vector end = - begin + (univ.size * univ.secSize * univ.areaSize) + Vector(1, 1); + cam.ToScreen((univ.size * univ.secSize * univ.areaSize)) + Vector(1, 1);; Fill(dst, background); - Grid(dst, begin, end, univ.areaSize, secGrid); - Grid(dst, begin, end, univ.secSize * univ.areaSize, univGrid); - Cross(dst, begin + Vector(focus.Pos()), 15, focusColor); + Grid(dst, begin, end, cam.ToScale(univ.areaSize), secGrid); + Grid(dst, begin, end, cam.ToScale(univ.secSize * univ.areaSize), univGrid); + Cross(dst, cam.ToScreen(focus.Pos()), 15, focusColor); for (const Entity &e : univ.Entities()) { - Cross(dst, begin + (e.area * univ.areaSize) + Vector(e.pos), 10, entityColor); + Cross(dst, cam.ToScreen((e.area * univ.areaSize) + Vector(e.pos)), 10, entityColor); } } diff --git a/src/graphics/Camera.cpp b/src/graphics/Camera.cpp index 0994a5a..a72157a 100644 --- a/src/graphics/Camera.cpp +++ b/src/graphics/Camera.cpp @@ -5,7 +5,8 @@ namespace space { Camera::Camera(int w, int h, const Vector &t) : target(&t) -, offset(w/2, h/2) { +, offset(w/2, h/2) +, zoom(0) { } @@ -14,4 +15,16 @@ void Camera::Resize(int w, int h) { offset = Vector(w/2, h/2); } +void Camera::Update(float delta) { + +} + +void Camera::DoubleZoom() { + zoom += 1; +} + +void Camera::HalfZoom() { + zoom -= 1; +} + } diff --git a/src/graphics/Camera.h b/src/graphics/Camera.h index 10699f0..e40b051 100644 --- a/src/graphics/Camera.h +++ b/src/graphics/Camera.h @@ -12,16 +12,37 @@ public: Camera(int w, int h, const Vector &); public: + void SetTarget(const Vector &t) { target = &t; } + void SetZoom(float z) { zoom = z; } + void Resize(int w, int h); + void Update(float deltaT); + + void DoubleZoom(); + void HalfZoom(); - Vector Offset() { - return -(*target - offset); + Vector ToScreen(Vector v) const { + return Vector(OffsetOf(v)); + } + Vector OffsetOf(Vector v) const { + return ToScale(v - *target) + offset; + } + Vector ToScale(Vector v) const { + if (zoom == 0) { + return v; + } else if (zoom > 0) { + return v * float(1 << zoom); + } else { + return v / float(1 << -zoom); + } } private: const Vector *target; Vector offset; + int zoom; + }; } diff --git a/src/graphics/primitive.cpp b/src/graphics/primitive.cpp index c97345a..1a68d45 100644 --- a/src/graphics/primitive.cpp +++ b/src/graphics/primitive.cpp @@ -128,4 +128,40 @@ void Grid( } } +void Grid( + SDL_Surface *dst, + Vector first, + Vector second, + Vector size, + Color color) { + Uint32 c = color.MapRGBA(dst); + + Vector from = min(first, second); + Vector to = max(first, second); + + if (size.x <= 1 || size.y <= 1) { + FillRect(dst, from, to - from, c); + return; + } + + if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) { + return; + } + + while (from.x < -size.x) from.x += size.x; + while (from.y < -size.y) from.y += size.y; + while (to.x > dst->w + size.x) to.x -= size.x; + while (to.y > dst->h + size.y) to.y -= size.y; + + float width = to.x - from.x; + float height = to.y - from.y; + + for (Vector pos(from); pos.x <= to.x; pos.x += size.x) { + VLine(dst, pos, height, c); + } + for (Vector pos(from); pos.y <= to.y; pos.y += size.y) { + HLine(dst, pos, width, c); + } +} + } diff --git a/src/graphics/primitive.h b/src/graphics/primitive.h index 133e1f9..7726700 100644 --- a/src/graphics/primitive.h +++ b/src/graphics/primitive.h @@ -34,6 +34,12 @@ void Grid( Vector to, Vector size, Color); +void Grid( + SDL_Surface *, + Vector from, + Vector to, + Vector size, + Color); } diff --git a/src/math/Vector.h b/src/math/Vector.h index 57159bf..b5c6d7d 100644 --- a/src/math/Vector.h +++ b/src/math/Vector.h @@ -2,6 +2,7 @@ #define SPACE_VECTOR_H_ #include +#include namespace space { @@ -66,6 +67,37 @@ constexpr Vector operator *(Vector lhs, Vector rhs) { return Vector(lhs.x * rhs.x, lhs.y * rhs.y); } + +template +constexpr Vector operator /(Vector lhs, Scalar rhs) { + return Vector(lhs.x / rhs, lhs.y / rhs); +} + +template +constexpr Vector operator /(Scalar lhs, Vector rhs) { + return rhs / lhs; +} +template +constexpr Vector operator /(Vector lhs, Vector rhs) { + return Vector(lhs.x / rhs.x, lhs.y / rhs.y); +} + + +template +constexpr bool operator ==(Vector lhs, Vector rhs) { + return lhs.x == rhs.x && lhs.y == rhs.y; +} +template +constexpr bool operator !=(Vector lhs, Vector rhs) { + return lhs.x != rhs.x && lhs.y != rhs.y; +} + + +template +inline std::ostream &operator <<(std::ostream &out, Vector v) { + return out << '<' << v.x << ',' << v.y << '>'; +} + } -- 2.39.2