UPD: Refactor Renderer to be Entity Specific

This commit is contained in:
sebastian 2026-02-08 08:34:21 +01:00
parent dbc61d2e64
commit 14e7a5e3b0
7 changed files with 116 additions and 60 deletions

View File

@ -65,6 +65,8 @@ add_executable(Dicewars_Siedler src/main.cpp
src/game/hexWorld/MapGenerator.h src/game/hexWorld/MapGenerator.h
src/game/hexWorld/HexModelFactory.cpp src/game/hexWorld/HexModelFactory.cpp
src/game/hexWorld/HexModelFactory.h src/game/hexWorld/HexModelFactory.h
src/engine/renderer/MasterRenderer.cpp
src/engine/renderer/MasterRenderer.h
) )
target_include_directories(Dicewars_Siedler PRIVATE target_include_directories(Dicewars_Siedler PRIVATE

View File

@ -0,0 +1,35 @@
//
// Created by sebastian on 08.02.26.
//
#include "MasterRenderer.h"
#include "../core/Application.h"
#include "glm/ext/matrix_clip_space.hpp"
void MasterRenderer::render(const Light &light, const Camera &camera) {
entityRenderer->prepare(camera, light);
entityRenderer->renderEntities(entities);
entityRenderer->finalizeFrame();
entities.clear();
}
void MasterRenderer::submitEntity(Entity *entity) {
TexturedModel* entityModel = entity->getModel().get();
entities[entityModel].push_back(entity);
}
glm::mat4 MasterRenderer::createProjectionMatrix() {
float aspectRatio = static_cast<float>(Application::getInstance().getWindow().GetWidth()) / static_cast<float>(Application::getInstance().getWindow().GetHeight());
glm::mat4 projection = glm::perspective(
glm::radians(FOV),
aspectRatio,
NEAR_PLANE,
FAR_PLANE
);
return projection;
}

View File

@ -0,0 +1,42 @@
//
// Created by sebastian on 08.02.26.
//
#ifndef MASTERRENDERER_H
#define MASTERRENDERER_H
#include <unordered_map>
#include <vector>
#include "Renderer.h"
#include "../../game/hexWorld/HexTile.h"
#include "../layer/entities/Entity.h"
#include "model/TexturedModel.h"
class Camera;
class Light;
class MasterRenderer {
private:
std::unordered_map<TexturedModel*, std::vector<Entity*>> entities;
std::unordered_map<TexturedModel*, std::vector<HexRenderData*>> terrainTiles;
glm::mat4 projectionMatrix;
std::unique_ptr<Renderer> entityRenderer;
constexpr static float FOV = 70.0f;
constexpr static float NEAR_PLANE = 0.1f;
constexpr static float FAR_PLANE = 1000.0f;
static glm::mat4 createProjectionMatrix();
public:
MasterRenderer() : projectionMatrix(createProjectionMatrix()), entityRenderer(std::make_unique<Renderer>(projectionMatrix)){};
void render(const Light &light, const Camera &camera);
void submitEntity(Entity* entity);
[[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;}
};
#endif //MASTERRENDERER_H

View File

@ -4,6 +4,8 @@
#include "Renderer.h" #include "Renderer.h"
#include <ranges>
#include "../../game/hexWorld/HexTile.h" #include "../../game/hexWorld/HexTile.h"
#include "../core/Application.h" #include "../core/Application.h"
#include "../layer/entities/Light.h" #include "../layer/entities/Light.h"
@ -23,71 +25,47 @@ void Renderer::prepare(const Camera& camera, const Light& light) {
staticShader.start(); staticShader.start();
staticShader.loadLight(light.getPosition(), light.getColor()); staticShader.loadLight(light.getPosition(), light.getColor());
staticShader.loadViewMatrix(viewMatrix); staticShader.loadViewMatrix(viewMatrix);
staticShader.stop();
} }
void Renderer::renderFrame(const Entity &entity, const Camera& camera, const Light& light, const std::vector<HexRenderData>& terrain) {
prepare(camera, light); void Renderer::renderEntities(const std::unordered_map<TexturedModel *, std::vector<Entity *>>& entities) {
staticShader.start(); for (const auto& [texturedModel, batch] : entities) {
renderRawModel(entity); prepareTexturedModel(*texturedModel);
for (const auto& terrainTile : terrain) { for (const auto& entity : batch) {
renderHexTile(terrainTile); prepareInstance(*entity);
glDrawElements(GL_TRIANGLES, texturedModel->getRawModel()->vertexCount, GL_UNSIGNED_INT, 0);
}
unbindTexturedModel();
} }
staticShader.stop();
} }
void Renderer::renderHexTile(const HexRenderData& tile) { void Renderer::prepareTexturedModel(const TexturedModel &texturedModel) {
auto texturedModel = tile.model; auto rawModel = texturedModel.getRawModel();
auto model = texturedModel->getRawModel(); glBindVertexArray(rawModel->vaoID);
glBindVertexArray(model->vaoID);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(tile.position, 0, 0, 0, 1.f);
staticShader.loadTransformationMatrix(transformationMatrix);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texturedModel->getTexture()->getTextureID()); glBindTexture(GL_TEXTURE_2D, texturedModel.getTexture()->getTextureID());
glDrawElements(GL_TRIANGLES , model->vertexCount, GL_UNSIGNED_INT, 0); }
void Renderer::unbindTexturedModel() {
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1); glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2); glDisableVertexAttribArray(2);
glBindVertexArray(0); glBindVertexArray(0);
} }
void Renderer::renderRawModel(const Entity& entity) { void Renderer::prepareInstance(const Entity &entity) {
auto texturedModel = entity.getModel();
auto model = texturedModel->getRawModel();
glBindVertexArray(model->vaoID);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(entity.getPosition(), entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale()); glm::mat4 transformationMatrix = MathUtils::createTransformationMatrix(entity.getPosition(), entity.getRotX(), entity.getRotY(), entity.getRotZ(), entity.getScale());
staticShader.loadTransformationMatrix(transformationMatrix); 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);
} }
glm::mat4 Renderer::createProjectionMatrix() { void Renderer::finalizeFrame() {
float aspectRatio = static_cast<float>(Application::getInstance().getWindow().GetWidth()) / static_cast<float>(Application::getInstance().getWindow().GetHeight()); staticShader.stop();
glm::mat4 projection = glm::perspective(
glm::radians(FOV),
aspectRatio,
NEAR_PLANE,
FAR_PLANE
);
return projection;
} }

