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

Introduced CollectorUnits for the global scene collector

parent f7c556ef
......@@ -3,7 +3,6 @@
//Core Main
#include <engine/Time.h>
#include <engine/Singleton.h>
#include <engine/Node.h>
#include <engine/Math.h>
#include <engine/GLWrapper.h>
......
......@@ -11,6 +11,8 @@
#include <io/Export.h>
#include <util/files.h>
#include <raytrace/data/collector_units/mesh.h>
namespace glare
{
......@@ -42,7 +44,7 @@ namespace glare
m_gbuffer->updateSize(width, height);
m_config.window_width = width;
m_config.window_height = height;
m_collector->setDirty(glare::raytrace::SceneCollector::DirtyFlags::eCamera);
m_collector->setDirty(glare::raytrace::DirtyFlags::eCamera);
m_collector->collect();
gl::viewport(0, 0, width, height);
}
......@@ -106,10 +108,10 @@ namespace glare
//quitPromptDefault(0);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_glass_0r.dae", 1.f);
initializeScene(m_current_scene_root / "cube.dae", 1.f);
//initializeScene(m_current_scene_root / "cube.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_mirror_0r.dae", 1.f);
//initializeScene(m_current_scene_root / "artifact_suzanne_x2_transparent.dae", 1.f);
//initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
initializeScene(m_current_scene_root / "benchmark_stfd_bunny_diff.dae", 1.f);
//initializeScene(m_current_scene_root / "difficult.dae", 1.f);
initializeRenderRequirements();
......@@ -125,7 +127,7 @@ namespace glare
environment_source->setLooping(true);
environment_source->play();
const auto &coll = *m_collector->meshCollectors().begin()->second;
const auto &coll = *m_collector->getUnit<raytrace::MeshCollector>("mesh_collector").localCollectors().begin()->second;
//const advanced::AngularLinespace lisp(coll, 100, 16);
......@@ -242,7 +244,7 @@ namespace glare
void Application::updateAdvanced()
{
m_collector->setDirty(raytrace::SceneCollector::DirtyFlags::eAll);
m_collector->setDirty(raytrace::DirtyFlags::eAll);
m_collector->collect(core::EngineState::graph_root);
m_raytracer->initialize(m_collector);
}
......
......@@ -5,6 +5,8 @@
#include <glare_io>
#include <glare_gui>
#include <util/singleton.h>
//Components
#include <components/PlayerController.h>
#include <components/FramerateCounter.h>
......@@ -12,7 +14,7 @@
using namespace glare;
namespace fs = std::experimental::filesystem;
class Game : public core::Singleton<Game>
class Game : public Singleton<Game>
{
public:
Game();
......
......@@ -142,6 +142,7 @@ namespace glare
bool are(F_Type flags) const;
bool operator &(F_Type flags);
bool operator &(F_Type flags) const;
F_Type operator +(F_Type flags);
......@@ -162,6 +163,8 @@ namespace glare
template<typename E>
bool operator &(E flags);
template<typename E>
bool operator &(E flags) const;
template<typename E>
typename std::enable_if<std::is_enum<E>::value, E>::type operator +(E flags);
......@@ -356,6 +359,12 @@ namespace glare
return are(flags);
}
template <typename F_Type>
bool Flags<F_Type>::operator&(F_Type flags) const
{
return are(flags);
}
template <typename F_Type>
F_Type Flags<F_Type>::operator+(F_Type flags)
{
......@@ -412,6 +421,13 @@ namespace glare
return are(flags);
}
template <typename F_Type>
template <typename E>
bool Flags<F_Type>::operator&(E flags) const
{
return are(flags);
}
template <typename F_Type>
template <typename E>
typename std::enable_if<std::is_enum<E>::value, E>::type Flags<F_Type>::operator+(E flags)
......
#ifndef __MESSAGING_H
#define __MESSAGING_H
#include <map>
#include <mutex>
#include <queue>
#include <engine/Singleton.h>
#pragma warning( disable : 4307 )
namespace glare
{
namespace core
{
using payload_t = void*;
using id_t = unsigned long long;
static constexpr id_t offset = 2166136261L;
static constexpr id_t prime = 16777619L;
constexpr id_t unique_id(id_t partial, const char *str) {
return (str[0] == 0 ? partial : unique_id(((partial^str[0])*prime), str + 1));
}
constexpr id_t unique_id(const char *str) {
return unique_id(offset, str);
}
namespace GlobalMessages
{
}
struct uuid_t
{
uuid_t() {
static id_t _id = 0;
m_id = _id++;
}
operator id_t() const
{
return m_id;
}
private:
id_t m_id;
};
struct message_t
{
id_t name;
payload_t payload;
template<typename T>
T as() const {
return *reinterpret_cast<T*>(payload);
}
};
namespace MessageFactory
{
/**
* @brief Creates a message with the given name id and payload data. The payload will be copied!
* @param name The message target name
* @param payload The payload data for the message. Will be copied! Should be of any empty-constructor type (e.g. all fundamental types or simple structs containing only fundamental types. NO pointers).
* @return The created message.
*/
template<typename PayloadType>
inline message_t createMessage(id_t name, const PayloadType &payload) {
message_t result;
result.payload = malloc(sizeof(PayloadType));
memcpy(result.payload, &payload, sizeof(PayloadType));
result.name = name;
return result;
}
};
class MessageReceiver
{
public:
virtual ~MessageReceiver() = default;
id_t id() const {
return m_unique_id;
}
virtual void handle(message_t &message) = 0;
protected:
const uuid_t m_unique_id; //!< Gets initialized here.
};
class MessageHandler : public Singleton<MessageHandler>
{
public:
void submitMessage(message_t message) {
{
const std::unique_lock<std::mutex> lock(m_queue_mutex);
m_message_queue.push(message);
}
if (!m_is_running) {
handleAllMessages();
}
}
void registerReceiver(id_t for_id, MessageReceiver &receiver) {
const std::unique_lock<std::mutex> lock(m_receiver_mutex);
m_receiver_list[for_id].emplace(receiver.id(), &receiver);
}
void unregisterReceiver(id_t for_id, MessageReceiver &receiver) {
const std::unique_lock<std::mutex> lock(m_receiver_mutex);
m_receiver_list[for_id].erase(receiver.id());
}
private:
void handleMessage(message_t &message) {
//foreach receiver -> handle(msg)
const std::unique_lock<std::mutex> lock(m_receiver_mutex);
for (auto &&id_receiver_pair : m_receiver_list[message.name]) {
id_receiver_pair.second->handle(message);
}
free(message.payload);
}
void handleAllMessages() {
message_t* message;
{
const std::unique_lock<std::mutex> lock(m_queue_mutex);
m_is_running = true;
message = &m_message_queue.front();
}
while (true) {
handleMessage(*message);
{
const std::unique_lock<std::mutex> lock(m_queue_mutex);
m_message_queue.pop();
if (m_message_queue.empty()) {
m_is_running = false;
break;
}
message = &m_message_queue.front();
}
}
}
private:
bool m_is_running = false;
std::map<id_t, std::map<id_t, MessageReceiver*>> m_receiver_list;
//This mutex will lock onto m_message_queue to limit thread dependant writing.
//Also it locks m_is_running for a well-balanced runtime.
std::mutex m_queue_mutex;
std::queue<message_t> m_message_queue;
//This mutex will save the receiver list on registering and unregistering
std::mutex m_receiver_mutex;
};
}
}
#endif __MESSAGING_H
\ No newline at end of file
#ifndef __SINGLETON_H
#define __SINGLETON_H
namespace glare
{
namespace core
{
/**
* \brief A simple-to-use singleton wrapper. Derive from this to make a class a singleton.
* \tparam T The type of the singleton object. Usually the deriving class itself.
*/
template<typename T>
class Singleton
{
public:
/**
* \brief Creates a new instance of the singleton if there is none. Then returns it.
* \return The singleton instance.
*/
static T& getInstance()
{
static T instance;
return instance;
}
Singleton() {};
virtual ~Singleton() {};
//Don't need those.
Singleton(const Singleton&) = delete;
Singleton(const Singleton&&) = delete;
void operator=(const Singleton&) = delete;
};
}
}
#endif //__SINGLETON_H
......@@ -3,6 +3,7 @@
#include <util/log.h>
#include "engine/Time.h"
#include <engine/message_tags.h>
#include "imgui/imgui_glfw.h"
......@@ -44,7 +45,7 @@ namespace glare
void Camera::onTransformChanged()
{
MessageHandler::getInstance().submitMessage(MessageFactory::createMessage(GlobalMessages::c_camera_changed, 1));
messaging::Handler::getInstance().submit(tags::camera, 1);
}
void Camera::setProjection(Projection projection)
......
......@@ -7,16 +7,12 @@
#include "engine/rendering/GraphNodeComponent.h"
#include "engine/Math.h"
#include "engine/Messaging.h"
#include <util/messaging.h>
namespace glare
{
namespace core
{
namespace GlobalMessages
{
constexpr id_t c_camera_changed = core::unique_id("camera_changed");
}
/**
* \brief A Camera can be attached as a Component to any Node. It does not contain any input controls.
......
......@@ -6,7 +6,7 @@
#include <map>
#include <filesystem>
#include "engine/Singleton.h"
#include <util/singleton.h>
#include "engine/Math.h"
#include "ImageTexture2D.h"
#include "engine/rendering/ShaderProgram.h"
......
#include "Light.h"
#include "engine/rendering/LightManager.h"
#include <util/messaging.h>
#include <engine/message_tags.h>
namespace glare
{
......@@ -27,7 +29,7 @@ namespace glare
void LightComponent::onTransformChanged()
{
MessageHandler::getInstance().submitMessage(MessageFactory::createMessage(GlobalMessages::c_light_changed, 1));
messaging::Handler::getInstance().submit(tags::light, 1);
}
void LightComponent::draw(DrawMode mode)
......
#ifndef __LIGHT_H
#define __LIGHT_H
#include "engine/rendering/GraphNodeComponent.h"
#include <engine/Messaging.h>
#include <engine/rendering/ShadowMapRenderer.h>
namespace glare
{
namespace core
{
namespace GlobalMessages
{
constexpr id_t c_light_changed = core::unique_id("light_changed");
}
struct Attenuation
{
......
#ifndef INCLUDE_MESSAGE_TAGS_H
#define INCLUDE_MESSAGE_TAGS_H
#include <util/messaging.h>
namespace tags
{
constexpr uint32_t graph_transform = messaging::tag("GRTR");
constexpr uint32_t mesh_transform = messaging::tag("M TR");
constexpr uint32_t camera = messaging::tag("CAMR");
constexpr uint32_t light = messaging::tag("LGHT");
constexpr uint32_t scene = messaging::tag("SCEN");
}
#endif // !INCLUDE_MESSAGE_TAGS_H
#include "GraphNode.h"
#include <engine/message_tags.h>
namespace glare
{
......@@ -46,8 +47,7 @@ namespace glare
return {
m_transform, [this, old](auto &&obj) {
if (obj != old) {
MessageHandler::getInstance().submitMessage(MessageFactory::createMessage(GlobalMessages::c_graph_transform_changed, obj));
messaging::Handler::getInstance().submit(tags::graph_transform, obj);
onAbsoluteTransformChanged();
}
}
......
......@@ -16,16 +16,13 @@
#include "GraphNodeComponent.h"
#include "engine/Node.h"
#include <engine/Transactable.h>
#include <engine/Messaging.h>
#include <util/messaging.h>
namespace glare
{
namespace core
{
namespace GlobalMessages
{
constexpr id_t c_graph_transform_changed = core::unique_id("graph_transform_changed");
}
enum class DrawMode
{
......
#ifndef __LIGHTMANAGER_H
#define __LIGHTMANAGER_H
#include "engine/Singleton.h"
#include "engine/graphics/Light.h"
#include <util/singleton.h>
namespace glare
{
......
#include "MeshRenderer.h"
#include "engine/EngineState.h"
#include <engine/message_tags.h>
namespace glare
{
namespace core
{
std::atomic<id_t> MeshRenderer::m_current_id = 0;
std::atomic<uint64_t> MeshRenderer::m_current_id = 0;
MeshRenderer::MeshRenderer()
: MeshRenderer(nullptr, nullptr)
......@@ -42,7 +43,7 @@ namespace glare
{
}
id_t MeshRenderer::id() const
uint64_t MeshRenderer::id() const
{
return m_renderer_id;
}
......@@ -83,7 +84,7 @@ namespace glare
void MeshRenderer::onTransformChanged()
{
MessageHandler::getInstance().submitMessage(MessageFactory::createMessage(GlobalMessages::c_mesh_transform_changed, 1));
messaging::Handler::getInstance().submit(tags::mesh_transform, 1);
}
}
}
\ No newline at end of file
......@@ -8,17 +8,11 @@
#include "GraphNodeComponent.h"
#include "engine/graphics/Mesh.h"
#include "engine/graphics/Material.h"
#include <engine/Messaging.h>
namespace glare
{
namespace core
{
namespace GlobalMessages
{
constexpr id_t c_mesh_transform_changed = core::unique_id("mesh_transform_changed");
}
class MeshRenderer : public GraphNodeComponent
{
public:
......@@ -37,12 +31,12 @@ namespace glare
std::shared_ptr<Material> getMaterial() const;
id_t id() const;
uint64_t id() const;
protected:
static std::atomic<id_t> m_current_id;
static std::atomic<uint64_t> m_current_id;
const id_t m_renderer_id;
const uint64_t m_renderer_id;
std::shared_ptr<Mesh> m_mesh;
std::shared_ptr<Material> m_material;
......
#ifndef __OPENGLSTATE_H
#define __OPENGLSTATE_H
#include <engine/Singleton.h>
#include <util/singleton.h>
namespace glare
{
......
#ifndef __RESOURCES_H
#define __RESOURCES_H
#include <engine/Singleton.h>
#include <util/singleton.h>
#include <map>
#include <functional>
#include <memory>
......@@ -30,7 +30,7 @@ namespace glare
std::map<std::string, std::weak_ptr<T>> m_storage;
};
class Resources : public core::Singleton<Resources>
class Resources : public Singleton<Resources>
{
public:
std::shared_ptr<core::TextureRGBA_UB> getTexture(const fs::path &path, bool force_reload = false);
......
#include "camera.h"
// --------------- STDLIB ---------------
// --------------- EXTERN ---------------
#include <engine/graphics/Camera.h>
// --------------- INTERN ---------------
#include <raytrace/data/global_collector.h>
namespace glare
{
namespace raytrace
{
CameraCollector::CameraCollector()
{
}
CameraCollector::~CameraCollector()
{
}
void CameraCollector::clear(const math::Flags<> &flags)
{
if (flags & DirtyFlags::eCamera)
{
m_cameras.clear();
}
}
void CameraCollector::collect(const math::Flags<> &flags, const core::GraphNode &node)
{
if (flags & DirtyFlags::eCamera)
{
if (const auto &camera = node.getComponent<core::Camera>())
{
if (camera == core::EngineState::main_camera)
m_active_camera = unsigned(m_cameras.size());
m_cameras.push_back(convert::camera(*camera));
}
}
}
void CameraCollector::build(const math::Flags<> &flags)
{
}
void CameraCollector::apply(core::ShaderProgram &program)
{
program.updateUniformStruct("u_camera", m_cameras[m_active_camera]);
}
}
}