1#include <Engine/RadiumEngine.hpp>
3#include <Core/Asset/FileData.hpp>
4#include <Core/Asset/FileLoaderInterface.hpp>
5#include <Core/Resources/Resources.hpp>
6#include <Core/Tasks/Task.hpp>
7#include <Core/Tasks/TaskQueue.hpp>
8#include <Core/Utils/StringUtils.hpp>
9#include <Engine/Data/BlinnPhongMaterial.hpp>
10#include <Engine/Data/LambertianMaterial.hpp>
11#include <Engine/Data/MaterialConverters.hpp>
12#include <Engine/Data/PlainMaterial.hpp>
13#include <Engine/Data/ShaderConfigFactory.hpp>
14#include <Engine/Data/ShaderProgramManager.hpp>
15#include <Engine/Data/TextureManager.hpp>
16#include <Engine/Data/VolumetricMaterial.hpp>
17#include <Engine/FrameInfo.hpp>
18#include <Engine/Rendering/RenderObject.hpp>
19#include <Engine/Rendering/RenderObjectManager.hpp>
20#include <Engine/Scene/ComponentMessenger.hpp>
21#include <Engine/Scene/DefaultCameraManager.hpp>
22#include <Engine/Scene/Entity.hpp>
23#include <Engine/Scene/EntityManager.hpp>
24#include <Engine/Scene/SignalManager.hpp>
25#include <Engine/Scene/System.hpp>
31#include <glbinding-aux/ContextInfo.h>
32#include <glbinding/Version.h>
37using namespace Core::Utils;
38using namespace Core::Asset;
40RadiumEngine::RadiumEngine() =
default;
42RadiumEngine::~RadiumEngine() =
default;
45 LOG( logINFO ) <<
"*** Radium Engine ***";
49 <<
"Default Radium resources dir not found. Setting resources path to \".\"";
50 resourceDir = {
"." };
52 m_resourcesRootDir = *resourceDir;
53 m_signalManager = std::make_unique<Scene::SignalManager>();
54 m_entityManager = std::make_unique<Scene::EntityManager>();
55 m_renderObjectManager = std::make_unique<Rendering::RenderObjectManager>();
56 m_textureManager = std::make_unique<Data::TextureManager>();
57 m_shaderProgramManager = std::make_unique<Data::ShaderProgramManager>();
60 Scene::ComponentMessenger::createInstance();
63 cameraManager->initialize();
65 Ra::Engine::RadiumEngine::getInstance()->registerSystem(
71 m_glVersion = glbinding::aux::ContextInfo::version();
74 m_openglState = std::make_unique<globjects::State>( globjects::State::DeferredMode );
75 registerDefaultPrograms();
77 m_openglState->pixelStore( GL_UNPACK_ALIGNMENT, 1 );
78 m_openglState->apply();
85void RadiumEngine::registerDefaultPrograms() {
87 CORE_ASSERT( m_shaderProgramManager !=
nullptr,
88 "ShaderProgramManager needs to be created first" );
97 m_shaderProgramManager->addNamedString(
98 "/TransformStructs.glsl", m_resourcesRootDir +
"Shaders/Transform/TransformStructs.glsl" );
99 m_shaderProgramManager->addNamedString(
100 "/DefaultLight.glsl", m_resourcesRootDir +
"Shaders/Lights/DefaultLight.glsl" );
103 m_shaderProgramManager->addNamedString(
104 "/VertexAttribInterface.frag.glsl",
105 m_resourcesRootDir +
"Shaders/Materials/VertexAttribInterface.frag.glsl" );
110 lConfig.addShader( Data::ShaderType_VERTEX,
111 m_resourcesRootDir +
"Shaders/Lines/Lines.vert.glsl" );
112 lConfig.addShader( Data::ShaderType_FRAGMENT,
113 m_resourcesRootDir +
"Shaders/Lines/Lines.frag.glsl" );
117 lgConfig.addShader( Data::ShaderType_VERTEX,
118 m_resourcesRootDir +
"Shaders/Lines/Lines.vert.glsl" );
119 lgConfig.addShader( Data::ShaderType_FRAGMENT,
120 m_resourcesRootDir +
"Shaders/Lines/Lines.frag.glsl" );
121 lgConfig.addShader( Data::ShaderType_GEOMETRY,
122 m_resourcesRootDir +
"Shaders/Lines/Lines.geom.glsl" );
126 lagConfig.addShader( Data::ShaderType_VERTEX,
127 m_resourcesRootDir +
"Shaders/Lines/Lines.vert.glsl" );
128 lagConfig.addShader( Data::ShaderType_FRAGMENT,
129 m_resourcesRootDir +
"Shaders/Lines/LinesAdjacency.frag.glsl" );
130 lagConfig.addShader( Data::ShaderType_GEOMETRY,
131 m_resourcesRootDir +
"Shaders/Lines/Lines.geom.glsl" );
146 m_signalManager->setOn(
false );
147 m_entityManager.
reset();
148 m_renderObjectManager.
reset();
149 m_textureManager.reset(
nullptr );
150 m_shaderProgramManager.reset(
nullptr );
152 m_loadedFile.
reset();
154 for (
auto& system : m_systems ) {
155 system.second.reset();
158 Scene::ComponentMessenger::destroyInstance();
160 m_loadingState =
false;
164 m_entityManager->swapBuffers();
165 m_signalManager->fireFrameEnded();
169 static uint frameCounter = 0;
171 if ( m_timeData.m_play || m_timeData.m_singleStep ) {
172 m_timeData.updateTime( dt );
173 m_timeData.m_singleStep =
false;
177 m_timeData.m_time, m_timeData.m_realTime ? dt : m_timeData.m_dt, frameCounter++ };
178 for (
auto& syst : m_systems ) {
179 syst.second->generateTasks( taskQueue, frameInfo );
184 if ( findSystem( name ) != m_systems.
end() ) {
185 LOG( logWARNING ) <<
"Try to add system " << name.
c_str()
186 <<
" multiple time. Keep the already registered one.";
191 LOG( logINFO ) <<
"Loaded : " << name;
197 auto it = findSystem( system );
199 if ( it != m_systems.
end() ) { sys = it->second.get(); }
209 if ( m_entityManager->entityExists( entityName ) ) {
210 auto e = m_entityManager->getEntity( entityName );
213 const auto c = e->getComponent( componentName );
215 if ( c !=
nullptr && !c->m_renderObjects.empty() ) {
217 if ( roName.
empty() ) {
218 return m_renderObjectManager->getRenderObject( c->m_renderObjects.front() )
223 for (
const auto& idx : c->m_renderObjects ) {
224 const auto& ro = m_renderObjectManager->getRenderObject( idx );
225 if ( ro->getName() == roName ) {
return ro->getMesh().get(); }
236 std::string extension = Core::Utils::getFileExt( filename );
238 for (
auto& l : m_fileLoaders ) {
239 if ( l->handleFileExtension( extension ) ) {
240 FileData* data = l->loadFile( filename );
241 if ( data !=
nullptr ) {
242 m_loadedFile.
reset( data );
248 if ( m_loadedFile ==
nullptr ) {
249 LOG( logERROR ) <<
"There is no loader to handle \"" << extension
250 <<
"\" extension ! File can't be loaded.";
255 std::string entityName = Core::Utils::getBaseName( filename,
false );
257 Scene::Entity* entity = m_entityManager->createEntity( entityName );
259 for (
auto& system : m_systems ) {
260 system.second->handleAssetLoading( entity, m_loadedFile.
get() );
263 if ( !entity->getComponents().empty() ) {
264 for (
auto& comp : entity->getComponents() ) {
269 LOG( logWARNING ) <<
"File \"" << filename <<
"\" has no usable data. Deleting entity...";
270 m_entityManager->removeEntity( entity );
272 m_loadingState =
true;
277 m_loadedFile.
reset(
nullptr );
278 m_loadingState =
false;
282 return m_renderObjectManager.
get();
286 return m_entityManager.
get();
290 return m_signalManager.get();
294 return m_textureManager.get();
298 return m_shaderProgramManager.get();
306 return m_fileLoaders;
312 CORE_ASSERT( m_loadingState,
"Access to file content is only available at loading time." );
313 return *( m_loadedFile.
get() );
316RadiumEngine::SystemContainer::const_iterator
317RadiumEngine::findSystem(
const std::string& name )
const {
319 return el.first.second == name;
323RadiumEngine::SystemContainer::iterator RadiumEngine::findSystem(
const std::string& name ) {
325 return el.first.second == name;
333 const auto& systemEntity = Scene::SystemEntity::getInstance();
334 auto entities = m_entityManager->getEntities();
335 for (
const auto& entity : entities ) {
336 if ( entity != systemEntity ) aabb.extend( entity->computeAabb() );
345 glGetIntegerv( GL_VIEWPORT, activeViewport.
data() );
347 GL_ASSERT( glGetIntegerv( GL_FRAMEBUFFER_BINDING, &activeFbo ) );
353 if ( m_fboAndViewportStack.
empty() ) {
354 LOG( logERROR ) <<
"RadiumEngine: try to pop from an empty Fbo and Viewport stack\n";
357 auto b = m_fboAndViewportStack.
top();
359 glViewport( b.m_viewport[0], b.m_viewport[1], b.m_viewport[2], b.m_viewport[3] );
360 GL_ASSERT( glBindFramebuffer( GL_FRAMEBUFFER, b.m_fbo ) );
361 m_fboAndViewportStack.
pop();
366 m_timeData.m_realTime = realTime;
370 return m_timeData.m_realTime;
374 return !m_timeData.m_realTime;
378 m_timeData.m_dt = dt;
380 return !m_timeData.m_realTime;
384 m_timeData.m_play = isPlaying;
388 m_timeData.m_singleStep =
true;
392 m_timeData.m_play =
false;
393 m_timeData.m_singleStep =
false;
394 m_timeData.m_time = m_timeData.m_startTime;
398 m_timeData.m_time = t;
402 m_timeData.m_startTime =
std::max( t, 0_ra );
406 return m_timeData.m_startTime;
410 m_timeData.m_endTime = t;
414 return m_timeData.m_endTime;
418 m_timeData.m_forwardBackward = mode;
420 if ( !m_timeData.m_forwardBackward ) { m_timeData.m_isBackward =
false; }
424 return m_timeData.m_time;
428 return uint(
std::ceil( m_timeData.m_time / m_timeData.m_dt ) );
431void RadiumEngine::TimeData::updateTime( Scalar dt ) {
432 dt += m_realTime ? dt : m_dt;
434 if ( m_forwardBackward && m_isBackward ) { m_time -= dt; }
435 else { m_time += dt; }
437 if ( m_endTime < 0 || m_startTime >= m_endTime ) {
439 m_isBackward =
false;
443 if ( m_time < m_startTime ) {
445 m_time = m_startTime;
447 m_isBackward =
false;
451 if ( !m_forwardBackward && m_time > m_endTime ) {
453 dt = Scalar(
fmod(
double( m_time - m_startTime ),
double( m_endTime - m_startTime ) ) );
455 m_time = m_startTime + dt;
459 if ( m_forwardBackward && m_time > m_endTime ) {
462 m_time = 2 * m_endTime - m_time;
474 m_gpuTaskQueue->runTasksInThisThread();
478 return m_gpuTaskQueue->registerTask(
std::move( task ) );
482 m_gpuTaskQueue->removeTask( taskId );
This class allows tasks to be registered and then executed in parallel on separate threads.
Utils::Index TaskId
Identifier for a task in the task queue.
static void registerMaterial()
static void unregisterMaterial()
static void unregisterMaterial()
Remove the material from the material library.
static void registerMaterial()
Register the material in the material library.
static void unregisterMaterial()
static void registerMaterial()
static void setOpenGLVersion(const glbinding::Version &version)
set the OpenGL version to use in the generated header for shaders.
Manage Texture loading and registration.
static void unregisterMaterial()
static void registerMaterial()
const Core::Asset::FileData & getFileData() const
Scene::System * getSystem(const std::string &system) const
bool loadFile(const std::string &file)
Scene::EntityManager * getEntityManager() const
void setEndTime(Scalar t)
void setStartTime(Scalar t)
void getTasks(Core::TaskQueue *taskQueue, Scalar dt)
bool isRealTime() const
Indicates if Real-time time flow is on (Constant-time is off) .
Core::Aabb computeSceneAabb() const
const std::vector< std::shared_ptr< Core::Asset::FileLoaderInterface > > & getFileLoaders() const
void setRealTime(bool realTime)
Toggles Real-time (on) or Constant (off) time flow.
Data::TextureManager * getTextureManager() const
void setForwardBackward(bool mode)
Activates or disables ForwardBackward time flow.
Rendering::RenderObjectManager * getRenderObjectManager() const
Manager getters.
void play(bool isPlaying)
Scene::SignalManager * getSignalManager() const
Scalar getStartTime() const
glbinding::Version getOpenGLVersion() const
Get the currently used OpenGL version.
void registerFileLoader(std::shared_ptr< Core::Asset::FileLoaderInterface > fileLoader)
void pushFboAndViewport()
Data::Displayable * getMesh(const std::string &entityName, const std::string &componentName, const std::string &roName=std::string()) const
Scalar getEndTime() const
void removeGpuTask(Core::TaskQueue::TaskId taskId)
Core::TaskQueue::TaskId addGpuTask(std::unique_ptr< Core::Task >)
Data::ShaderProgramManager * getShaderProgramManager() const
bool setConstantTimeStep(Scalar dt, bool forceConstantTime=false)
Sets the time delta between two frames for Constant-time time flow.
bool isConstantTime() const
Indicates if Constant-time time flow is on (Real-time is off) .
bool registerSystem(const std::string &name, Scene::System *system, int priority=1)
DefaultCameraManager. A simple Camera Manager with a list of Cameras.
An entity is an scene element. It ties together components with a transform.
optional< std::string > getRadiumResourcesPath()
Get the path of Radium internal resources.
void addConfiguration(const ShaderConfiguration &config)
hepler function to manage enum as underlying types in VariableSet
Structure passed to each system before they fill the task queue.