Commit 164c2e25 authored by Florian Oetke's avatar Florian Oetke
Browse files

fixed shader compilation and particle system loading

parent 4220906a
......@@ -23,13 +23,13 @@ set(MIRRAGE_GLSL_COMPILER "glslc" CACHE STRING "Path to glslc compiler")
foreach(GLSL ${GLSL_SOURCE_FILES})
get_filename_component(FILE_DIR ${GLSL} DIRECTORY)
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" FILE_DIR ${FILE_DIR})
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" FILE_DIR ${FILE_DIR})
get_filename_component(FILE_NAME ${GLSL} NAME)
set(SPIRV "${CMAKE_CURRENT_BINARY_DIR}/${FILE_DIR}/${FILE_NAME}.spv")
add_custom_command(
OUTPUT ${SPIRV}
COMMAND ${CMAKE_COMMAND} -E make_directory "${CMAKE_CURRENT_BINARY_DIR}/${FILE_DIR}/"
COMMAND ${CMAKE_GLSL_COMPILER} -o ${SPIRV} -c ${GLSL}
COMMAND ${MIRRAGE_GLSL_COMPILER} -o ${SPIRV} -c ${GLSL}
DEPENDS ${ALL_SHADERS})
list(APPEND SPIRV_BINARY_FILES ${SPIRV})
endforeach(GLSL)
......
......@@ -187,12 +187,18 @@ namespace mirrage::renderer {
public:
explicit Particle_emitter(const Particle_emitter_config& cfg) : _cfg(&cfg) {}
void active(bool b) noexcept { _active = b; }
auto active() const noexcept { return _active; }
void position(glm::vec3 p) noexcept { _position = p; }
auto position() const noexcept { return _position; }
void rotation(glm::quat r) noexcept { _rotation = r; }
auto rotation() const noexcept { return _rotation; }
void absolute(bool b) noexcept { _absolute = b; }
auto absolute() const noexcept { return _absolute; }
void incr_time(float dt) { _time_accumulator += dt; }
auto cfg() const noexcept -> auto& { return *_cfg; }
......@@ -201,28 +207,38 @@ namespace mirrage::renderer {
const Particle_emitter_config* _cfg;
// TODO: userdata?
bool _active = true;
glm::vec3 _position{0, 0, 0};
glm::quat _rotation{1, 0, 0, 0};
bool _absolute = false;
float _time_accumulator = 0.f;
};
class Particle_system : private std::enable_shared_from_this<Particle_system> {
public:
using Emitter_list = util::small_vector<Particle_emitter, 1>;
using Emitter_list = util::small_vector<Particle_emitter, 1>;
using Effector_list = std::vector<Particle_effector_config>;
Particle_system() = default;
Particle_system(asset::Ptr<Particle_system_config> cfg,
glm::vec3 position = {0, 0, 0},
glm::quat rotation = {1, 0, 0, 0});
auto cfg() const noexcept { return _cfg; }
auto cfg_aid() const { return _cfg ? util::just(_cfg.aid()) : util::nothing; }
auto emitters() noexcept -> auto& { return _emitters; }
auto emitters() const noexcept -> auto& { return _emitters; }
auto emitters() noexcept -> auto&
{
_check_reload();
return _emitters;
}
auto effectors() noexcept -> auto& { return _effectors; }
auto effectors() const noexcept -> auto& { return _effectors; }
auto effectors() noexcept -> auto&
{
_check_reload();
return _effectors;
}
void position(glm::vec3 p) noexcept { _position = p; }
auto position() const noexcept { return _position; }
......@@ -230,13 +246,26 @@ namespace mirrage::renderer {
void rotation(glm::quat r) noexcept { _rotation = r; }
auto rotation() const noexcept { return _rotation; }
auto emitter_position(const Particle_emitter& e) const noexcept
{
return e.absolute() ? e.position() : _position + e.position();
}
auto emitter_rotation(const Particle_emitter& e) const noexcept
{
return e.absolute() ? e.rotation() : _rotation * e.rotation();
}
private:
asset::Ptr<Particle_system_config> _cfg;
Emitter_list _emitters;
std::vector<Particle_effector_config> _effectors;
asset::Ptr<Particle_system_config> _cfg;
bool _loaded = false;
Emitter_list _emitters;
Effector_list _effectors;
glm::vec3 _position{0, 0, 0};
glm::quat _rotation{1, 0, 0, 0};
void _check_reload();
};
......
......@@ -116,7 +116,15 @@ namespace mirrage::renderer {
struct Particle_draw {
Particle_emitter* emitter;
gsl::span<Particle_effector_config> effectors;
bool in_draw_range;
std::uint32_t culling_mask;
Particle_draw() = default;
Particle_draw(Particle_emitter& emitter,
gsl::span<Particle_effector_config> effectors,
std::uint32_t culling_mask)
: emitter(&emitter), effectors(effectors), culling_mask(culling_mask)
{
}
};
class Frame_data {
......
......@@ -17,13 +17,28 @@ namespace mirrage::renderer {
glm::vec3 position,
glm::quat rotation)
: _cfg(std::move(cfg))
, _emitters(util::build_vector(_cfg->emitters.size(),
, _loaded(_cfg.ready())
, _emitters(!_loaded ? Emitter_list{}
: util::build_vector(
_cfg->emitters.size(),
[&](auto idx) { return Particle_emitter(_cfg->emitters[idx]); }))
, _effectors(_cfg->effectors)
, _effectors(!_loaded ? Effector_list{} : _cfg->effectors)
, _position(position)
, _rotation(rotation)
{
}
void Particle_system::_check_reload()
{
MIRRAGE_INVARIANT(_cfg.ready(),
"Tried to access Particle_system emitters before the config was laoded!");
if(!_loaded) {
_loaded = true;
_emitters = util::build_vector(_cfg->emitters.size(),
[&](auto idx) { return Particle_emitter(_cfg->emitters[idx]); });
_effectors = _cfg->effectors;
}
}
namespace {
auto comp_cfg_aid(const Particle_system_comp& comp)
......@@ -36,9 +51,8 @@ namespace mirrage::renderer {
{
auto aid = comp_cfg_aid(comp);
auto new_aid = aid;
auto effectors = std::vector<Particle_effector_config>();
state.read_virtual(sf2::vmember("cfg", new_aid), sf2::vmember("effectors", effectors));
auto new_aid = aid;
state.read_virtual(sf2::vmember("cfg", new_aid));
if(new_aid != aid) {
comp.particle_system =
......@@ -46,9 +60,6 @@ namespace mirrage::renderer {
? Particle_system{}
: Particle_system{state.assets.load<Particle_system_config>(asset::AID(new_aid))};
}
if(!effectors.empty())
comp.particle_system.effectors() = std::move(effectors);
}
void save_component(ecs::Serializer& state, const Particle_system_comp& comp)
{
......@@ -102,12 +113,15 @@ namespace mirrage::asset {
},
r);
auto loads = std::vector<async::shared_task<renderer::Particle_script>>();
loads.reserve(r.emitters.size());
auto loads = std::vector<async::task<void>>();
loads.reserve(r.emitters.size() * 2u);
for(auto& e : r.emitters) {
e.emit_script = in.manager().load<renderer::Particle_script>(e.emit_script_id);
loads.emplace_back(e.emit_script.internal_task());
e.type = in.manager().load<renderer::Particle_type_config>(e.type_id);
loads.emplace_back(async::when_all(e.emit_script.internal_task(), e.type.internal_task())
.then([](auto&&...) {}));
}
return async::when_all(loads.begin(), loads.end()).then([r = std::move(r)](auto&&...) mutable {
......
......@@ -124,6 +124,41 @@ namespace mirrage::renderer {
}
}
for(auto& particle_sys : _ecs.list<Particle_system_comp>()) {
if(!particle_sys.particle_system.cfg().ready())
continue;
for(auto&& emitter : particle_sys.particle_system.emitters()) {
if(emitter.active()) {
auto pos = particle_sys.particle_system.emitter_position(emitter);
auto update_range = emitter.cfg().type->update_range;
auto draw_range = emitter.cfg().type->draw_range;
auto shadowcaster = emitter.cfg().type->shadowcaster;
auto draw_mask = draw_range < 0.f ? ~std::uint32_t(0) : std::uint32_t(0);
auto update = update_range < 0.f;
if(!draw_mask) {
for(auto i = 0u; i < viewers.size(); i++) {
if(viewers[i].shadowmap && !shadowcaster)
continue;
if(is_visible(viewers[i], pos, draw_range)) {
draw_mask |= std::uint32_t(1) << i;
} else if(!update && is_visible(viewers[i], pos, update_range)) {
update = true;
}
}
}
if(update || draw_mask) {
frame.particle_queue.emplace_back(
emitter, particle_sys.particle_system.effectors(), draw_mask);
}
}
}
}
for(auto& [entity, model, transform] : _ecs.list<ecs::Entity_facet, Model_comp, Transform_comp>()) {
auto entity_pos = transform.position;
auto dir_mat = transform.to_mat3();
......
......@@ -30,6 +30,9 @@ namespace mirrage::renderer {
void Particle_pass::update(util::Time dt)
{
for(auto& [transform, ps] : _ecs.list<Transform_comp, Particle_system_comp>()) {
if(!ps.particle_system.cfg().ready())
continue;
ps.particle_system.position(transform.position);
ps.particle_system.rotation(transform.orientation);
for(auto& e : ps.particle_system.emitters())
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment