From 997e1ccbb1b7ccb69ff4d66724c83093e73abc64 Mon Sep 17 00:00:00 2001 From: sebastian Date: Sun, 8 Feb 2026 07:44:25 +0100 Subject: [PATCH] ADD: Render Terrain --- .gitmodules | 3 -- .idea/vcs.xml | 1 + CMakeLists.txt | 11 ++++- assets/dragon/dragon.png | Bin 0 -> 1606 bytes src/engine/layer/entities/Camera.h | 2 +- src/engine/renderer/Renderer.cpp | 28 +++++++++++- src/engine/renderer/Renderer.h | 7 ++- src/game/DicewarsApp.cpp | 2 +- src/{engine/layer => game}/GameLayer.cpp | 51 +++++++++------------ src/{engine/layer => game}/GameLayer.h | 16 ++++--- src/game/hexWorld/HexModelFactory.cpp | 55 +++++++++++++++++++++++ src/game/hexWorld/HexModelFactory.h | 23 ++++++++++ src/game/hexWorld/HexTile.h | 25 +++++++++++ src/game/hexWorld/Map.cpp | 15 +++++++ src/game/hexWorld/Map.h | 24 ++++++++++ src/game/hexWorld/MapGenerator.cpp | 5 +++ src/game/hexWorld/MapGenerator.h | 39 ++++++++++++++++ 17 files changed, 263 insertions(+), 44 deletions(-) create mode 100644 assets/dragon/dragon.png rename src/{engine/layer => game}/GameLayer.cpp (51%) rename src/{engine/layer => game}/GameLayer.h (57%) create mode 100644 src/game/hexWorld/HexModelFactory.cpp create mode 100644 src/game/hexWorld/HexModelFactory.h create mode 100644 src/game/hexWorld/HexTile.h create mode 100644 src/game/hexWorld/Map.cpp create mode 100644 src/game/hexWorld/Map.h create mode 100644 src/game/hexWorld/MapGenerator.cpp create mode 100644 src/game/hexWorld/MapGenerator.h diff --git a/.gitmodules b/.gitmodules index d94eda4..f965af7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,6 +4,3 @@ [submodule "lib/glm"] path = lib/glm url = https://github.com/g-truc/glm.git -[submodule "lib/tinyobjloader"] - path = lib/tinyobjloader - url = https://github.com/tinyobjloader/tinyobjloader.git diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 39268c1..b75e802 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -4,5 +4,6 @@ + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f04234c..3db3f68 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,8 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/renderer/Renderer.h src/engine/layer/Layer.cpp src/engine/layer/Layer.h - src/engine/layer/GameLayer.cpp - src/engine/layer/GameLayer.h + src/game/GameLayer.cpp + src/game/GameLayer.h src/engine/renderer/shaders/ShaderProgram.cpp src/engine/renderer/shaders/ShaderProgram.h src/engine/renderer/shaders/StaticShader.cpp @@ -58,6 +58,13 @@ add_executable(Dicewars_Siedler src/main.cpp src/engine/layer/entities/Light.h src/engine/platform/glfw/MousePicker.cpp src/engine/platform/glfw/MousePicker.h + src/game/hexWorld/HexTile.h + src/game/hexWorld/Map.cpp + src/game/hexWorld/Map.h + src/game/hexWorld/MapGenerator.cpp + src/game/hexWorld/MapGenerator.h + src/game/hexWorld/HexModelFactory.cpp + src/game/hexWorld/HexModelFactory.h ) target_include_directories(Dicewars_Siedler PRIVATE diff --git a/assets/dragon/dragon.png b/assets/dragon/dragon.png new file mode 100644 index 0000000000000000000000000000000000000000..1d78510c9e752d71ec53ab2969f9655daec7acfa GIT binary patch literal 1606 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&t&wwUqN(AjMc5+H3kOOIi4<#Ar-gYUNsbCFyLU= z81(bw6L6Vn1LT&&0sYaDagUXbTSmS& terrain) { prepare(camera, light); staticShader.start(); renderRawModel(entity); + for (const auto& terrainTile : terrain) { + renderHexTile(terrainTile); + } staticShader.stop(); } +void Renderer::renderHexTile(const HexRenderData& tile) { + auto texturedModel = tile.model; + auto model = texturedModel->getRawModel(); + + glBindVertexArray(model->vaoID); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(tile.position, 0, 0, 0, 1.f); + staticShader.loadTransformationMatrix(transformationMatrix); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texturedModel->getTexture()->getTextureID()); + glDrawElements(GL_TRIANGLES , model->vertexCount, GL_UNSIGNED_INT, 0); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glBindVertexArray(0); +} + void Renderer::renderRawModel(const Entity& entity) { auto texturedModel = entity.getModel(); auto model = texturedModel->getRawModel(); diff --git a/src/engine/renderer/Renderer.h b/src/engine/renderer/Renderer.h index 1ba7fa2..6da20e6 100644 --- a/src/engine/renderer/Renderer.h +++ b/src/engine/renderer/Renderer.h @@ -4,12 +4,14 @@ #ifndef DICEWARS_SIEDLER_RENDERER_H #define DICEWARS_SIEDLER_RENDERER_H +#include "../../game/hexWorld/HexTile.h" #include "../layer/entities/Entity.h" #include "model/RawModel.h" #include "model/TexturedModel.h" #include "shaders/StaticShader.h" + class Light; class Camera; @@ -21,7 +23,10 @@ public: staticShader.stop(); }; void prepare(const ::Camera &camera, const Light& light); - void renderFrame(const ::Entity &entity, const ::Camera &camera, const Light& light); + void renderFrame(const ::Entity &entity, const ::Camera &camera, const ::Light &light, const std::vector &terrainTiles); + + void renderHexTile(const HexRenderData &tile); + [[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;} private: void renderRawModel(const Entity &entity); diff --git a/src/game/DicewarsApp.cpp b/src/game/DicewarsApp.cpp index a15d92d..a8c80c7 100644 --- a/src/game/DicewarsApp.cpp +++ b/src/game/DicewarsApp.cpp @@ -4,7 +4,7 @@ #include "DicewarsApp.h" -#include "../engine/layer/GameLayer.h" +#include "GameLayer.h" DicewarsApp::DicewarsApp() { pushLayer(new GameLayer()); diff --git a/src/engine/layer/GameLayer.cpp b/src/game/GameLayer.cpp similarity index 51% rename from src/engine/layer/GameLayer.cpp rename to src/game/GameLayer.cpp index ec0acab..bcbed58 100644 --- a/src/engine/layer/GameLayer.cpp +++ b/src/game/GameLayer.cpp @@ -4,13 +4,15 @@ #include "GameLayer.h" -#include "../platform/glfw/InputManager.h" -#include "../renderer/Renderer.h" -#include "../renderer/loader/OBJLoader.h" -#include "../renderer/model/TexturedModel.h" -#include "../renderer/textures/ModelTexture.h" -#include "../toolbox/MathUtils.h" -#include "entities/Light.h" +#include "../engine/platform/glfw/InputManager.h" +#include "../engine/renderer/Renderer.h" +#include "../engine/renderer/loader/OBJLoader.h" +#include "../engine/renderer/model/TexturedModel.h" +#include "../engine/renderer/textures/ModelTexture.h" +#include "../engine/toolbox/MathUtils.h" +#include "../engine/layer/entities/Light.h" +#include "hexWorld/HexModelFactory.h" +#include "hexWorld/MapGenerator.h" GameLayer::GameLayer() :texturedModel(0,0) //Platzhalter, echtes Model kommt in onAttach { @@ -18,30 +20,17 @@ GameLayer::GameLayer() :texturedModel(0,0) //Platzhalter, echtes Model kommt in void GameLayer::onAttach() { - std::vector vertices = { - -0.5f, 0.5f, 0.f,//v0 - -0.5f, -0.5f, 0.f,//v1 - 0.5f, -0.5f, 0.f,//v2 - 0.5f, 0.5f, 0.f,//v3 - }; - - std::vector indices = { - 0,1,3, - 3,1,2 - }; - - std::vector textureCoords = { - 0,0, //v0 - 0,1, // v1 - 1,1, // v2 - 1,0 //v3 - }; - texturedModel = *OBJLoader::loadModel("assets/dragon/dragon.obj", "assets/dragon/dragon.png", loader); entity = std::make_unique(Entity(std::make_shared(texturedModel), glm::vec3(0,0,-25), 0,0,0, 1.f)); camera = std::make_unique(); - light = std::make_unique(glm::vec3(0,0,-20), glm::vec3(1,1,1)); + light = std::make_unique(glm::vec3(0,10,0), glm::vec3(1,1,1)); mousePicker = std::make_unique(renderer.getProjectionMatrix(), MathUtils::createViewMatrix(*camera)); + + //Map Generation + hexModel = std::make_shared(HexModelFactory::createTexturedHexModel(loader)); + map = std::make_unique(); + MapGenerator::generateHexMap(*map, 10,10,1.f); + printf("Generated Terrain with %lu Tiles!\n", map->tiles.size()); } void GameLayer::onDetach() @@ -52,16 +41,20 @@ void GameLayer::onDetach() void GameLayer::onUpdate() { mousePicker->update(*camera); - printf("Mouse Ray: %f, %f, %f\n", mousePicker->getCurrentRay().x, mousePicker->getCurrentRay().y, mousePicker->getCurrentRay().z); + //printf("Mouse Ray: %f, %f, %f\n", mousePicker->getCurrentRay().x, mousePicker->getCurrentRay().y, mousePicker->getCurrentRay().z); glm::vec3 moveDir = glm::vec3(0,0,0); if (InputManager::isKeyPressed(GLFW_KEY_W)) moveDir.z -= 1.0f; if (InputManager::isKeyPressed(GLFW_KEY_S)) moveDir.z += 1.0f; if (InputManager::isKeyPressed(GLFW_KEY_A)) moveDir.x -= 1.0f; if (InputManager::isKeyPressed(GLFW_KEY_D)) moveDir.x += 1.0f; + + entity->increaseRotation(0,1,0); camera->move(moveDir, 0.5f); - renderer.renderFrame(*entity, *camera, *light); + + std::vector terrainRenderData = map->getTerrainRenderData(hexModel); + renderer.renderFrame(*entity, *camera, *light, terrainRenderData); } diff --git a/src/engine/layer/GameLayer.h b/src/game/GameLayer.h similarity index 57% rename from src/engine/layer/GameLayer.h rename to src/game/GameLayer.h index 37a848f..c4c1c7c 100644 --- a/src/engine/layer/GameLayer.h +++ b/src/game/GameLayer.h @@ -4,12 +4,13 @@ #ifndef DICEWARS_SIEDLER_GAMELAYER_H #define DICEWARS_SIEDLER_GAMELAYER_H -#include "Layer.h" -#include "../platform/glfw/MousePicker.h" -#include "../renderer/Renderer.h" -#include "../renderer/loader/Loader.h" -#include "../renderer/model/TexturedModel.h" -#include "entities/Camera.h" +#include "../engine/layer/Layer.h" +#include "../engine/platform/glfw/MousePicker.h" +#include "../engine/renderer/Renderer.h" +#include "../engine/renderer/loader/Loader.h" +#include "../engine/renderer/model/TexturedModel.h" +#include "../engine/layer/entities/Camera.h" +#include "hexWorld/Map.h" class GameLayer: public Layer { @@ -29,6 +30,9 @@ private: std::unique_ptr light; std::unique_ptr mousePicker; Renderer renderer; + + std::shared_ptr hexModel; + std::unique_ptr map; }; diff --git a/src/game/hexWorld/HexModelFactory.cpp b/src/game/hexWorld/HexModelFactory.cpp new file mode 100644 index 0000000..bf2a703 --- /dev/null +++ b/src/game/hexWorld/HexModelFactory.cpp @@ -0,0 +1,55 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "HexModelFactory.h" + +#include + +#include "../../engine/renderer/loader/Loader.h" +#include "glm/trigonometric.hpp" + +RawModel HexModelFactory::createHexRawModel(Loader &loader, float radius) { + std::vector vertices; + std::vector uvs; + std::vector indices; + std::vector normals; + + vertices.insert(vertices.end(), {0.f, 0.f, 0.f}); + normals.insert(normals.end(), {0.f, 1.f, 0.f}); + uvs.insert(uvs.end(), {0.5f, 0.5f}); + + for (int i = 0; i < 6; i++) { + float angle = glm::radians((60.f * i - 30.0f)); + float x = radius * std::cos(angle); + float z = radius * std::sin(angle); + + //Vertex positions + vertices.push_back(x); + vertices.push_back(0.0f); + vertices.push_back(z); + + //Normals + normals.push_back(0.0f); + normals.push_back(1.0f); + normals.push_back(0.0f); + + //uvs mapped to circle + uvs.push_back((x / radius + 1.f) * 0.5f); + uvs.push_back((z / radius + 1.f) * 0.5f); + } + + for (int i = 1; i <= 6; ++i) { + indices.push_back(0); + indices.push_back(i); + indices.push_back(i % 6 + 1); + } + + return loader.loadToVAO(vertices, normals, uvs, indices); +} + +TexturedModel HexModelFactory::createTexturedHexModel(Loader &loader, float radius) { + RawModel rawModel = createHexRawModel(loader, radius); + ModelTexture modelTexture = loader.loadTextureFromFile("assets/hex/white.png"); + return {std::make_shared(rawModel), std::make_shared(modelTexture)}; +} diff --git a/src/game/hexWorld/HexModelFactory.h b/src/game/hexWorld/HexModelFactory.h new file mode 100644 index 0000000..e71ff74 --- /dev/null +++ b/src/game/hexWorld/HexModelFactory.h @@ -0,0 +1,23 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef HEXMODELFACTORY_H +#define HEXMODELFACTORY_H +#include "../../engine/renderer/model/RawModel.h" +#include "../../engine/renderer/model/TexturedModel.h" + + +class Loader; + +class HexModelFactory { +public: + + static TexturedModel createTexturedHexModel(Loader& loader, float radius = 1.0f); +private: + static RawModel createHexRawModel(Loader& loader, float radius = 1.0f); +}; + + + +#endif //HEXMODELFACTORY_H diff --git a/src/game/hexWorld/HexTile.h b/src/game/hexWorld/HexTile.h new file mode 100644 index 0000000..8cfe655 --- /dev/null +++ b/src/game/hexWorld/HexTile.h @@ -0,0 +1,25 @@ +// +// Created by sebastian on 07.02.26. +// + +#ifndef HEXTILE_H +#define HEXTILE_H +#include + +#include "../../engine/renderer/model/TexturedModel.h" +#include "glm/vec3.hpp" + +struct HexTile { + glm::vec3 worldPos; + int q, r; //Axiale Koordinaten (hex-Koordinaten) + int ownerID = -1; + //Later: ResourceType +}; + +struct HexRenderData { + std::shared_ptr model; + glm::vec3 position; + bool highlight = false; +}; + +#endif //HEXTILE_H diff --git a/src/game/hexWorld/Map.cpp b/src/game/hexWorld/Map.cpp new file mode 100644 index 0000000..2891798 --- /dev/null +++ b/src/game/hexWorld/Map.cpp @@ -0,0 +1,15 @@ +// +// Created by sebastian on 07.02.26. +// + +#include "Map.h" + +std::vector Map::getTerrainRenderData(const std::shared_ptr& hexModel) { + std::vector renderData; + renderData.reserve(tiles.size()); + for (auto& tile : tiles) { + HexRenderData data = HexRenderData(hexModel, tile.worldPos, false); + renderData.push_back(data); + } + return renderData; +} diff --git a/src/game/hexWorld/Map.h b/src/game/hexWorld/Map.h new file mode 100644 index 0000000..341309b --- /dev/null +++ b/src/game/hexWorld/Map.h @@ -0,0 +1,24 @@ +// +// Created by sebastian on 07.02.26. +// + +#ifndef MAP_H +#define MAP_H +#include "HexTile.h" + +struct Area { + int id; + std::vector tiles; +}; + +class Map { +public: + std::vector areas; + std::vector tiles; + + std::vector getTerrainRenderData(const std::shared_ptr& hexModel); +}; + + + +#endif //MAP_H diff --git a/src/game/hexWorld/MapGenerator.cpp b/src/game/hexWorld/MapGenerator.cpp new file mode 100644 index 0000000..4d47824 --- /dev/null +++ b/src/game/hexWorld/MapGenerator.cpp @@ -0,0 +1,5 @@ +// +// Created by sebastian on 07.02.26. +// + +#include "MapGenerator.h" diff --git a/src/game/hexWorld/MapGenerator.h b/src/game/hexWorld/MapGenerator.h new file mode 100644 index 0000000..b1d9643 --- /dev/null +++ b/src/game/hexWorld/MapGenerator.h @@ -0,0 +1,39 @@ +// +// Created by sebastian on 07.02.26. +// + +#ifndef MAPGENERATOR_H +#define MAPGENERATOR_H +#include + +#include "HexTile.h" +#include "Map.h" + +class MapGenerator { +public: + static void generateHexMap(Map& map, int width, int height, float hexRadius) { + map.tiles.clear(); + + float xOffset = hexRadius * std::sqrt(3.0f); + float zOffset = hexRadius * 1.5f; + + for (int r = 0; r < height; ++r) { + for (int q = 0; q < width; ++q) { + HexTile tile; + tile.q = q; + tile.r = r; + + // Pointy-top Hexes + float x = xOffset * (q + 0.5f * (r % 2)); + float z = zOffset * r; + tile.worldPos = glm::vec3(x, 0.0f, z); + + map.tiles.push_back(tile); + } + } + } +}; + + + +#endif //MAPGENERATOR_H