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>
26 #include <Engine/Scene/SystemDisplay.hpp>
31 #include <glbinding-aux/ContextInfo.h>
32 #include <glbinding/Version.h>
37 using namespace Core::Utils;
38 using namespace Core::Asset;
40 RadiumEngine::RadiumEngine() =
default;
42 RadiumEngine::~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(
66 "DefaultCameraManager", cameraManager, std::numeric_limits<int>::min() );
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();
85 void 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.";
190 m_systems[std::make_pair( priority, name )] = std::shared_ptr<Scene::System>( system );
191 LOG( logINFO ) <<
"Loaded : " << name;
197 auto it = findSystem( system );
199 if ( it != m_systems.end() ) { sys = it->second.get(); }
205 const std::string& componentName,
206 const std::string& roName )
const {
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();
302 m_fileLoaders.push_back( fileLoader );
306 return m_fileLoaders;
312 CORE_ASSERT( m_loadingState,
"Access to file content is only available at loading time." );
313 return *( m_loadedFile.get() );
316 RadiumEngine::SystemContainer::const_iterator
317 RadiumEngine::findSystem(
const std::string& name )
const {
318 return std::find_if( m_systems.cbegin(), m_systems.cend(), [&name](
const auto& el ) {
319 return el.first.second == name;
323 RadiumEngine::SystemContainer::iterator RadiumEngine::findSystem(
const std::string& name ) {
324 return std::find_if( m_systems.begin(), m_systems.end(), [&name](
const auto& el ) {
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() );
343 std::array<int, 4> activeViewport;
345 glGetIntegerv( GL_VIEWPORT, activeViewport.data() );
347 GL_ASSERT( glGetIntegerv( GL_FRAMEBUFFER_BINDING, &activeFbo ) );
349 m_fboAndViewportStack.emplace( activeFbo, std::move( activeViewport ) );
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;
379 if ( forceConstantTime ) { setRealTime(
false ); }
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 ) );
431 void 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 );
Utils::Index TaskId
Identifier for a task in the task queue.
static void registerMaterial()
static void unregisterMaterial()
static void unregisterMaterial()
static void registerMaterial()
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.
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)
Structure passed to each system before they fill the task queue.
Scalar m_dt
Time elapsed since the last frame in seconds.