View File

@ -17,7 +17,7 @@ class Camera;
class Renderer { class Renderer {
public: public:
Renderer() : projectionMatrix(createProjectionMatrix()) { explicit Renderer(const glm::mat4 &projectionMatrix) {
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
@ -26,21 +26,17 @@ public:
staticShader.stop(); staticShader.stop();
}; };
void prepare(const ::Camera &camera, const Light& light); void prepare(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); void renderEntities(const std::unordered_map<TexturedModel *, std::vector<Entity *>> &entities);
void finalizeFrame();
[[nodiscard]] glm::mat4 getProjectionMatrix() const {return projectionMatrix;}
private: private:
void renderRawModel(const Entity &entity);
StaticShader staticShader; StaticShader staticShader;
glm::mat4 projectionMatrix; void prepareTexturedModel(const TexturedModel &texturedModel);
constexpr static float FOV = 70.0f; void unbindTexturedModel();
constexpr static float NEAR_PLANE = 0.1f; void prepareInstance(const Entity &entity);
constexpr static float FAR_PLANE = 1000.0f;
static glm::mat4 createProjectionMatrix();
}; };

View File

@ -24,7 +24,7 @@ void GameLayer::onAttach()
entity = std::make_unique<Entity>(Entity(std::make_shared<TexturedModel>(texturedModel), glm::vec3(0,0,-25), 0,0,0, 1.f)); 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>(); camera = std::make_unique<Camera>();
light = std::make_unique<Light>(glm::vec3(0,10,0), 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)); mousePicker = std::make_unique<MousePicker>(renderer->getProjectionMatrix(), MathUtils::createViewMatrix(*camera));
//Map Generation //Map Generation
hexModel = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader)); hexModel = std::make_shared<TexturedModel>(HexModelFactory::createTexturedHexModel(loader));
@ -54,7 +54,9 @@ void GameLayer::onUpdate()
camera->move(moveDir, 0.5f); camera->move(moveDir, 0.5f);
std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModel); std::vector<HexRenderData> terrainRenderData = map->getTerrainRenderData(hexModel);
renderer.renderFrame(*entity, *camera, *light, terrainRenderData); renderer->submitEntity(entity.get());
renderer->render(*light, *camera);
} }

View File

@ -10,6 +10,7 @@
#include "../engine/renderer/loader/Loader.h" #include "../engine/renderer/loader/Loader.h"
#include "../engine/renderer/model/TexturedModel.h" #include "../engine/renderer/model/TexturedModel.h"
#include "../engine/layer/entities/Camera.h" #include "../engine/layer/entities/Camera.h"
#include "../engine/renderer/MasterRenderer.h"
#include "hexWorld/Map.h" #include "hexWorld/Map.h"
@ -29,7 +30,7 @@ private:
std::unique_ptr<Camera> camera; std::unique_ptr<Camera> camera;
std::unique_ptr<Light> light; std::unique_ptr<Light> light;
std::unique_ptr<MousePicker> mousePicker; std::unique_ptr<MousePicker> mousePicker;
Renderer renderer; std::unique_ptr<MasterRenderer> renderer = std::make_unique<MasterRenderer>();
std::shared_ptr<TexturedModel> hexModel; std::shared_ptr<TexturedModel> hexModel;
std::unique_ptr<Map> map; std::unique_ptr<Map> map;