diff --git a/CMakeLists.txt b/CMakeLists.txt index 579d689..245b226 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,8 @@ add_executable(Dicewars_Siedler src/main.cpp src/game/hexWorld/HexModelFactory.h src/engine/renderer/MasterRenderer.cpp src/engine/renderer/MasterRenderer.h + src/engine/renderer/TerrainRenderer.cpp + src/engine/renderer/TerrainRenderer.h ) target_include_directories(Dicewars_Siedler PRIVATE diff --git a/src/engine/renderer/MasterRenderer.cpp b/src/engine/renderer/MasterRenderer.cpp index 3e4b81e..bbb98ea 100644 --- a/src/engine/renderer/MasterRenderer.cpp +++ b/src/engine/renderer/MasterRenderer.cpp @@ -8,11 +8,20 @@ #include "glm/ext/matrix_clip_space.hpp" void MasterRenderer::render(const Light &light, const Camera &camera) { + glEnable(GL_DEPTH_TEST); + glClearColor(1.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + entityRenderer->prepare(camera, light); entityRenderer->renderEntities(entities); entityRenderer->finalizeFrame(); entities.clear(); + terrainRenderer->prepare(camera, light); + terrainRenderer->renderTerrainTiles(terrainTiles); + terrainRenderer->finalizeFrame(); + terrainTiles.clear(); + } void MasterRenderer::submitEntity(Entity *entity) { @@ -20,6 +29,10 @@ void MasterRenderer::submitEntity(Entity *entity) { entities[entityModel].push_back(entity); } +void MasterRenderer::submitTerrainTile(HexRenderData *tile) { + terrainTiles[tile->model.get()].push_back(tile); +} + glm::mat4 MasterRenderer::createProjectionMatrix() { float aspectRatio = static_cast(Application::getInstance().getWindow().GetWidth()) / static_cast(Application::getInstance().getWindow().GetHeight()); diff --git a/src/engine/renderer/MasterRenderer.h b/src/engine/renderer/MasterRenderer.h index f211d92..848cf5f 100644 --- a/src/engine/renderer/MasterRenderer.h +++ b/src/engine/renderer/MasterRenderer.h @@ -8,6 +8,7 @@ #include #include "Renderer.h" +#include "TerrainRenderer.h" #include "../../game/hexWorld/HexTile.h" #include "../layer/entities/Entity.h" #include "model/TexturedModel.h" @@ -22,6 +23,7 @@ private: std::unordered_map> terrainTiles; glm::mat4 projectionMatrix; std::unique_ptr entityRenderer; + std::unique_ptr terrainRenderer; constexpr static float FOV = 70.0f; constexpr static float NEAR_PLANE = 0.1f; constexpr static float FAR_PLANE = 1000.0f; @@ -29,10 +31,16 @@ private: static glm::mat4 createProjectionMatrix(); public: - MasterRenderer() : projectionMatrix(createProjectionMatrix()), entityRenderer(std::make_unique(projectionMatrix)){}; + MasterRenderer() : projectionMatrix(createProjectionMatrix()), entityRenderer(std::make_unique(projectionMatrix)), + terrainRenderer(std::make_unique(projectionMatrix)) + { + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + }; void render(const Light &light, const Camera &camera); void submitEntity(Entity* entity); + void submitTerrainTile(HexRenderData* tile); [[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;} }; diff --git a/src/engine/renderer/Renderer.cpp b/src/engine/renderer/Renderer.cpp index 2ad3e22..48e489f 100644 --- a/src/engine/renderer/Renderer.cpp +++ b/src/engine/renderer/Renderer.cpp @@ -17,10 +17,6 @@ void Renderer::prepare(const Camera& camera, const Light& light) { - glEnable(GL_DEPTH_TEST); - glClearColor(1.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera); staticShader.start(); staticShader.loadLight(light.getPosition(), light.getColor()); diff --git a/src/engine/renderer/Renderer.h b/src/engine/renderer/Renderer.h index 9234e94..c8579d9 100644 --- a/src/engine/renderer/Renderer.h +++ b/src/engine/renderer/Renderer.h @@ -18,9 +18,6 @@ class Camera; class Renderer { public: explicit Renderer(const glm::mat4 &projectionMatrix) { - glEnable(GL_CULL_FACE); - glCullFace(GL_BACK); - staticShader.start(); staticShader.loadProjectionMatrix(projectionMatrix); staticShader.stop(); diff --git a/src/engine/renderer/TerrainRenderer.cpp b/src/engine/renderer/TerrainRenderer.cpp new file mode 100644 index 0000000..31c3ddc --- /dev/null +++ b/src/engine/renderer/TerrainRenderer.cpp @@ -0,0 +1,54 @@ +// +// Created by sebastian on 08.02.26. +// + +#include "TerrainRenderer.h" + +#include "../toolbox/MathUtils.h" + +void TerrainRenderer::prepare(const Camera &camera, const Light &light) { + const glm::mat4 viewMatrix = MathUtils::createViewMatrix(camera); + staticShader.start(); + staticShader.loadLight(light.getPosition(), light.getColor()); + staticShader.loadViewMatrix(viewMatrix); +} + +void TerrainRenderer::renderTerrainTiles(const std::unordered_map> &terrainTiles) { + for (const auto& [texturedModel, batch] : terrainTiles) { + prepareTexturedModel(*texturedModel); + for (const auto& hexTile : batch) { + prepareInstance(*hexTile); + printf("Render terrain Tile at %f, %f, %f!\n", hexTile->position.x, hexTile->position.y, hexTile->position.z); + glDrawElements(GL_TRIANGLES, texturedModel->getRawModel()->vertexCount, GL_UNSIGNED_INT, 0); + } + unbindTexturedModel(); + } + +} + +void TerrainRenderer::finalizeFrame() { + staticShader.stop(); +} + +void TerrainRenderer::prepareTexturedModel(const TexturedModel &texturedModel) { + auto rawModel = texturedModel.getRawModel(); + glBindVertexArray(rawModel->vaoID); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texturedModel.getTexture()->getTextureID()); +} + +void TerrainRenderer::unbindTexturedModel() { + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisableVertexAttribArray(2); + glBindVertexArray(0); +} + +void TerrainRenderer::prepareInstance(const HexRenderData &hexTile) { + glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(hexTile.position, 0,0,0,1); + staticShader.loadTransformationMatrix(transformationMatrix); +} diff --git a/src/engine/renderer/TerrainRenderer.h b/src/engine/renderer/TerrainRenderer.h new file mode 100644 index 0000000..76a1d03 --- /dev/null +++ b/src/engine/renderer/TerrainRenderer.h @@ -0,0 +1,36 @@ +// +// Created by sebastian on 08.02.26. +// + +#ifndef TERRAINRENDERER_H +#define TERRAINRENDERER_H +#include "../../game/hexWorld/HexTile.h" +#include "model/TexturedModel.h" +#include "shaders/StaticShader.h" + +#include "../layer/entities/Camera.h" +#include "../layer/entities/Light.h" + + +class TerrainRenderer { +public: + explicit TerrainRenderer(const glm::mat4 &projectionMatrix) { + staticShader.start(); + staticShader.loadProjectionMatrix(projectionMatrix); + staticShader.stop(); + } + + void prepare(const Camera &camera, const Light &light); + void renderTerrainTiles(const std::unordered_map>& terrainTiles); + void finalizeFrame(); +private: + StaticShader staticShader; + + void prepareTexturedModel(const TexturedModel &texturedModel); + void unbindTexturedModel(); + void prepareInstance(const HexRenderData& hexTile); +}; + + + +#endif //TERRAINRENDERER_H diff --git a/src/game/GameLayer.cpp b/src/game/GameLayer.cpp index c5ef74a..aee575c 100644 --- a/src/game/GameLayer.cpp +++ b/src/game/GameLayer.cpp @@ -53,8 +53,13 @@ void GameLayer::onUpdate() entity->increaseRotation(0,1,0); camera->move(moveDir, 0.5f); - std::vector terrainRenderData = map->getTerrainRenderData(hexModel); renderer->submitEntity(entity.get()); + std::vector terrainRenderData = map->getTerrainRenderData(hexModel); + + + for (auto& renderData : terrainRenderData) { + renderer->submitTerrainTile(&renderData); + } renderer->render(*light, *camera); }