Commit bd0d7adc authored by Johannes Braun's avatar Johannes Braun
Browse files

Improvement on Scene graph: multiple of the same component type and component...

Improvement on Scene graph: multiple of the same component type and component removal from inside components.
parent 00d67401
......@@ -191,6 +191,7 @@ namespace glare
Application::~Application()
{
core::state::quit();
ImGui::glfw3::shutdown();
}
......@@ -198,7 +199,6 @@ namespace glare
{
//Initialize some scene graph from an obj file
core::state::graph_root = core::Resources::getInstance().getColladaFile(path, scale);
if (!core::state::graph_root)
{
core::state::quit();
......@@ -227,7 +227,8 @@ namespace glare
#define DEBUG__ADD_ROTATOR
#ifdef DEBUG__ADD_ROTATOR
if (auto &&node = core::state::graph_root->findFirstWithName("#Suzanne-mesh")) {
auto node = core::state::graph_root->findFirstWithName("#Suzanne-mesh");
if (node) {
node->addComponent(std::make_shared<component::Rotator>());
}
#endif
......
......@@ -35,6 +35,18 @@ namespace glare
Log_Debug << "Program was linked successfully.";
}
collectUniforms();
collectSubroutines(shaders);
}
Program::Program(std::shared_ptr<Shader> shader)
: Program(std::vector<std::shared_ptr<Shader>>{shader}) {}
Program::Program(const fs::path& shader_file)
: Program(std::make_shared<Shader>(gl::ShaderType::eCompute, fs::path(shader_file))) {}
void Program::collectUniforms()
{
int num_uniforms;
gl::getProgramiv(m_handle, gl::ProgramParameter::eActiveUniforms, &num_uniforms);
int max_length;
......@@ -51,7 +63,10 @@ namespace glare
m_uniforms[data.name] = data;
delete[] name;
}
}
void Program::collectSubroutines(const std::vector<std::shared_ptr<Shader>> &shaders)
{
for (auto &&shader : shaders)
{
m_shader_stages.push_back(shader->type());
......@@ -73,21 +88,11 @@ namespace glare
m_subroutines[info.name].emplace(info.shader_type, info);
Log_Info << "info:name: " << info.name;
delete[] name;
}
}
Log_Hint << "SUBROUTINES " << m_subroutines.size();
}
Program::Program(std::shared_ptr<Shader> shader)
: Program(std::vector<std::shared_ptr<Shader>>{shader}) {}
Program::Program(const fs::path& shader_file)
: Program(std::make_shared<Shader>(gl::ShaderType::eCompute, fs::path(shader_file))) {}
void Program::dispatch1d(unsigned global_x, unsigned local_x)
{
gl::dispatchComputeGroupSize(invocations(global_x, local_x), 1, 1, local_x, 1, 1);
......@@ -110,6 +115,7 @@ namespace glare
{
gl::useProgram(m_handle);
//Upload the bound subroutines because with gl::useProgram they (for some OpenGL reason) are cleared to their default values.
if (!m_subroutine_bindings.empty())
{
for (const auto& stage_routines : m_subroutine_bindings)
......
......@@ -70,14 +70,16 @@ namespace glare
int uniformLocation(const std::string &uniform) const;
UniformInfo uniformInfo(const std::string &uniform) const;
int bufferBlock(const std::string& block) const;
int subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const;
unsigned id() const;
private:
int subroutineIndex(gl::ShaderType shader_stage, const std::string &name) const;
void setSubroutines(gl::ShaderType stage, std::vector<unsigned> indices) const;
void collectUniforms();
void collectSubroutines(const std::vector<std::shared_ptr<Shader>> &shaders);
void setSubroutines(gl::ShaderType stage, std::vector<unsigned> indices) const;
void uniformUpdate(gl::UniformType type, unsigned location, const void* data) const;
unsigned invocations(unsigned global, unsigned local);
......
......@@ -3,6 +3,7 @@
#include <memory>
#include <map>
#include <vector>
namespace glare
{
......@@ -19,17 +20,16 @@ namespace glare
template<typename TComponent, typename... TArgs>
std::shared_ptr<TComponent> makeComponent(TArgs ... args);
template<typename T>
std::shared_ptr<T> getComponent();
template<typename T>
std::shared_ptr<T> getComponent() const;
template<typename T>
std::vector<std::shared_ptr<T>> getComponents() const;
protected:
//TODO: make components a map<id, vec<sptr<compType>>> for multiple of the same components
std::map<size_t, std::shared_ptr<TComponent>> m_components;
std::map<size_t, std::vector<std::shared_ptr<TComponent>>> m_components;
};
template <typename TNode, typename TComponent>
......@@ -37,7 +37,7 @@ namespace glare
void ComponentContainer<TNode, TComponent>::addComponent(std::shared_ptr<T> component)
{
component->m_owner = std::enable_shared_from_this<TNode>::shared_from_this();
m_components.emplace(typeid(T).hash_code(), component);
m_components[typeid(T).hash_code()].push_back(component);
}
template <typename TNode, typename TComponent>
......@@ -50,8 +50,8 @@ namespace glare
}
template <typename TNode, typename TComponent>
template <typename T>
std::shared_ptr<T> ComponentContainer<TNode, TComponent>::getComponent()
template<typename T>
std::shared_ptr<T> ComponentContainer<TNode, TComponent>::getComponent() const
{
if (m_components.count(typeid(T).hash_code()) == 0)
{
......@@ -59,21 +59,26 @@ namespace glare
}
else
{
return std::static_pointer_cast<T>(m_components.at(typeid(T).hash_code()));
const auto& list = m_components.at(typeid(T).hash_code());
if (list.empty())
return std::shared_ptr<T>(nullptr);
return std::static_pointer_cast<T>(list[0]);
}
}
template <typename TNode, typename TComponent>
template<typename T>
std::shared_ptr<T> ComponentContainer<TNode, TComponent>::getComponent() const
std::vector<std::shared_ptr<T>> ComponentContainer<TNode, TComponent>::getComponents() const
{
if (m_components.count(typeid(T).hash_code()) == 0)
{
return std::shared_ptr<T>(nullptr);
return std::vector<std::vector<std::shared_ptr<T>>>();
}
else
{
return std::static_pointer_cast<T>(m_components.at(typeid(T).hash_code()));
const auto& components = m_components.at(typeid(T).hash_code());
return std::vector<std::vector<std::shared_ptr<T>>>(components.begin(), components.end());
}
}
}
......
......@@ -37,12 +37,12 @@ namespace glare
std::shared_ptr<NodeType> findFirst(std::function<bool(const NodeType &node)> predicate) {
for (auto &&node : shared_from_this())
{
if (predicate(*node)) {
if (node && predicate(*node)) {
return node->shared_from_this();
}
}
return nullptr;
return std::shared_ptr<NodeType>(nullptr);
}
std::shared_ptr<NodeType> findFirstWithName(std::string name) {
......
......@@ -16,6 +16,7 @@ namespace glare
class GraphNodeComponent
{
friend class ComponentContainer<GraphNode, GraphNodeComponent>;
friend class GraphNode;
public:
virtual ~GraphNodeComponent() = default;
......@@ -29,8 +30,16 @@ namespace glare
return m_owner.lock();
}
void markDeletable()
{
m_flag_delete = true;
}
protected:
std::weak_ptr<GraphNode> m_owner;
private:
bool m_flag_delete = false;
};
}
}
......
......@@ -17,10 +17,27 @@ namespace glare
const glm::mat4 absolute_transform = parent_transform * m_transform.matrix();
m_world_transform.fromMatrix(absolute_transform);
for (auto &&component : m_components)
for (auto &&component_list : m_components)
{
component.second->gui();
component.second->update();
for (auto&& component_iterator = component_list.second.begin(); component_iterator != component_list.second.end();)
{
auto&& component = *component_iterator;
if (component) component->gui();
//If not deleted in gui()
if (component) component->update();
//No else, because it might have been deleted in gui() or update();
if (!component || component->m_flag_delete)
{
component_iterator = component_list.second.erase(component_iterator);
}
else
{
++component_iterator;
}
}
}
for (auto && child : m_children)
......@@ -31,9 +48,24 @@ namespace glare
void GraphNode::draw(DrawMode mode)
{
for (auto &&component : m_components)
for (auto &&component_list : m_components)
{
component.second->draw(mode);
for (auto&& component_iterator = component_list.second.begin(); component_iterator != component_list.second.end();)
{
auto&& component = *component_iterator;
if (component) component->draw(mode);
//No else again
if (!component || component->m_flag_delete)
{
component_iterator = component_list.second.erase(component_iterator);
}
else
{
++component_iterator;
}
}
}
for (auto && child : m_children)
......@@ -48,7 +80,7 @@ namespace glare
return {
m_transform, [this, old](auto &&obj) {
if (obj != old) {
messaging::Handler::getInstance().submit(tags::graph_transform, obj);
messaging::Handler::getInstance().submit(tags::graph_transform, obj);
onAbsoluteTransformChanged();
}
}
......@@ -57,9 +89,24 @@ namespace glare
void GraphNode::onAbsoluteTransformChanged()
{
for (auto &&component : m_components)
for (auto &&component_list : m_components)
{
component.second->onTransformChanged();
for (auto&& component_iterator = component_list.second.begin(); component_iterator != component_list.second.end();)
{
auto&& component = *component_iterator;
if (component) component->onTransformChanged();
//No else again
if (!component || component->m_flag_delete)
{
component_iterator = component_list.second.erase(component_iterator);
}
else
{
++component_iterator;
}
}
}
for (auto && child : m_children)
......
......@@ -73,8 +73,6 @@ namespace glare
decodeNodes(collada_root.child("library_visual_scenes"));
Log_Info << "Decoding Collada File took " << clock.time() << "ms";
data->images.clear();
data->controller_geometries.clear();
data->lights.clear();
......@@ -90,6 +88,8 @@ namespace glare
file_root_node->attach(scene.second);
}
Log_Info << "Decoding Collada File took " << clock.time() << "ms";
return file_root_node;
}
......
......@@ -33,13 +33,15 @@ namespace glare
}
void CameraCollector::collect(const math::Flags &flags, const core::GraphNode &node)
{
{
if (flags & DirtyFlags::eCamera)
{
if (const auto &camera = node.getComponent<core::Camera>())
{
const auto camera = node.getComponent<core::Camera>();
if (camera)
{
if (camera == core::state::camera)
m_active_camera = unsigned(m_cameras.size());
m_active_camera = unsigned(m_cameras.size());
m_cameras.push_back(convert::camera(*camera));
}
}
......
......@@ -35,7 +35,7 @@ namespace glare
}
void MeshCollector::collect(const math::Flags &flags, const core::GraphNode &node)
{
{
if (const auto& renderer = node.getComponent<core::MeshRenderer>())
{
const bool update_meshes = (flags & DirtyFlags::eMesh);
......@@ -51,6 +51,7 @@ namespace glare
if (update_mesh_transforms)
collectMeshTransform(renderer);
}
}
void MeshCollector::build(const math::Flags &flags)
......
......@@ -76,7 +76,7 @@ namespace glare
for (const auto &node : m_scene_root)
{
for (auto &&unit : m_units)
{
{
// Collecting will call collector dependent functionality.
unit.second->collect(m_dirty_flags, *node);
}
......
Markdown is supported
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