Add separate getRenderObjects function
This will make the functions clearer when shadow rendering is added.
This commit is contained in:
parent
51c0cb22d2
commit
5f30873f23
@ -20,106 +20,6 @@ using namespace ECS;
|
|||||||
|
|
||||||
class RenderSystem : public EntitySystem {
|
class RenderSystem : public EntitySystem {
|
||||||
public:
|
public:
|
||||||
void render(World *pWorld, Shader shader) {
|
|
||||||
|
|
||||||
pWorld->each<Camera, Transform>([&](Entity *ent, ComponentHandle<Camera> camera, ComponentHandle<Transform> cameraTransform) {
|
|
||||||
glClearColor(0.6f, 0.9f, 0.9f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
||||||
|
|
||||||
shader.use();
|
|
||||||
|
|
||||||
// Lighting
|
|
||||||
// TODO: Currently only the last light is used!
|
|
||||||
pWorld->each<DirectionalLight>([&](Entity *ent, ComponentHandle<DirectionalLight> light) {
|
|
||||||
shader.setVec3("lightDirection", light->direction);
|
|
||||||
});
|
|
||||||
|
|
||||||
glm::vec3 cameraPos = cameraTransform->get_origin();
|
|
||||||
|
|
||||||
glm::mat4 view = cameraTransform->matrix;
|
|
||||||
view[3] = glm::vec4(cameraPos, 1.0);
|
|
||||||
|
|
||||||
shader.setMat4("projection", camera->projection);
|
|
||||||
shader.setMat4("view", glm::inverse(view));
|
|
||||||
shader.setVec3("cameraPosition", cameraTransform->get_origin());
|
|
||||||
|
|
||||||
std::vector<RenderObject> renderObjects;
|
|
||||||
std::vector<RenderObject> transparentRenderObjects;
|
|
||||||
|
|
||||||
/*pWorld->each<Mesh, Transform>([&](Entity *ent, ComponentHandle<Mesh> mesh, ComponentHandle<Transform> transform) {
|
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), 0));
|
|
||||||
});*/
|
|
||||||
|
|
||||||
/*// TODO: Is it possible to do get ObjMeshes in the Mesh loop above implicitly via polymorphism?
|
|
||||||
* // TODO: Commented out because of double rendering - we only want to get objects that explicitly DON'T have a texture here!
|
|
||||||
pWorld->each<ObjMesh, Transform>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
|
||||||
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
|
||||||
float distance = glm::distance(cameraPos, transform->getPosition());
|
|
||||||
|
|
||||||
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), distance));
|
|
||||||
}
|
|
||||||
});*/
|
|
||||||
|
|
||||||
// ObjMesh with textures
|
|
||||||
pWorld->each<ObjMesh, Transform, Texture>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform, ComponentHandle<Texture> texture) {
|
|
||||||
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
|
||||||
float distance = glm::distance(cameraPos, transform->get_origin());
|
|
||||||
|
|
||||||
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
|
||||||
// Get optional components
|
|
||||||
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
|
||||||
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
|
||||||
|
|
||||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
|
||||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
|
||||||
|
|
||||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
|
||||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
|
||||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
|
||||||
} else {
|
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// LODObjMesh with Texture
|
|
||||||
pWorld->each<LODObjMesh, Transform>([&](Entity *ent, ComponentHandle<LODObjMesh> lodMesh, ComponentHandle<Transform> transform) {
|
|
||||||
float distance = glm::distance(cameraPos, transform->get_origin());
|
|
||||||
|
|
||||||
for (const auto &mesh : lodMesh->meshes) {
|
|
||||||
if (distance > mesh.minDistance && distance < mesh.maxDistance) {
|
|
||||||
// Get optional components
|
|
||||||
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
|
||||||
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
|
||||||
|
|
||||||
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
|
||||||
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
|
||||||
|
|
||||||
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
|
||||||
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
|
||||||
transparentRenderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
|
||||||
} else {
|
|
||||||
renderObjects.emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const RenderObject &obj : renderObjects) {
|
|
||||||
obj.render(shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort transparent objects and render them
|
|
||||||
std::sort(transparentRenderObjects.begin(), transparentRenderObjects.end(), [](const RenderObject &first, const RenderObject &second) -> bool {
|
|
||||||
return first.distance > second.distance;
|
|
||||||
});
|
|
||||||
for (const RenderObject &obj : transparentRenderObjects) {
|
|
||||||
obj.render(shader);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
struct RenderObject {
|
struct RenderObject {
|
||||||
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, const Mesh &mesh, float distance, const Material &material)
|
RenderObject(const glm::mat4 &matrix, const glm::vec3 &origin, unsigned int textureId, const Mesh &mesh, float distance, const Material &material)
|
||||||
: matrix(matrix),
|
: matrix(matrix),
|
||||||
@ -152,6 +52,113 @@ public:
|
|||||||
float distance;
|
float distance;
|
||||||
Material material;
|
Material material;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fill the passed vector with render objects of the given world
|
||||||
|
std::vector<std::vector<RenderObject>> getRenderObjects(World *world, glm::vec3 cameraPos) {
|
||||||
|
std::vector<std::vector<RenderObject>> renderObjects(2); // First normal, then transparent
|
||||||
|
|
||||||
|
/*pWorld->each<Mesh, Transform>([&](Entity *ent, ComponentHandle<Mesh> mesh, ComponentHandle<Transform> transform) {
|
||||||
|
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), 0));
|
||||||
|
});*/
|
||||||
|
|
||||||
|
/*// TODO: Is it possible to do get ObjMeshes in the Mesh loop above implicitly via polymorphism?
|
||||||
|
* // TODO: Commented out because of double rendering - we only want to get objects that explicitly DON'T have a texture here!
|
||||||
|
pWorld->each<ObjMesh, Transform>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform) {
|
||||||
|
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
||||||
|
float distance = glm::distance(cameraPos, transform->getPosition());
|
||||||
|
|
||||||
|
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
||||||
|
renderObjects.emplace_back(RenderObject(transform->matrix, 0, mesh.get(), distance));
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
|
||||||
|
// ObjMesh with textures
|
||||||
|
world->each<ObjMesh, Transform, Texture>([&](Entity *ent, ComponentHandle<ObjMesh> mesh, ComponentHandle<Transform> transform, ComponentHandle<Texture> texture) {
|
||||||
|
// Add the object to the renderObjects to draw if the distance is within the min and max distance of the mesh
|
||||||
|
float distance = glm::distance(cameraPos, transform->get_origin());
|
||||||
|
|
||||||
|
if (distance > mesh->minDistance && distance < mesh->maxDistance) {
|
||||||
|
// Get optional components
|
||||||
|
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
||||||
|
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
||||||
|
|
||||||
|
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||||
|
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||||
|
|
||||||
|
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||||
|
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||||
|
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
||||||
|
} else {
|
||||||
|
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh.get(), distance, material));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// LODObjMesh with Texture
|
||||||
|
world->each<LODObjMesh, Transform>([&](Entity *ent, ComponentHandle<LODObjMesh> lodMesh, ComponentHandle<Transform> transform) {
|
||||||
|
float distance = glm::distance(cameraPos, transform->get_origin());
|
||||||
|
|
||||||
|
for (const auto &mesh : lodMesh->meshes) {
|
||||||
|
if (distance > mesh.minDistance && distance < mesh.maxDistance) {
|
||||||
|
// Get optional components
|
||||||
|
ComponentHandle<Texture> textureComponent = ent->get<Texture>();
|
||||||
|
ComponentHandle<Material> materialComponent = ent->get<Material>();
|
||||||
|
|
||||||
|
Material material = materialComponent.isValid() ? materialComponent.get() : Material();
|
||||||
|
unsigned int textureID = textureComponent.isValid() ? textureComponent->id : 0;
|
||||||
|
|
||||||
|
// Put it into the list of transparent render objects if the texture wants to be rendered transparently
|
||||||
|
if (textureComponent.isValid() && textureComponent->render_transparent) {
|
||||||
|
renderObjects[1].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
||||||
|
} else {
|
||||||
|
renderObjects[0].emplace_back(RenderObject(transform->matrix, transform->get_origin(), textureID, mesh, distance, material));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sort transparent objects
|
||||||
|
std::sort(renderObjects[1].begin(), renderObjects[1].end(), [](const RenderObject &first, const RenderObject &second) -> bool {
|
||||||
|
return first.distance > second.distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
return renderObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(World *pWorld, Shader shader) {
|
||||||
|
pWorld->each<Camera, Transform>([&](Entity *ent, ComponentHandle<Camera> camera, ComponentHandle<Transform> cameraTransform) {
|
||||||
|
glClearColor(0.6f, 0.9f, 0.9f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
shader.use();
|
||||||
|
|
||||||
|
// Lighting
|
||||||
|
// TODO: Currently only the last light is used!
|
||||||
|
pWorld->each<DirectionalLight>([&](Entity *ent, ComponentHandle<DirectionalLight> light) {
|
||||||
|
shader.setVec3("lightDirection", light->direction);
|
||||||
|
});
|
||||||
|
|
||||||
|
glm::vec3 cameraPos = cameraTransform->get_origin();
|
||||||
|
|
||||||
|
glm::mat4 view = cameraTransform->matrix;
|
||||||
|
view[3] = glm::vec4(cameraPos, 1.0);
|
||||||
|
|
||||||
|
shader.setMat4("projection", camera->projection);
|
||||||
|
shader.setMat4("view", glm::inverse(view));
|
||||||
|
shader.setVec3("cameraPosition", cameraTransform->get_origin());
|
||||||
|
|
||||||
|
std::vector<std::vector<RenderObject>> allRenderObjects = getRenderObjects(pWorld, cameraPos);
|
||||||
|
std::vector<RenderObject> renderObjects = allRenderObjects[0];
|
||||||
|
std::vector<RenderObject> transparentRenderObjects = allRenderObjects[1];
|
||||||
|
|
||||||
|
for (const RenderObject &obj : renderObjects) {
|
||||||
|
obj.render(shader);
|
||||||
|
}
|
||||||
|
for (const RenderObject &obj : transparentRenderObjects) {
|
||||||
|
obj.render(shader);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //ECSGAME_RENDERSYSTEM_H
|
#endif //ECSGAME_RENDERSYSTEM_H
|
||||||
|
Loading…
x
Reference in New Issue
Block a user