Skip to content

Commit

Permalink
fix lighting scene to new renderer
Browse files Browse the repository at this point in the history
  • Loading branch information
hotstreams committed Aug 28, 2024
1 parent d7626dc commit 39adad3
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 27 deletions.
35 changes: 30 additions & 5 deletions include/limitless/instances/instance_builder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,34 @@
#include <limitless/instances/instance.hpp>
#include <limitless/instances/skeletal_instance.hpp>
#include <limitless/instances/effect_instance.hpp>
#include <limitless/instances/decal_instance.hpp>
#include <limitless/models/model.hpp>
#include "decal_instance.hpp"

namespace Limitless {
class instance_builder_exception : public std::runtime_error {
public:
using std::runtime_error::runtime_error;
};

/**
*
*/
class Instance::Builder {
private:
std::shared_ptr<AbstractModel> model_;
std::shared_ptr<EffectInstance> effect_;

/**
* Instance data
*/
glm::quat rotation_ {1.0f, 0.0f, 0.0f, 0.0f};
glm::vec3 position_ {0.0f};
glm::vec3 scale_ {1.0f};
bool cast_shadow_ {true};
std::optional<Box> bounding_box_ {};
uint8_t decal_mask {0xFF};
uint8_t decal_proj_mask {0xFF};

/**
* Model data
*/
std::shared_ptr<AbstractModel> model_;

class MaterialChange {
public:
Expand All @@ -37,13 +44,26 @@ namespace Limitless {

std::vector<std::shared_ptr<Instance>> attachments;

/**
* Skeletal data
*/
class SocketAttachment {
public:
std::string bone_name;
std::shared_ptr<Instance> attachment;
};
std::vector<SocketAttachment> bone_attachments;

/**
* Effect data
*/
std::shared_ptr<EffectInstance> effect_;

/**
* Decal
*/
uint8_t decal_proj_mask {0xFF};

void initialize(Instance& instance);
void initialize(const std::shared_ptr<ModelInstance>& instance);
public:
Expand Down Expand Up @@ -154,5 +174,10 @@ namespace Limitless {
*
*/
std::shared_ptr<DecalInstance> asDecal();

/**
*
*/
std::shared_ptr<DecalInstance> asTerrain();
};
}
4 changes: 4 additions & 0 deletions include/limitless/renderer/instance_renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ namespace Limitless {
* Renders only visible subset of InstancedInstance instances from frustum culling
*/
void renderVisibleInstancedInstance(InstancedInstance& instance, const DrawParameters& drawp);
/**
* Renders only visible MeshInstances of terrain
*/
void renderVisibleTerrain(TerrainInstance& instance, const DrawParameters& drawp);
void renderVisible(Instance& instance, const DrawParameters& drawp);
public:
void update(Scene& scene, Camera& camera);
Expand Down
40 changes: 32 additions & 8 deletions include/limitless/util/frustum_culling.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,25 @@
namespace Limitless {
class FrustumCulling {
private:
// contains visible array of instances
/**
* Contains visible array of simple instances
*/
std::vector<std::shared_ptr<Instance>> visible;
// contains visible array of model instances for each instanced instance
std::map<uint64_t, std::vector<std::shared_ptr<ModelInstance>>> visible_model_instanced;

/**
* Contains visible array of model instances for each instanced instance
*/
std::map<uint64_t, std::vector<std::shared_ptr<ModelInstance>>> visible_instances_of_instanced_instances;

/**
* Contains visible MeshInstances of TerrainInstance
*/
std::map<uint64_t, std::vector<std::reference_wrapper<MeshInstance>>> visible_meshes_of_terrain_instances;
public:
void update(Scene& scene, Camera& camera) {
visible.clear();
visible_model_instanced.clear();
visible_instances_of_instanced_instances.clear();
visible_meshes_of_terrain_instances.clear();

const auto frustum = Frustum::fromCamera(camera);

Expand All @@ -22,11 +33,23 @@ namespace Limitless {

for (auto& i: instanced.getInstances()) {
if (frustum.intersects(*i)) {
visible_model_instanced[instance->getId()].emplace_back(i);
visible_instances_of_instanced_instances[instance->getId()].emplace_back(i);
}
}

if (visible_instances_of_instanced_instances.count(instance->getId()) != 0) {
visible.emplace_back(instance);
}
} else if (instance->getInstanceType() == InstanceType::Terrain) {
auto& terrain = static_cast<TerrainInstance&>(*instance); //NOLINT

for (auto& [_, mesh_instance] : terrain.getMeshes()) {
if (frustum.intersects(mesh_instance.getMesh()->getBoundingBox())) {
visible_meshes_of_terrain_instances[instance->getId()].emplace_back(mesh_instance);
}
}

if (visible_model_instanced.count(instance->getId()) != 0) {
if (visible_meshes_of_terrain_instances.count(instance->getId()) != 0) {
visible.emplace_back(instance);
}
} else {
Expand All @@ -37,7 +60,8 @@ namespace Limitless {
}
}

const Instances& getVisibleInstances() const noexcept { return visible; }
const std::vector<std::shared_ptr<ModelInstance>>& getVisibleModelInstanced(const InstancedInstance& instance) const noexcept { return visible_model_instanced.at(instance.getId()); }
[[nodiscard]] const Instances& getVisibleInstances() const noexcept { return visible; }
[[nodiscard]] const std::vector<std::shared_ptr<ModelInstance>>& getVisibleModelInstanced(const InstancedInstance& instance) const noexcept { return visible_instances_of_instanced_instances.at(instance.getId()); }
const std::vector<std::reference_wrapper<MeshInstance>>& getVisibleTerrainMeshes(const TerrainInstance& instance) const noexcept { return visible_meshes_of_terrain_instances.at(instance.getId()); }
};
}
6 changes: 6 additions & 0 deletions src/limitless/instances/instance_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <limitless/instances/skeletal_instance.hpp>
#include <limitless/models/elementary_model.hpp>
#include <limitless/instances/decal_instance.hpp>
#include <limitless/models/mesh.hpp>
#include <limitless/core/indexed_stream.hpp>

using namespace Limitless;

Expand Down Expand Up @@ -213,3 +215,7 @@ Instance::Builder &Instance::Builder::decal_projection_mask(uint8_t mask) {
decal_proj_mask = mask;
return *this;
}

std::shared_ptr<DecalInstance> Instance::Builder::asTerrain() {
return std::shared_ptr<DecalInstance>();
}
36 changes: 22 additions & 14 deletions src/limitless/renderer/instance_renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,6 @@ void InstanceRenderer::render(SkeletalInstance& instance, const DrawParameters&
return;
}

for (const auto& [_, mesh]: instance.getMeshes()) {
// skip mesh if blending is different
if (mesh.getMaterial()->getBlending() != drawp.blending) {
return;
}

// set render state: shaders, material, blending, etc
setRenderState(mesh, drawp, {InstanceType::Model, instance.getFinalMatrix(), instance.getDecalMask()});

// draw vertices
mesh.getMesh()->draw();
}

instance.getBoneBuffer()->bindBase(drawp.ctx.getIndexedBuffers().getBindingPoint(IndexedBuffer::Type::ShaderStorage, "bone_buffer"));

for (const auto& [_, mesh]: instance.getMeshes()) {
Expand Down Expand Up @@ -128,6 +115,27 @@ void InstanceRenderer::renderVisibleInstancedInstance(InstancedInstance& instanc
render(instance, drawp);
}

void InstanceRenderer::renderVisibleTerrain(TerrainInstance &instance, const DrawParameters &drawp) {
if (instance.isHidden()) {
return;
}

for (const auto& mref: frustum_culling.getVisibleTerrainMeshes(instance)) {
auto& mesh = mref.get();

// skip mesh if blending is different
if (mesh.getMaterial()->getBlending() != drawp.blending) {
return;
}

// set render state: shaders, material, blending, etc
setRenderState(mesh, drawp, {InstanceType::Terrain, instance.getFinalMatrix(), instance.getDecalMask()});

// draw vertices
mesh.getMesh()->draw();
}
}

void InstanceRenderer::render(InstancedInstance &instance, const DrawParameters &drawp) {
if (instance.isHidden()) {
return;
Expand Down Expand Up @@ -162,7 +170,7 @@ void InstanceRenderer::renderVisible(Instance &instance, const DrawParameters &d
case InstanceType::SkeletalInstanced: break; //NOLINT
case InstanceType::Effect: break; //NOLINT
case InstanceType::Decal: break; //NOLINT
case InstanceType::Terrain: render(static_cast<TerrainInstance&>(instance), drawp); break; //NOLINT
case InstanceType::Terrain: renderVisibleTerrain(static_cast<TerrainInstance&>(instance), drawp); break; //NOLINT
}
}

Expand Down

0 comments on commit 39adad3

Please sign in to comment.