/* * Renderer.cpp * * Created on: 4 nov. 2020 * Author: simon */ #include "render/Renderer.h" #include "render/shaders/WorldShader.h" #include "render/shaders/EntityShader.h" #include #include #include #include "misc/Time.h" #include "misc/Easing.h" using namespace gl; namespace td{ namespace render{ namespace Renderer{ #define ANIMATION_SPEED 2.0f static std::unique_ptr worldShader; static std::unique_ptr entityShader; static bool isometricView = true; static float isometricShade = isometricView; static glm::vec2 camPos{}; void updateIsometricView(){ worldShader->start(); worldShader->setIsometricView(isometricShade); entityShader->start(); entityShader->setIsometricView(isometricShade); } void initShader(){ worldShader = std::make_unique(); worldShader->loadShader(); entityShader = std::make_unique(); entityShader->loadShader(); setIsometricView(true); updateIsometricView(); } bool init(){ glbinding::Binding::initialize(); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); initShader(); return true; } void destroy(){ worldShader.reset(0); entityShader.reset(0); } void renderVAO(const GL::VAO& vao){ worldShader->start(); vao.bind(); glDrawArrays(GL_TRIANGLES, 0, vao.getVertexCount()); vao.unbind(); } void renderModel(const Model& model){ entityShader->start(); entityShader->setModelPos(model.positon); model.vao->bind(); glDrawArrays(GL_TRIANGLES, 0, model.vao->getVertexCount()); model.vao->unbind(); } void updateIsometricFade(){ static std::uint64_t lastTime = utils::getTime(); if(isometricShade != (float) isometricView){ float step = (float) (utils::getTime() - lastTime) / 1000.0f * ANIMATION_SPEED; if(isometricShade < isometricView){ isometricShade += step; }else{ isometricShade -= step; } isometricShade = std::min(isometricShade, 1.0f); isometricShade = std::max(isometricShade, 0.0f); updateIsometricView(); } lastTime = utils::getTime(); } void prepare(){ glClear(GL_COLOR_BUFFER_BIT); glClearColor(0, 0, 0, 0); updateIsometricFade(); } void resize(int width, int height){ worldShader->start(); worldShader->setAspectRatio((float)width / height); entityShader->start(); entityShader->setAspectRatio((float)width / height); glViewport(0, 0, width, height); } void setZoom(float zoom){ worldShader->start(); worldShader->setZoom(zoom); entityShader->start(); entityShader->setZoom(zoom); } void setCamMovement(const glm::vec2& mov){ camPos.x += mov.x * (1 - isometricView) + (0.5 * mov.x - mov.y) * isometricView; camPos.y += -mov.y * (1 - isometricView) + (-0.5 * mov.x - mov.y) * isometricView; setCamPos(camPos); } void setCamPos(const glm::vec2& newPos){ camPos = newPos; worldShader->start(); worldShader->setCamPos(newPos); entityShader->start(); entityShader->setCamPos(newPos); } void setIsometricView(bool isometric){ isometricView = isometric; } glm::vec2 getCursorWorldPos(const glm::vec2& cursorPos, float aspectRatio, float zoom, float windowWidth, float windowHeight){ float relativeX = (cursorPos.x / windowWidth * 2) - 1; float relativeY = (cursorPos.y / windowHeight * 2) - 1; float deltaX = relativeX * aspectRatio / zoom; float deltaY = relativeY / zoom; float worldX = camPos.x + deltaX * (1 - isometricView) + (0.5 * deltaX + deltaY) * isometricView; float worldY = camPos.y + deltaY * (1 - isometricView) + (-0.5 * deltaX + deltaY) * isometricView; return {worldX, worldY}; } } // namespace Renderer } // namespace render } // namespace td