Program Listing for File renderSystem.cpp
↰ Return to documentation for file (PrismEngine/src/renderSystem.cpp)
#include "renderSystem.h"
#include "cameraComponent.h"
#include "transformComponent.h"
#include "materialComponent.h"
#include "lightsComponent.h"
#include "linker.h"
#include "pipelineComponent.h"
void prism::scene::RenderSystem::start() {
renderer = prism::linker.find<prism::scene::Scene, prism::render::Renderer>(scene);
}
void prism::scene::RenderSystem::update()
{
if (renderer->isRenderingActive()) {
renderer->beginFrame();
auto cameras = scene->getEntitiesWithAll<TransformComponent, CameraComponent>();
for (auto camera : cameras) {
CameraComponent* cameraComponent = scene->getComponent<CameraComponent>(camera);
if (cameraComponent->isActive) {
TransformComponent* transformComponent = scene->getComponent<TransformComponent>(camera);
renderer->updateCamera(transformComponent, cameraComponent);
}
}
auto renderingObjects = scene->getEntitiesWithAll<TransformComponent, MeshComponent>();
batches.clear();
for (auto object : renderingObjects) {
TransformComponent* transform = scene->getComponent<TransformComponent>(object);
MeshComponent* mesh = scene->getComponent<MeshComponent>(object);
MaterialComponent* material = scene->getComponent<MaterialComponent>(object);
PipelineComponent* pipeline = scene->getComponent<PipelineComponent>(object);
const MeshComponent::DataType* subMeshes; uint16_t subMeshesCount = 0;
const MaterialComponent::DataType* subMaterials; uint16_t subMaterialsCount = 0;
PipelineIndex pipelineIndex = renderer->getDefaultPipeline().pipeline;
if (mesh->isValid()) subMeshes = scene->getDataFromPool(*mesh, subMeshesCount);
else { logger::info("NO FOUNND SUBMESH " + std::to_string(mesh->id) + "IN DATAPOOL"); continue; }
if (material->isValid()) subMaterials = scene->getDataFromPool(*material, subMaterialsCount);
else { logger::info("NO FOUNND SUBMATERIAL " + std::to_string(material->id) + "IN DATAPOOL"); continue; }
if (subMaterialsCount < subMeshesCount) logger::info("SUBMATERIALS COUNT(" + std::to_string(subMaterialsCount) + ") < SUBMESHES COUNT(" + std::to_string(subMeshesCount) + ")");
if (pipeline) pipelineIndex = pipeline->pipeline;
for (uint16_t i = 0; i < subMeshesCount; i++)
{
batches.push_back(prism::render::RenderObjectBatch(0, pipelineIndex, *(subMeshes+i),
transform, subMaterials+i));
}
}
if (batches.size() == 0) return;
std::sort(batches.begin(), batches.end());
prism::render::LightData lightData;
auto pointsLightEntitys = scene->getEntitiesWith<PointLightComponent>();
for (auto pointLightEntity : pointsLightEntitys) {
PointLightComponent pointsLight = *scene->getComponent<PointLightComponent>(pointLightEntity);
if (TransformComponent* transform = scene->getComponent<TransformComponent>(pointLightEntity)) { pointsLight.pos += transform->pos; }
lightData.pointLights.push_back(pointsLight);
}
auto directionalLightEntitys = scene->getEntitiesWith<DirectionalLightComponents>();
for (auto directionalLightEntity : directionalLightEntitys) {
DirectionalLightComponents* dirLight = scene->getComponent<DirectionalLightComponents>(directionalLightEntity);
lightData.directionalLights.push_back(*dirLight);
}
renderer->updateRenderObjects(batches);
renderer->updateLights(&lightData);
renderer->beginRender();
renderer->bindDefault();
renderer->bindObjectsData();
MeshComponent::DataType oldSubMesh = batches[0].subMesh;
PipelineIndex oldPipelineIndex = batches[0].pipeline;
uint32_t instanceCount = 0;
uint32_t firstIndex = 0;
for (auto& obj : batches) {
if (oldSubMesh != obj.subMesh) {
renderer->drawMesh(oldSubMesh, instanceCount, firstIndex);
firstIndex += instanceCount;
instanceCount = 0;
}
if (oldPipelineIndex != obj.pipeline) {
renderer->bindPipeline(obj.pipeline);
}
instanceCount++;
oldSubMesh = obj.subMesh;
oldPipelineIndex = obj.pipeline;
}
if (instanceCount > 0) {
renderer->drawMesh(oldSubMesh, instanceCount, firstIndex);
}
renderer->endRender();
renderer->endFrame();
batches.clear();
}
}