ADD: Render Terrain

This commit is contained in:
sebastian 2026-02-08 07:44:25 +01:00
parent 5ab79c8756
commit 997e1ccbb1
17 changed files with 263 additions and 44 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -4,5 +4,6 @@
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/glfw" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/glm" vcs="Git" />
<mapping directory="$PROJECT_DIR$/lib/tinyobjloader" vcs="Git" />
</component>
</project>

View File

@ -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

BIN
assets/dragon/dragon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -11,7 +11,7 @@
class Camera {
private:
glm::vec3 position = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 position = glm::vec3(0.0f, 5.0f, 0.0f);
float pitch = 0.0f;
float yaw = 0.0f;
float roll = 0.0f;

View File

@ -4,6 +4,7 @@
#include "Renderer.h"
#include "../../game/hexWorld/HexTile.h"
#include "../core/Application.h"
#include "../layer/entities/Light.h"
#include "../toolbox/MathUtils.h"
@ -25,13 +26,38 @@ void Renderer::prepare(const Camera& camera, const Light& light) {
staticShader.stop();
}
void Renderer::renderFrame(const Entity &entity, const Camera& camera, const Light& light) {
void Renderer::renderFrame(const Entity &entity, const Camera& camera, const Light& light, const std::vector<HexRenderData>& 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();

View File

@ -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<HexRenderData> &terrainTiles);
void renderHexTile(const HexRenderData &tile);
[[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;}
private:
void renderRawModel(const Entity &entity);

View File

@ -4,7 +4,7 @@
#include "DicewarsApp.h"
#include "../engine/layer/GameLayer.h"
#include "GameLayer.h"
DicewarsApp::DicewarsApp() {
pushLayer(new GameLayer());

View File

@ -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<float> 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<int> indices = {
0,1,3,
3,1,2
};
std::vector<float> 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>(Entity(std::make_shared<TexturedModel>(texturedModel), glm::vec3(0,0,-25), 0,0,0, 1.f));
camera = std::make_unique<Camera>();
light = std::make_unique<Light>(glm::vec3(0,0,-20), glm::vec3(1,1,1));
light = std::make_unique<Light>(glm::vec3(0,10,0), glm::vec3(1,1,1));
mousePicker = std::make_unique<MousePicker>(renderer.getProjectionMatrix(), MathUtils::createViewMatrix(*camera));
//Map Generation
hexModel = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader));
map = std::make_unique<Map>();
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<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModel);
renderer.renderFrame(*entity, *camera, *light, terrainRenderData);
}

View File

@ -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> light;
std::unique_ptr<MousePicker> mousePicker;
Renderer renderer;
std::shared_ptr<TexturedModel> hexModel;
std::unique_ptr<Map> map;
};

View File

@ -0,0 +1,55 @@
//
// Created by sebastian on 08.02.26.
//
#include "HexModelFactory.h"
#include <vector>
#include "../../engine/renderer/loader/Loader.h"
#include "glm/trigonometric.hpp"
RawModel HexModelFactory::createHexRawModel(Loader &loader, float radius) {
std::vector<float> vertices;
std::vector<float> uvs;
std::vector<int> indices;
std::vector<float> 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>(rawModel), std::make_shared<ModelTexture>(modelTexture)};
}

View File

@ -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

View File

@ -0,0 +1,25 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef HEXTILE_H
#define HEXTILE_H
#include <memory>
#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<TexturedModel> model;
glm::vec3 position;
bool highlight = false;
};
#endif //HEXTILE_H

15
src/game/hexWorld/Map.cpp Normal file
View File

@ -0,0 +1,15 @@
//
// Created by sebastian on 07.02.26.
//
#include "Map.h"
std::vector<HexRenderData> Map::getTerrainRenderData(const std::shared_ptr<TexturedModel>& hexModel) {
std::vector<HexRenderData> renderData;
renderData.reserve(tiles.size());
for (auto& tile : tiles) {
HexRenderData data = HexRenderData(hexModel, tile.worldPos, false);
renderData.push_back(data);
}
return renderData;
}

24
src/game/hexWorld/Map.h Normal file
View File

@ -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<HexTile*> tiles;
};
class Map {
public:
std::vector<Area> areas;
std::vector<HexTile> tiles;
std::vector<HexRenderData> getTerrainRenderData(const std::shared_ptr<TexturedModel>& hexModel);
};
#endif //MAP_H

View File

@ -0,0 +1,5 @@
//
// Created by sebastian on 07.02.26.
//
#include "MapGenerator.h"

View File

@ -0,0 +1,39 @@
//
// Created by sebastian on 07.02.26.
//
#ifndef MAPGENERATOR_H
#define MAPGENERATOR_H
#include <cmath>
#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