#include <cmath> | #include <cmath> | ||||
#include <array> | #include <array> | ||||
#include "Vector2.h" | |||||
namespace SwanCommon { | namespace SwanCommon { | ||||
template<typename T> | template<typename T> | ||||
struct Matrix3 { | struct Matrix3 { | ||||
using Vec = Vector2<T>; | |||||
static constexpr std::array<T, 9> identity = {1, 0, 0, 0, 1, 0, 0, 0, 1}; | static constexpr std::array<T, 9> identity = {1, 0, 0, 0, 1, 0, 0, 0, 1}; | ||||
std::array<T, 9> vals; | std::array<T, 9> vals; | ||||
return *this; | return *this; | ||||
} | } | ||||
constexpr Matrix3<T> &translate(T x, T y) { | |||||
at(2, 0) += x; | |||||
at(2, 1) += y; | |||||
constexpr Matrix3<T> &translate(Vec vec) { | |||||
at(2, 0) += vec.x; | |||||
at(2, 1) += vec.y; | |||||
return *this; | return *this; | ||||
} | } | ||||
constexpr Matrix3<T> &scale(T x, T y) { | |||||
at(0, 0) *= x; | |||||
at(1, 1) *= y; | |||||
constexpr Matrix3<T> &scale(Vec vec) { | |||||
at(0, 0) *= vec.x; | |||||
at(1, 1) *= vec.y; | |||||
return *this; | return *this; | ||||
} | } | ||||
#pragma once | |||||
namespace SwanCommon { | |||||
template<typename T> | |||||
class Lock { | |||||
}; | |||||
} |
GLuint tex; | GLuint tex; | ||||
}; | }; | ||||
struct RenderCamera { | |||||
SwanCommon::Vec2 pos; | |||||
float zoom; | |||||
}; | |||||
class Renderer { | class Renderer { | ||||
public: | public: | ||||
using TileID = uint16_t; | using TileID = uint16_t; | ||||
void drawChunk(SwanCommon::Vec2 pos, RenderChunk chunk); | void drawChunk(SwanCommon::Vec2 pos, RenderChunk chunk); | ||||
void draw(); | |||||
void draw(const RenderCamera &cam); | |||||
void registerTileTexture(TileID tileId, const void *data, size_t len); | void registerTileTexture(TileID tileId, const void *data, size_t len); | ||||
void uploadTileTexture(); | void uploadTileTexture(); |
TileAtlas atlas; | TileAtlas atlas; | ||||
GlTexture atlasTex; | GlTexture atlasTex; | ||||
Mat3gf camera; | |||||
}; | }; | ||||
Renderer::Renderer(): state_(std::make_unique<RendererState>()) {} | Renderer::Renderer(): state_(std::make_unique<RendererState>()) {} | ||||
Renderer::~Renderer() = default; | Renderer::~Renderer() = default; | ||||
void Renderer::draw() { | |||||
void Renderer::draw(const RenderCamera &cam) { | |||||
Mat3gf camMat; | |||||
camMat.translate({ -cam.pos.x, cam.pos.y }); // TODO: Change something to make this -cam.pos | |||||
camMat.scale({ cam.zoom, cam.zoom }); | |||||
auto &chunkProg = state_->chunkProg; | auto &chunkProg = state_->chunkProg; | ||||
state_->camera.reset().translate(-0.9, 0.9).scale(0.125, 0.125); | |||||
chunkProg.enable(); | chunkProg.enable(); | ||||
glUniform2f(chunkProg.tileAtlasSize, | glUniform2f(chunkProg.tileAtlasSize, | ||||
(float)(int)(state_->atlasTex.width() / SwanCommon::TILE_SIZE), | (float)(int)(state_->atlasTex.width() / SwanCommon::TILE_SIZE), | ||||
(float)(int)(state_->atlasTex.height() / SwanCommon::TILE_SIZE)); | (float)(int)(state_->atlasTex.height() / SwanCommon::TILE_SIZE)); | ||||
glUniformMatrix3fv(chunkProg.camera, 1, GL_TRUE, state_->camera.data()); | |||||
glUniformMatrix3fv(chunkProg.camera, 1, GL_TRUE, camMat.data()); | |||||
glCheck(); | glCheck(); | ||||
glActiveTexture(GL_TEXTURE0); | glActiveTexture(GL_TEXTURE0); | ||||
glCheck(); | glCheck(); | ||||
glActiveTexture(GL_TEXTURE1); | glActiveTexture(GL_TEXTURE1); | ||||
for (auto [pos, chunk]: draw_chunks_) { | for (auto [pos, chunk]: draw_chunks_) { | ||||
glUniform2f(chunkProg.pos, pos.x, pos.y); | glUniform2f(chunkProg.pos, pos.x, pos.y); | ||||
glBindTexture(GL_TEXTURE_2D, chunk.tex); | glBindTexture(GL_TEXTURE_2D, chunk.tex); |
chunk = rnd.createChunk(tiles); | chunk = rnd.createChunk(tiles); | ||||
} | } | ||||
Cygnet::RenderCamera cam = { | |||||
.pos = { 0.9, 0.9 }, | |||||
.zoom = 0.125, | |||||
}; | |||||
while (true) { | while (true) { | ||||
SDL_Event evt; | SDL_Event evt; | ||||
while (SDL_PollEvent(&evt)) { | while (SDL_PollEvent(&evt)) { | ||||
rnd.drawChunk({0, 0}, chunk); | rnd.drawChunk({0, 0}, chunk); | ||||
win.clear(); | win.clear(); | ||||
rnd.draw(); | |||||
rnd.draw(cam); | |||||
win.flip(); | win.flip(); | ||||
} | } | ||||