#include "render/WorldRenderer.h" #include "render/loader/WorldLoader.h" #include "render/Renderer.h" #include "render/gui/imgui/imgui.h" #include "window/Display.h" #include "game/client/ClientGame.h" #include namespace td { namespace render { void WorldRenderer::loadModels() { std::cout << "World Created !\n"; m_WorldVao = std::make_unique(std::move(WorldLoader::loadWorldModel(m_World))); m_MobVao = std::make_unique(std::move(WorldLoader::loadMobModel())); m_SelectTileVao = std::make_unique(std::move(WorldLoader::loadTileSelectModel())); std::cout << "Vertex Count : " << m_WorldVao->getVertexCount() << std::endl; } WorldRenderer::WorldRenderer(game::World* world, client::ClientGame* client) : m_Client(client), m_Renderer(m_Client->getRenderer()), m_World(world) { m_Renderer->setZoom(m_Zoom); m_Renderer->setCamMovement({}); } void WorldRenderer::updateCursorPos() { m_CursorPos = getCursorWorldPos(); } void WorldRenderer::update() { if (m_WorldVao == nullptr) return; ImGuiIO& io = ImGui::GetIO(); if (io.MouseDown[0] && !ImGui::IsAnyItemActive()) { ImVec2 mouseDelta = ImGui::GetIO().MouseDelta; const float relativeX = mouseDelta.x / (float)Display::getWindowWidth() * 2; const float relativeY = mouseDelta.y / (float)Display::getWindowHeight() * 2; moveCam(relativeX, relativeY, Display::getAspectRatio()); } if (io.MouseWheel != 0) { changeZoom(io.MouseWheel); } updateCursorPos(); if (ImGui::IsMouseClicked(0)) { if (!m_TowerPlacePopupOpened) { m_HoldCursorPos = { io.MousePos.x, io.MousePos.y }; } else { m_TowerPlacePopupOpened = false; } } } void WorldRenderer::renderWorld() const { m_Renderer->renderVAO(*m_WorldVao); } void WorldRenderer::renderMobs() const { for (game::MobPtr mob : m_World->getMobList()) { Renderer::Model model; model.vao = m_MobVao.get(); model.positon = { mob->getX(), mob->getY() }; m_Renderer->renderModel(model); } } void WorldRenderer::renderTowers() const { if (!m_TowersCache.isEmpty()) m_Renderer->renderVAO(m_TowersCache.getVertexArray()); } void WorldRenderer::renderTileSelect() const { Renderer::Model tileSelectModel; tileSelectModel.vao = m_SelectTileVao.get(); tileSelectModel.positon = { (int)m_CursorPos.x, (int)m_CursorPos.y }; m_Renderer->renderModel(tileSelectModel); } void WorldRenderer::render() { if (m_WorldVao == nullptr) return; renderWorld(); renderMobs(); renderTowers(); renderTileSelect(); detectClick(); renderPopups(); } WorldRenderer::~WorldRenderer() { } void WorldRenderer::moveCam(float relativeX, float relativeY, float aspectRatio) { if (m_WorldVao == nullptr) return; float movementX = -relativeX / m_Zoom * aspectRatio; float movementY = relativeY / m_Zoom; m_Renderer->setCamMovement({ movementX, movementY }); } void WorldRenderer::changeZoom(float zoomStep) { if (m_WorldVao == nullptr) return; static float sensibility = 1.5f; if (zoomStep < 0) { m_Zoom /= -zoomStep * sensibility; } else { m_Zoom *= zoomStep * sensibility; } m_Renderer->setZoom(m_Zoom); m_Renderer->setCamMovement({}); } void WorldRenderer::click() { if (m_Client->getWorld().CanPlaceLittleTower(getClickWorldPos(), m_Client->getPlayer()->getID())) { ImGui::OpenPopup("TowerPlace"); m_TowerPlacePopupOpened = true; } } void WorldRenderer::setCamPos(float camX, float camY) { m_CamPos = { camX, camY }; m_Renderer->setCamPos(m_CamPos); } void WorldRenderer::renderPopups() const { if (ImGui::BeginPopup("TowerPlace")) { for (int i = 0; i < (int)game::TowerType::TowerCount; i++) { game::TowerType towerType = game::TowerType(i); const game::TowerInfo& towerInfo = game::getTowerInfo(towerType); if (!towerInfo.isBigTower() || (towerInfo.isBigTower() && m_Client->getWorld().CanPlaceBigTower(getClickWorldPos(), m_Client->getPlayer()->getID()))) { if (ImGui::Button(game::getTowerInfo(towerType).getName().c_str())) { m_Client->PlaceTower(towerType, getClickWorldPos()); ImGui::CloseCurrentPopup(); break; } if (ImGui::IsItemHovered()) { ImGui::SetTooltip(game::getTowerInfo(towerType).getDescription().c_str(), "%s"); } } } ImGui::EndPopup(); } } void WorldRenderer::detectClick() { ImGuiIO& io = ImGui::GetIO(); if (ImGui::IsMouseReleased(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemFocused()) { glm::vec2 cursorPos = { io.MousePos.x, io.MousePos.y }; if (cursorPos == m_HoldCursorPos) { click(); } } } void WorldRenderer::addTower(game::TowerPtr tower) { const WorldLoader::RenderData& renderData = WorldLoader::loadTowerModel(tower); m_TowersCache.addData(tower->getID(), renderData.positions, renderData.colors); m_TowersCache.updateVertexArray(); } void WorldRenderer::removeTower(game::TowerPtr tower) { m_TowersCache.removeData(tower->getID()); m_TowersCache.updateVertexArray(); } glm::vec2 WorldRenderer::getCursorWorldPos() const { ImGuiIO& io = ImGui::GetIO(); return m_Renderer->getCursorWorldPos({ io.MousePos.x, io.MousePos.y }, Display::getAspectRatio(), m_Zoom, Display::getWindowWidth(), Display::getWindowHeight()); } glm::vec2 WorldRenderer::getClickWorldPos() const { return m_Renderer->getCursorWorldPos(m_HoldCursorPos, Display::getAspectRatio(), m_Zoom, Display::getWindowWidth(), Display::getWindowHeight()); } } // namespace render } // namespace td