#ifndef CAMERA_HPP #define CAMERA_HPP 1 #include "vex.hpp" #include "shape.hpp" #include "straw.hpp" #include #include #include class Camera; struct RenderBatchEntry { shapes::shapes_variant shape; straw::color fg, bg; char c; template constexpr RenderBatchEntry(T Shape) : shape(Shape), fg(straw::WHITE), bg(straw::BLACK), c('#') {} template constexpr RenderBatchEntry(T Shape, char C) : shape(Shape), fg(straw::WHITE), bg(straw::BLACK), c(C) {} template constexpr RenderBatchEntry(T Shape, straw::color Fg, char C) : shape(Shape), fg(Fg), bg(straw::BLACK), c(C) {} template constexpr RenderBatchEntry(T Shape, straw::color Fg, straw::color Bg, char C) : shape(Shape), fg(Fg), bg(Bg), c(C) {} void translate(Camera *camera); void plot(Camera *camera); private: void plotPoint(shapes::point point, Camera *camera); void plotLine(shapes::line line, Camera *camera); void plotRectangle(shapes::rectangle rectangle, Camera *camera); void plotCircle(shapes::circle circle, Camera *camera); void plotEllipse(shapes::ellipse ellipse, Camera *camera); }; class Camera { friend struct RenderBatchEntry; vex::vec2 m_position; vex::vec2 m_origin; shapes::rectangle m_frustum; std::vector m_shapeBatch; long m_scale; bool m_dirty; straw::screen *m_viewport; void updateFrustum(); template void translateShape(T &shape); public: Camera(straw::screen *viewport) : m_position(0, 0), m_origin(0, 0), m_frustum(0, 0, 0, 0), m_scale(16384), m_dirty(true), m_viewport(viewport) {} ~Camera() {} constexpr long getscale() const { return m_scale; } constexpr vex::vec2 getpos() const { return m_position; } constexpr vex::vec2 getorigin() const { return m_origin; } constexpr bool dirty() const { return m_dirty; } void markDirty() { m_dirty = true; } void zoom(long by) { m_scale = std::max((unsigned)((int)m_scale + by), (unsigned)1); m_dirty = true; } void setscale(long scale) { m_scale = std::max(scale, (long)1); m_dirty = true; } void move(const vex::vec2 &pos) { m_position += pos; m_dirty = true; } void move(long x, long y) { move(vex::vec2(x, y)); } void setpos(const vex::vec2 &pos) { m_position = pos; m_dirty = true; } void setpos(long x, long y) { setpos(vex::vec2(x, y)); } void setorigin(const vex::vec2 &origin) { m_origin = origin; m_dirty = true; } template void batchShape(T shape) { m_shapeBatch.emplace_back(shape); } template void batchShape(T shape, char c) { m_shapeBatch.emplace_back(shape, c); } template void batchShape(T shape, straw::color fg, char c) { m_shapeBatch.emplace_back(shape, fg, c); } template void batchShape(T shape, straw::color fg, straw::color bg, char c) { m_shapeBatch.emplace_back(shape, fg, bg, c); } void draw(); }; #endif