From: Daniel Karbach Date: Fri, 20 Dec 2013 06:25:45 +0000 (+0100) Subject: dynamic zoom X-Git-Url: http://git.localhorst.tv/?p=space.git;a=commitdiff_plain;h=a1fd5c4181db1da990b6280892eb1b9f31b73871 dynamic zoom butt ugly --- diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 9ebc261..d18c757 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -88,10 +88,10 @@ void Application::OnKeyDown(const SDL_KeyboardEvent &e) { control.x += 1; break; case SDLK_z: - cam.DoubleZoom(); + cam.StartZoom(); break; case SDLK_x: - cam.HalfZoom(); + cam.StartShrink(); break; default: break; @@ -124,6 +124,12 @@ void Application::OnKeyUp(const SDL_KeyboardEvent &e) { case SDLK_d: control.x -= 1; break; + case SDLK_z: + cam.StopZoom(); + break; + case SDLK_x: + cam.StopShrink(); + break; default: break; } @@ -149,11 +155,11 @@ void Application::Render() { SDL_Surface *dst = screen.Screen(); const Vector begin = cam.ToScreen(Vector(0, 0)); const Vector end = - cam.ToScreen((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, cam.ToScale(univ.areaSize), secGrid); - Grid(dst, begin, end, cam.ToScale(univ.secSize * univ.areaSize), univGrid); + Grid2(dst, begin, end, cam.ToScale(univ.areaSize), univ.secSize, secGrid, univGrid); Cross(dst, cam.ToScreen(focus.Pos()), 15, focusColor); for (const Entity &e : univ.Entities()) { diff --git a/src/graphics/Camera.cpp b/src/graphics/Camera.cpp index a72157a..553b74f 100644 --- a/src/graphics/Camera.cpp +++ b/src/graphics/Camera.cpp @@ -6,7 +6,7 @@ namespace space { Camera::Camera(int w, int h, const Vector &t) : target(&t) , offset(w/2, h/2) -, zoom(0) { +, zoom(1) { } @@ -16,15 +16,24 @@ void Camera::Resize(int w, int h) { } void Camera::Update(float delta) { + zoom += zoom * zoomAcc * delta; + if (zoom < 0.0001) zoom = 0.0001; +} + +void Camera::StartZoom() { + zoomAcc += 1; +} +void Camera::StopZoom() { + zoomAcc -= 1; } -void Camera::DoubleZoom() { - zoom += 1; +void Camera::StartShrink() { + zoomAcc -= 1; } -void Camera::HalfZoom() { - zoom -= 1; +void Camera::StopShrink() { + zoomAcc += 1; } } diff --git a/src/graphics/Camera.h b/src/graphics/Camera.h index e40b051..ad1a997 100644 --- a/src/graphics/Camera.h +++ b/src/graphics/Camera.h @@ -18,8 +18,10 @@ public: void Resize(int w, int h); void Update(float deltaT); - void DoubleZoom(); - void HalfZoom(); + void StartZoom(); + void StopZoom(); + void StartShrink(); + void StopShrink(); Vector ToScreen(Vector v) const { return Vector(OffsetOf(v)); @@ -28,20 +30,15 @@ public: 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); - } + return v * zoom; } private: const Vector *target; Vector offset; - int zoom; + float zoom; + int zoomAcc; }; diff --git a/src/graphics/primitive.cpp b/src/graphics/primitive.cpp index 1a68d45..f8b5863 100644 --- a/src/graphics/primitive.cpp +++ b/src/graphics/primitive.cpp @@ -164,4 +164,86 @@ void Grid( } } +void Grid2( + SDL_Surface *dst, + Vector first, + Vector second, + Vector size, + Vector n, + Color color1, + Color color2) { + Uint32 c1 = color1.MapRGBA(dst); + Uint32 c2 = color2.MapRGBA(dst); + + Vector from = min(first, second); + Vector to = max(first, second); + + if (size.x <= 1 || size.y <= 1) { + FillRect(dst, from, to - from, c1); + Grid(dst, from, to, size * n, color2); + return; + } + + if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) { + return; + } + + Vector i(0, 0); + while (from.x < -size.x) { from.x += size.x; ++i.x; } + while (from.y < -size.y) { from.y += size.y; ++i.y; } + while (to.x > dst->w + size.x) to.x -= size.x; + while (to.y > dst->h + size.y) to.y -= size.y; + + int width = to.x - from.x; + int height = to.y - from.y; + + for (Vector pos(from); pos.x <= to.x; pos.x += size.x) { + VLine(dst, pos, height, (i.x++ % n.x) ? c1 : c2); + } + for (Vector pos(from); pos.y <= to.y; pos.y += size.y) { + HLine(dst, pos, width, (i.y++ % n.y) ? c1 : c2); + } +} + +void Grid2( + SDL_Surface *dst, + Vector first, + Vector second, + Vector size, + Vector n, + Color color1, + Color color2) { + Uint32 c1 = color1.MapRGBA(dst); + Uint32 c2 = color2.MapRGBA(dst); + + Vector from = min(first, second); + Vector to = max(first, second); + + if (size.x <= 1 || size.y <= 1) { + FillRect(dst, from, to - from, c1); + Grid(dst, from, to, size * Vector(n), color2); + return; + } + + if (from.x > dst->w || from.y > dst->h || to.x < 0 || to.y < 0) { + return; + } + + Vector i(0, 0); + while (from.x < -size.x) { from.x += size.x; ++i.x; } + while (from.y < -size.y) { from.y += size.y; ++i.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, (i.x++ % n.x) ? c1 : c2); + } + for (Vector pos(from); pos.y <= to.y; pos.y += size.y) { + HLine(dst, pos, width, (i.y++ % n.y) ? c1 : c2); + } +} + } diff --git a/src/graphics/primitive.h b/src/graphics/primitive.h index 7726700..6dcc6fe 100644 --- a/src/graphics/primitive.h +++ b/src/graphics/primitive.h @@ -41,6 +41,23 @@ void Grid( Vector size, Color); +void Grid2( + SDL_Surface *, + Vector from, + Vector to, + Vector size, + Vector n, + Color, + Color); +void Grid2( + SDL_Surface *, + Vector from, + Vector to, + Vector size, + Vector n, + Color, + Color); + } #endif