Browse Source

Added GraphicsLoadToMemory and GraphicsLoadToVideoMemory components

Added GraphicsLoad components to mark the graphics objects that are loaded to system memory or video memory
Added move constructor and move assignment for LightComponent
Changed the lights from being processed in RendererScene to LightingPass; changed lights from being passed in arrays to using predetermined ECS views
Changed storing separate directional light variables to a single directional light data set in UniformData
Changed storing big camera data struct to just storing camera view matrix in SceneObjects in RendererScene
Fixed a bug of lights array overflow, when the number of lights in the scene exceed the allocated maximum
Removed some old unused code
Paul A 3 years ago
parent
commit
e04dd5ebb2

+ 1 - 1
Praxis3D/Praxis3D.vcxproj

@@ -261,7 +261,7 @@
     <ClInclude Include="Source\GeometryBuffer.h" />
     <ClInclude Include="Source\GeometryPass.h" />
     <ClInclude Include="Source\GraphicsDataSets.h" />
-    <ClInclude Include="Source\GraphicsLoadToMemoryComponent.h" />
+    <ClInclude Include="Source\GraphicsLoadComponents.h" />
     <ClInclude Include="Source\GraphicsObject.h" />
     <ClInclude Include="Source\GUICommandBuffer.h" />
     <ClInclude Include="Source\GUIDataManager.h" />

+ 1 - 1
Praxis3D/Praxis3D.vcxproj.filters

@@ -854,7 +854,7 @@
     <ClInclude Include="Source\MainMenuState.h">
       <Filter>Engine States\Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="Source\GraphicsLoadToMemoryComponent.h">
+    <ClInclude Include="Source\GraphicsLoadComponents.h">
       <Filter>Renderer\Objects\Header Files</Filter>
     </ClInclude>
   </ItemGroup>

+ 1 - 1
Praxis3D/Source/AtmScatteringPass.cpp

@@ -1,7 +1,7 @@
 
 #include "AtmScatteringPass.h"
 #include "AtmScatteringShaderPass.h"
-
+#include "RendererScene.h"
 
 void AtmScatteringPass::InitModel()
 {

+ 2 - 2
Praxis3D/Source/AtmScatteringPass.h

@@ -155,7 +155,7 @@ public:
 			//m_renderer.passUpdateCommandsToBackend();
 
 			// Perform various visual effects in the post process shader
-			m_renderer.queueForDrawing(m_skyShader->getShaderHandle(), m_skyShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+			m_renderer.queueForDrawing(m_skyShader->getShaderHandle(), m_skyShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 			
 		}
 		else
@@ -199,7 +199,7 @@ public:
 			//m_renderer.passUpdateCommandsToBackend();
 
 			// Perform various visual effects in the post process shader
-			m_renderer.queueForDrawing(m_groundShader->getShaderHandle(), m_groundShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+			m_renderer.queueForDrawing(m_groundShader->getShaderHandle(), m_groundShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		
 		}
 		

+ 1 - 1
Praxis3D/Source/BloomCompositePass.h

@@ -52,7 +52,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
 
 		// Perform various visual effects in the post process shader
-		m_renderer.queueForDrawing(m_bloomCompositeShader->getShaderHandle(), m_bloomCompositeShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_bloomCompositeShader->getShaderHandle(), m_bloomCompositeShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		p_renderPassData.swapColorInputOutputMaps();

+ 2 - 2
Praxis3D/Source/BloomPass.h

@@ -120,7 +120,7 @@ public:
 			const unsigned int groupY = (unsigned int)glm::ceil(mipmapSize.y / 8.0);
 
 			// Dispatch the compute shader
-			m_renderer.queueForDrawing(m_bloomDownscaleShader->getShaderHandle(), m_bloomDownscaleShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat, groupX, groupY, 1, MemoryBarrierType::MemoryBarrierType_AccessAndFetchBarrier);
+			m_renderer.queueForDrawing(m_bloomDownscaleShader->getShaderHandle(), m_bloomDownscaleShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix, groupX, groupY, 1, MemoryBarrierType::MemoryBarrierType_AccessAndFetchBarrier);
 			m_renderer.passComputeDispatchCommandsToBackend();
 			
 			// Half the mipmap size as we go up the mipmap levels
@@ -151,7 +151,7 @@ public:
 			const unsigned int groupY = (unsigned int)glm::ceil(mipmapSize.y / 8.0);
 
 			// Dispatch the compute shader
-			m_renderer.queueForDrawing(m_bloomUpscaleShader->getShaderHandle(), m_bloomUpscaleShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat, groupX, groupY, 1, MemoryBarrierType::MemoryBarrierType_AccessAndFetchBarrier);
+			m_renderer.queueForDrawing(m_bloomUpscaleShader->getShaderHandle(), m_bloomUpscaleShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix, groupX, groupY, 1, MemoryBarrierType::MemoryBarrierType_AccessAndFetchBarrier);
 			m_renderer.passComputeDispatchCommandsToBackend();
 		}
 	}

+ 4 - 4
Praxis3D/Source/BlurPass.h

@@ -73,7 +73,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getIntermediateMap());
 
 		// Perform verical blur. Queue and render a full screen quad using a vertical blur shader
-		m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		for(decltype(p_renderPassData.m_numOfBlurPasses) i = 0; i < p_renderPassData.m_numOfBlurPasses; i++)
@@ -85,7 +85,7 @@ public:
 			m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getBlurInputMap());
 
 			// Perform horizontal blur. Queue and render a full screen quad using a horizontal blur shader
-			m_renderer.queueForDrawing(m_blurHorizontalShader->getShaderHandle(), m_blurHorizontalShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+			m_renderer.queueForDrawing(m_blurHorizontalShader->getShaderHandle(), m_blurHorizontalShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 			m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 			// Bind emissive texture for reading so it can be accessed in the shaders
@@ -95,7 +95,7 @@ public:
 			m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getIntermediateMap());
 
 			// Perform verical blur. Queue and render a full screen quad using a vertical blur shader
-			m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+			m_renderer.queueForDrawing(m_blurVerticalShader->getShaderHandle(), m_blurVerticalShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 			m_renderer.passScreenSpaceDrawCommandsToBackend();
 		}
 
@@ -113,7 +113,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getBlurOutputMap());
 
 		// Perform horizontal blur. Queue and render a full screen quad using a horizontal blur shader
-		m_renderer.queueForDrawing(m_blurHorizontalShader->getShaderHandle(), m_blurHorizontalShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_blurHorizontalShader->getShaderHandle(), m_blurHorizontalShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		// If blending should be enabled

+ 11 - 2
Praxis3D/Source/EntityViewDefinitions.h

@@ -2,6 +2,9 @@
 
 #include <entt/entt.hpp>
 
+#include "CameraComponent.h"
+#include "GraphicsLoadComponents.h"
+#include "LightComponent.h"
 #include "ModelComponent.h"
 #include "ShaderComponent.h"
 #include "SpatialComponent.h"
@@ -10,5 +13,11 @@
 //class SpatialComponent;
 //class ShaderComponent;
 
-typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent, SpatialComponent>, entt::exclude_t<ShaderComponent>> ModelSpatialView;
-typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent, ShaderComponent, SpatialComponent>, entt::exclude_t<>> ModelShaderSpatialView;
+typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent, SpatialComponent>, entt::exclude_t<ShaderComponent, GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>> ModelSpatialView;
+typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent, ShaderComponent, SpatialComponent>, entt::exclude_t<GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>> ModelShaderSpatialView;
+typedef entt::basic_view<unsigned int, entt::get_t<LightComponent, SpatialComponent>, entt::exclude_t<>> LightSpatialView;
+
+//typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent>, entt::exclude_t<ShaderComponent, GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>> ModelLoadToVideoMemoryView;
+//typedef entt::basic_view<unsigned int, entt::get_t<ModelComponent, ShaderComponent>, entt::exclude_t<GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>> ModelShaderLoadToVideoMemoryView;
+
+typedef entt::basic_view<unsigned int, entt::get_t<GraphicsLoadToVideoMemoryComponent>, entt::exclude_t<GraphicsLoadToMemoryComponent>> LoadToVideoMemoryView;

+ 1 - 1
Praxis3D/Source/FinalPass.h

@@ -80,7 +80,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindFramebufferForWriting(GeometryBuffer::FramebufferDefault);
 
 		// Queue and render a full screen quad using a final pass shader
-		m_renderer.queueForDrawing(m_shaderFinalPass->getShaderHandle(), m_shaderFinalPass->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_shaderFinalPass->getShaderHandle(), m_shaderFinalPass->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 #endif // SETTING_USE_BLIT_FRAMEBUFFER

+ 2 - 2
Praxis3D/Source/GeometryPass.h

@@ -73,7 +73,7 @@ public:
 		for(auto entity : p_sceneObjects.m_models)
 		{
 			ModelComponent &model = p_sceneObjects.m_models.get<ModelComponent>(entity);
-			if(model.isObjectActive() && model.isLoadedToVideoMemory())
+			if(model.isObjectActive())
 			{
 				SpatialComponent &spatialData = p_sceneObjects.m_models.get<SpatialComponent>(entity);
 				auto &modelData = model.getModelData();
@@ -93,7 +93,7 @@ public:
 		for(auto entity : p_sceneObjects.m_modelsWithShaders)
 		{
 			ModelComponent &model = p_sceneObjects.m_modelsWithShaders.get<ModelComponent>(entity);
-			if(model.isObjectActive() && model.isLoadedToVideoMemory())
+			if(model.isObjectActive())
 			{
 				SpatialComponent &spatialData = p_sceneObjects.m_modelsWithShaders.get<SpatialComponent>(entity);
 				ShaderComponent &shader = p_sceneObjects.m_modelsWithShaders.get<ShaderComponent>(entity);

+ 11 - 2
Praxis3D/Source/GraphicsDataSets.h

@@ -249,13 +249,22 @@ struct RenderableMeshData
 
 struct DirectionalLightDataSet
 {
-	DirectionalLightDataSet(glm::vec3 p_color = glm::vec3(1.0f), 
+	DirectionalLightDataSet(glm::vec3 p_color = glm::vec3(0.0f), 
 		glm::vec3 p_direction = glm::vec3(0.0f, 1.0f, 0.0f),
-		float p_intensity = 1.0f) :
+		float p_intensity = 0.0f) :
 		m_color(p_color), 
 		m_direction(p_direction), 
 		m_intensity(p_intensity) { }
 
+	DirectionalLightDataSet &operator=(const DirectionalLightDataSet &p_other)
+	{
+		m_color = p_other.m_color;
+		m_direction = p_other.m_direction;
+		m_intensity = p_other.m_intensity;
+
+		return *this;
+	}
+
 	void clear()
 	{
 		m_color = glm::vec3(0.0f);

+ 33 - 0
Praxis3D/Source/GraphicsLoadComponents.h

@@ -0,0 +1,33 @@
+#pragma once
+
+#include <queue>
+
+#include "CommonDefinitions.h"
+#include "GraphicsDataSets.h"
+
+struct GraphicsLoadToMemoryComponent
+{
+	GraphicsLoadToMemoryComponent(const EntityID p_entityID) : m_entityID(p_entityID)
+	{
+		m_loaded = false;
+	}
+	~GraphicsLoadToMemoryComponent() { }
+
+	bool m_loaded;
+	EntityID m_entityID;
+};
+
+struct GraphicsLoadToVideoMemoryComponent
+{
+	GraphicsLoadToVideoMemoryComponent(const EntityID p_entityID) : m_entityID(p_entityID)
+	{
+		m_loaded = false;
+	}
+	~GraphicsLoadToVideoMemoryComponent() { }
+
+	bool m_loaded;
+	EntityID m_entityID;
+
+	// Objects that need to be loaded to VRAM
+	std::queue<LoadableObjectsContainer> m_objectsToLoad;
+};

+ 1 - 1
Praxis3D/Source/HdrMappingPass.h

@@ -96,7 +96,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBuffersForWriting(m_emissiveAndOutputBuffers);
 
 		// Perform HDR mapping. Queue and render a full screen quad using an HDR pass shader
-		m_renderer.queueForDrawing(m_hdrMappingShader->getShaderHandle(), m_hdrMappingShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_hdrMappingShader->getShaderHandle(), m_hdrMappingShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 		
 		p_renderPassData.setBlurInputMap(p_renderPassData.getEmissiveInputMap());

+ 1 - 1
Praxis3D/Source/LenseFlareCompositePass.h

@@ -84,7 +84,7 @@ public:
 		glBindTexture(GL_TEXTURE_2D, m_lenseFlareStarburst.getHandle());
 
 		// Perform various visual effects in the post process shader
-		m_renderer.queueForDrawing(m_lenseFlareShader->getShaderHandle(), m_lenseFlareShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_lenseFlareShader->getShaderHandle(), m_lenseFlareShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 		
 		p_renderPassData.swapColorInputOutputMaps();

+ 1 - 1
Praxis3D/Source/LenseFlarePass.h

@@ -124,7 +124,7 @@ public:
 		glBindTexture(GL_TEXTURE_2D, m_lensFlareGhostGradient.getHandle());
 
 		// Perform various visual effects in the post process shader
-		m_renderer.queueForDrawing(m_lenseFlareShader->getShaderHandle(), m_lenseFlareShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_lenseFlareShader->getShaderHandle(), m_lenseFlareShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		p_renderPassData.setBlurInputMap(GeometryBuffer::GBufferDiffuse);

+ 135 - 82
Praxis3D/Source/LightComponent.h

@@ -57,6 +57,40 @@ public:
 		m_lightComponentType = LightComponentType::LightComponentType_spot;
 		m_lightComponent.m_spot = p_lightDataSet;
 	}
+	LightComponent(const LightComponent &p_other)
+	{
+		m_lightComponentType = p_other.m_lightComponentType;
+
+		switch(m_lightComponentType)
+		{
+		case LightComponent::LightComponentType_directional:
+			m_lightComponent.m_directional = p_other.m_lightComponent.m_directional;
+			break;
+		case LightComponent::LightComponentType_point:
+			m_lightComponent.m_point = p_other.m_lightComponent.m_point;
+			break;
+		case LightComponent::LightComponentType_spot:
+			m_lightComponent.m_spot = p_other.m_lightComponent.m_spot;
+			break;
+		}
+	}
+	LightComponent(LightComponent &&p_other) noexcept
+	{
+		m_lightComponentType = p_other.m_lightComponentType;
+
+		switch(m_lightComponentType)
+		{
+		case LightComponent::LightComponentType_directional:
+			m_lightComponent.m_directional = p_other.m_lightComponent.m_directional;
+			break;
+		case LightComponent::LightComponentType_point:
+			m_lightComponent.m_point = p_other.m_lightComponent.m_point;
+			break;
+		case LightComponent::LightComponentType_spot:
+			m_lightComponent.m_spot = p_other.m_lightComponent.m_spot;
+			break;
+		}
+	}
 
 	~LightComponent()
 	{
@@ -72,6 +106,26 @@ public:
 		}
 	}
 
+	LightComponent &operator=(LightComponent &&p_other) noexcept
+	{
+		m_lightComponentType = p_other.m_lightComponentType;
+
+		switch(m_lightComponentType)
+		{
+		case LightComponent::LightComponentType_directional:
+			m_lightComponent.m_directional = p_other.m_lightComponent.m_directional;
+			break;
+		case LightComponent::LightComponentType_point:
+			m_lightComponent.m_point = p_other.m_lightComponent.m_point;
+			break;
+		case LightComponent::LightComponentType_spot:
+			m_lightComponent.m_spot = p_other.m_lightComponent.m_spot;
+			break;
+		}
+
+		return *this;
+	}
+
 	ErrorCode init()
 	{
 		// Mark the object as loaded, because there is nothing to be specifically loaded, at least for now
@@ -86,63 +140,63 @@ public:
 		ErrorCode importError = ErrorCode::Failure;
 
 		// Check if light node is present and the component hasn't been loaded already
-		if(p_properties && !isLoadedToMemory()) 
-		{	
-			// Get the light type
-			auto const &type = p_properties.getPropertyByID(Properties::Type).getID();
-
-			// Load values based on the type of light
-			switch(type)
-			{
-			case Properties::DirectionalLight:
-				m_lightComponentType = LightComponentType::LightComponentType_directional;
-				m_objectType = Properties::PropertyID::DirectionalLight;
-
-				m_lightComponent.m_directional.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
-				m_lightComponent.m_directional.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
-				setLoadedToMemory(true);
-				importError = ErrorCode::Success;
-
-				ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Directional light loaded");
-				break;
-
-			case Properties::PointLight:
-				m_lightComponentType = LightComponentType::LightComponentType_point;
-				m_objectType = Properties::PropertyID::PointLight;
-
-				m_lightComponent.m_point.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
-				m_lightComponent.m_point.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
-				setLoadedToMemory(true);
-				importError = ErrorCode::Success;
-
-				ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Point light loaded");
-				break;
-
-			case Properties::SpotLight:
-				m_lightComponentType = LightComponentType::LightComponentType_spot;
-				m_objectType = Properties::PropertyID::SpotLight;
-
-				m_lightComponent.m_spot.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
-				m_lightComponent.m_spot.m_cutoffAngle = p_properties.getPropertyByID(Properties::CutoffAngle).getFloat();
-				m_lightComponent.m_spot.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
-				setLoadedToMemory(true);
-				importError = ErrorCode::Success;
-
-				ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Spot light loaded");
-				break;
-
-			default:
-				ErrHandlerLoc().get().log(ErrorType::Warning, ErrorSource::Source_LightComponent, m_name + " - missing \'Type\' identifier");
-				break;
-			}
-
-			if(importError == ErrorCode::Success)
-			{
-				setLoadedToMemory(true);
-				setLoadedToVideoMemory(true);
-				setActive(true);
-			}
-		}
+		//if(p_properties && !isLoadedToMemory()) 
+		//{	
+		//	// Get the light type
+		//	auto const &type = p_properties.getPropertyByID(Properties::Type).getID();
+
+		//	// Load values based on the type of light
+		//	switch(type)
+		//	{
+		//	case Properties::DirectionalLight:
+		//		m_lightComponentType = LightComponentType::LightComponentType_directional;
+		//		m_objectType = Properties::PropertyID::DirectionalLight;
+
+		//		m_lightComponent.m_directional.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
+		//		m_lightComponent.m_directional.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
+		//		setLoadedToMemory(true);
+		//		importError = ErrorCode::Success;
+
+		//		ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Directional light loaded");
+		//		break;
+
+		//	case Properties::PointLight:
+		//		m_lightComponentType = LightComponentType::LightComponentType_point;
+		//		m_objectType = Properties::PropertyID::PointLight;
+
+		//		m_lightComponent.m_point.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
+		//		m_lightComponent.m_point.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
+		//		setLoadedToMemory(true);
+		//		importError = ErrorCode::Success;
+
+		//		ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Point light loaded");
+		//		break;
+
+		//	case Properties::SpotLight:
+		//		m_lightComponentType = LightComponentType::LightComponentType_spot;
+		//		m_objectType = Properties::PropertyID::SpotLight;
+
+		//		m_lightComponent.m_spot.m_color = p_properties.getPropertyByID(Properties::Color).getVec3f();
+		//		m_lightComponent.m_spot.m_cutoffAngle = p_properties.getPropertyByID(Properties::CutoffAngle).getFloat();
+		//		m_lightComponent.m_spot.m_intensity = p_properties.getPropertyByID(Properties::Intensity).getFloat();
+		//		setLoadedToMemory(true);
+		//		importError = ErrorCode::Success;
+
+		//		ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Spot light loaded");
+		//		break;
+
+		//	default:
+		//		ErrHandlerLoc().get().log(ErrorType::Warning, ErrorSource::Source_LightComponent, m_name + " - missing \'Type\' identifier");
+		//		break;
+		//	}
+
+		//	if(importError == ErrorCode::Success)
+		//	{
+		//		setLoadedToMemory(true);
+		//		setLoadedToVideoMemory(true);
+		//		setActive(true);
+		//	}
+		//}
 		return importError;
 	}
 
@@ -152,36 +206,36 @@ public:
 		PropertySet propertySet(Properties::Lighting);
 
 		// Add the properties based on the type of light
-		switch(getLightType())
-		{
-		case LightComponent::LightComponentType_directional:
-			propertySet.addProperty(Properties::Type, Properties::DirectionalLight);
-			propertySet.addProperty(Properties::Color, m_lightComponent.m_directional.m_color);
-			propertySet.addProperty(Properties::Intensity, m_lightComponent.m_directional.m_intensity);
+		//switch(getLightType())
+		//{
+		//case LightComponent::LightComponentType_directional:
+		//	propertySet.addProperty(Properties::Type, Properties::DirectionalLight);
+		//	propertySet.addProperty(Properties::Color, m_lightComponent.m_directional.m_color);
+		//	propertySet.addProperty(Properties::Intensity, m_lightComponent.m_directional.m_intensity);
 
-			ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Directional light exported.");
-			break;
+		//	ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Directional light exported.");
+		//	break;
 
-		case LightComponent::LightComponentType_point:
-			propertySet.addProperty(Properties::Type, Properties::PointLight);
-			propertySet.addProperty(Properties::Color, m_lightComponent.m_point.m_color);
-			propertySet.addProperty(Properties::Intensity, m_lightComponent.m_point.m_intensity);
+		//case LightComponent::LightComponentType_point:
+		//	propertySet.addProperty(Properties::Type, Properties::PointLight);
+		//	propertySet.addProperty(Properties::Color, m_lightComponent.m_point.m_color);
+		//	propertySet.addProperty(Properties::Intensity, m_lightComponent.m_point.m_intensity);
 
-			ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Point light exported.");
-			break;
+		//	ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Point light exported.");
+		//	break;
 
-		case LightComponent::LightComponentType_spot:
-			propertySet.addProperty(Properties::Type, Properties::SpotLight);
-			propertySet.addProperty(Properties::Color, m_lightComponent.m_spot.m_color);
-			propertySet.addProperty(Properties::CutoffAngle, m_lightComponent.m_spot.m_cutoffAngle);
-			propertySet.addProperty(Properties::Intensity, m_lightComponent.m_spot.m_intensity);
+		//case LightComponent::LightComponentType_spot:
+		//	propertySet.addProperty(Properties::Type, Properties::SpotLight);
+		//	propertySet.addProperty(Properties::Color, m_lightComponent.m_spot.m_color);
+		//	propertySet.addProperty(Properties::CutoffAngle, m_lightComponent.m_spot.m_cutoffAngle);
+		//	propertySet.addProperty(Properties::Intensity, m_lightComponent.m_spot.m_intensity);
 
-			ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Spot light exported.");
-			break;
+		//	ErrHandlerLoc().get().log(ErrorType::Info, ErrorSource::Source_LightComponent, m_name + " - Spot light exported.");
+		//	break;
 
-		default:
-			break;
-		}
+		//default:
+		//	break;
+		//}
 
 		return propertySet;
 	}
@@ -287,7 +341,6 @@ public:
 	inline SpotLightDataSet *getSpotLightSafe() { return (m_lightComponentType == LightComponentType::LightComponentType_spot) ? &m_lightComponent.m_spot : nullptr; }
 
 private:
-
 	inline void updateColor(const glm::vec3 &p_color)
 	{
 		// Update each type of light individually

+ 83 - 8
Praxis3D/Source/LightingPass.h

@@ -9,7 +9,9 @@ public:
 		RenderPass(p_renderer), 
 		m_pointLightBuffer(BufferType_Uniform, BufferBindTarget_Uniform, BufferUsageHint_DynamicDraw),
 		m_spotLightBuffer(BufferType_Uniform, BufferBindTarget_Uniform, BufferUsageHint_DynamicDraw),
-		m_shaderLightPass(nullptr) { }
+		m_shaderLightPass(nullptr),
+		m_maxNumPointLights(decltype(m_pointLights.size())(Config::graphicsVar().max_num_point_lights)),
+		m_maxNumSpotLights(decltype(m_spotLights.size())(Config::graphicsVar().max_num_spot_lights)) { }
 
 	~LightingPass() { }
 
@@ -24,8 +26,10 @@ public:
 		m_spotLightBuffer.m_bindingIndex = UniformBufferBinding_SpotLights;
 
 		// Set the light buffer sizes
-		m_pointLightBuffer.m_size = sizeof(PointLightDataSet) * Config::graphicsVar().max_num_point_lights;
-		m_spotLightBuffer.m_size = sizeof(SpotLightDataSet) * Config::graphicsVar().max_num_spot_lights;
+		m_pointLightBuffer.m_size = sizeof(PointLightDataSet) * m_maxNumPointLights;
+		m_spotLightBuffer.m_size = sizeof(SpotLightDataSet) * m_maxNumSpotLights;
+		m_pointLights.reserve(m_maxNumPointLights);
+		m_spotLights.reserve(m_maxNumSpotLights);
 		
 		// Set buffer values
 		m_emissiveAndOutputBuffers.resize(2);
@@ -69,13 +73,77 @@ public:
 		glDepthFunc(GL_GREATER);
 		glDepthMask(GL_FALSE);
 
+		// Clear light arrays from previous frame
+		m_pointLights.clear();
+		m_spotLights.clear();
+		m_directionalLight.clear();
+
+		// Iterate over all objects to be rendered with geometry shader
+		for(auto entity : p_sceneObjects.m_lights)
+		{
+			LightComponent &lightComponent = p_sceneObjects.m_lights.get<LightComponent>(entity);
+
+			// Check if the light is enabled
+			if(lightComponent.isObjectActive())
+			{
+				SpatialComponent &spatialComponent = p_sceneObjects.m_lights.get<SpatialComponent>(entity);
+
+				// Add the light data to the corresponding array, based on the light type
+				switch(lightComponent.getLightType())
+				{
+				case LightComponent::LightComponentType_point:
+				{
+					if(m_pointLights.size() < m_maxNumPointLights)
+					{
+						// Update position of the light data set
+						PointLightDataSet *lightDataSet = lightComponent.getPointLight();
+						lightDataSet->m_position = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[3];
+
+						m_pointLights.push_back(*lightDataSet);
+					}
+				}
+				break;
+
+				case LightComponent::LightComponentType_spot:
+				{
+					if(m_spotLights.size() < m_maxNumSpotLights)
+					{
+						// Update position and rotation of the light data set
+						SpotLightDataSet *lightDataSet = lightComponent.getSpotLight();
+						lightDataSet->m_position = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[3];
+						lightDataSet->m_direction = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[2];
+
+						m_spotLights.push_back(*lightDataSet);
+					}
+				}
+				break;
+
+				case LightComponent::LightComponentType_directional:
+				{
+					DirectionalLightDataSet *lightDataSet = lightComponent.getDirectionalLight();
+					lightDataSet->m_direction = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[2];
+
+					m_directionalLight = *lightDataSet;
+				}
+				break;
+				}
+			}
+		}
+
+		// Set the directional light data so it can be sent to the shader
+		m_renderer.m_frameData.m_directionalLight = m_directionalLight;
+
+		// Set number of lights so they can be send to the shader
+		m_renderer.m_frameData.m_numPointLights = (decltype(m_renderer.m_frameData.m_numPointLights))m_pointLights.size();
+		m_renderer.m_frameData.m_numSpotLights = (decltype(m_renderer.m_frameData.m_numSpotLights))m_spotLights.size();
+
 		// Setup point light buffer values
-		m_pointLightBuffer.m_updateSize = sizeof(PointLightDataSet) * p_sceneObjects.m_pointLights.size();
-		m_pointLightBuffer.m_data = (void*)p_sceneObjects.m_pointLights.data();
+		m_pointLightBuffer.m_updateSize = sizeof(PointLightDataSet) * m_pointLights.size();
+		m_pointLightBuffer.m_data = (void*)m_pointLights.data();
 
 		// Setup spot light buffer values
-		m_spotLightBuffer.m_updateSize = sizeof(SpotLightDataSet) * p_sceneObjects.m_spotLights.size();
-		m_spotLightBuffer.m_data = (void*)p_sceneObjects.m_spotLights.data();
+		m_spotLightBuffer.m_updateSize = sizeof(SpotLightDataSet) * m_spotLights.size();
+		m_spotLightBuffer.m_data = (void*)m_spotLights.data();
 
 		// Bind textures for reading
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForReading(GeometryBuffer::GBufferPosition, GeometryBuffer::GBufferPosition);
@@ -95,7 +163,7 @@ public:
 		m_renderer.passUpdateCommandsToBackend();
 
 		// Queue the screen space triangle, using lighting shader, to be drawn
-		m_renderer.queueForDrawing(m_shaderLightPass->getShaderHandle(), m_shaderLightPass->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_shaderLightPass->getShaderHandle(), m_shaderLightPass->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 
 		// Pass the draw command so it is executed
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
@@ -112,4 +180,11 @@ private:
 	// Light buffers
 	RendererFrontend::ShaderBuffer	m_pointLightBuffer, 
 									m_spotLightBuffer;
+
+	DirectionalLightDataSet m_directionalLight;
+	std::vector<PointLightDataSet> m_pointLights;
+	std::vector<SpotLightDataSet> m_spotLights;
+
+	decltype(m_pointLights.size()) m_maxNumPointLights;
+	decltype(m_spotLights.size()) m_maxNumSpotLights;
 };

+ 3 - 3
Praxis3D/Source/LuminancePass.h

@@ -93,7 +93,7 @@ public:
 
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferToImageUnitForReading(GeometryBuffer::GBufferFinal, GeometryBuffer::GBufferInputTexture, 0);
 
-		m_renderer.queueForDrawing(m_luminanceHistogramShader->getShaderHandle(), m_luminanceHistogramShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat, groupsX, groupsY, 1, MemoryBarrierType::MemoryBarrierType_ShaderStorageBarrier);
+		m_renderer.queueForDrawing(m_luminanceHistogramShader->getShaderHandle(), m_luminanceHistogramShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix, groupsX, groupsY, 1, MemoryBarrierType::MemoryBarrierType_ShaderStorageBarrier);
 		m_renderer.passComputeDispatchCommandsToBackend();
 
 		//glActiveTexture(GL_TEXTURE0);
@@ -101,7 +101,7 @@ public:
 
 		glBindImageTexture(0, m_luminanceAverageTexture.getHandle(), 0, GL_FALSE, 0, GL_READ_WRITE, GL_R16F);
 
-		m_renderer.queueForDrawing(m_luminanceAverageShader->getShaderHandle(), m_luminanceAverageShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat, 1, 1, 1, MemoryBarrierType::MemoryBarrierType_ShaderStorageBarrier);
+		m_renderer.queueForDrawing(m_luminanceAverageShader->getShaderHandle(), m_luminanceAverageShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix, 1, 1, 1, MemoryBarrierType::MemoryBarrierType_ShaderStorageBarrier);
 		m_renderer.passComputeDispatchCommandsToBackend();
 
 
@@ -115,7 +115,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
 
 		// Queue and render a full screen quad using a final pass shader
-		m_renderer.queueForDrawing(m_tonemappingShader->getShaderHandle(), m_tonemappingShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_tonemappingShader->getShaderHandle(), m_tonemappingShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		p_renderPassData.swapColorInputOutputMaps();

+ 1 - 1
Praxis3D/Source/PostProcessPass.h

@@ -99,7 +99,7 @@ public:
 		glBindTexture(GL_TEXTURE_2D, m_lensFlareGhostGradient.getHandle());
 
 		// Perform various visual effects in the post process shader
-		m_renderer.queueForDrawing(m_postProcessShader->getShaderHandle(), m_postProcessShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_postProcessShader->getShaderHandle(), m_postProcessShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		m_renderer.passScreenSpaceDrawCommandsToBackend();
 
 		p_renderPassData.swapColorInputOutputMaps();

+ 48 - 91
Praxis3D/Source/RendererFrontend.cpp

@@ -3,6 +3,7 @@
 #include "BloomCompositePass.h"
 #include "BloomPass.h"
 #include "BlurPass.h"
+#include "EntityViewDefinitions.h"
 #include "GeometryPass.h"
 #include "GUIPass.h"
 #include "LenseFlareCompositePass.h"
@@ -298,115 +299,73 @@ void RendererFrontend::renderFrame(SceneObjects &p_sceneObjects, const float p_d
 		}
 	}
 
-	// Handle loading before any rendering takes place
-	passLoadCommandsToBackend();
+	unsigned int numLoadedObjectsThisFrame = 0;
 
-	// Mark all loading-to-video-memory objects as loaded
-	for(decltype(p_sceneObjects.m_loadToVideoMemory.size()) i = 0, size = p_sceneObjects.m_loadToVideoMemory.size(); i < size; i++)
+	// Iterate over all objects to be rendered with geometry shader
+	for(auto entity : p_sceneObjects.m_objectsToLoadToVideoMemory)
 	{
-		switch(p_sceneObjects.m_loadToVideoMemory[i].m_objectType)
-		{
-		case LoadableObjectsContainer::LoadableObjectType_Model:
-			p_sceneObjects.m_loadToVideoMemory[i].m_loadableObject.m_model.setLoadedToVideoMemory(true);
-			break;
-		case LoadableObjectsContainer::LoadableObjectType_Shader:
-			p_sceneObjects.m_loadToVideoMemory[i].m_loadableObject.m_shader->setLoadedToVideoMemory(true);
-			break;
-		case LoadableObjectsContainer::LoadableObjectType_Texture:
-			p_sceneObjects.m_loadToVideoMemory[i].m_loadableObject.m_texture.setLoadedToVideoMemory(true);
-			break;
-		}
-	}
+		GraphicsLoadToVideoMemoryComponent &component = p_sceneObjects.m_objectsToLoadToVideoMemory.get<GraphicsLoadToVideoMemoryComponent>(entity);
 
-	// Clear the load-to-GPU queue, since everything in it has been processed
-	p_sceneObjects.m_loadToVideoMemory.clear();
-
-	glm::quat qPitch = glm::angleAxis(glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler.x), glm::vec3(1, 0, 0));
-	glm::quat qYaw = glm::angleAxis(glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler.y), glm::vec3(0, 1, 0));
-	glm::quat qRoll = glm::angleAxis(glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler.z), glm::vec3(0, 0, 1));
-	glm::quat orientation = qPitch * qYaw * qRoll;
-	
-	orientation = glm::toQuat(p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		while(!component.m_objectsToLoad.empty())
+		{
+			if(numLoadedObjectsThisFrame++ >= 1)
+				goto jumpAfterLoading;
 
-	//glm::quat orientation = qPitch * qYaw * qRoll; 
-	//glm::quat orientation(glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler));
-	orientation = glm::normalize(orientation);
-	glm::mat4 rotate = glm::mat4_cast(orientation);
-	glm::mat4 translate = glm::mat4(1.0f);
-	//translate = glm::translate(translate, -p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position);
-	translate = glm::translate(translate, -glm::vec3(p_sceneObjects.m_camera.m_spatialData.m_transformMat[3]));
-	//translate = glm::translate(translate, -glm::vec3(1.0f, 10.0f, 1.0f));
+			LoadableObjectsContainer &loadableObject = component.m_objectsToLoad.front();
 
-	m_frameData.m_viewMatrix = rotate * translate;
+			switch(loadableObject.m_objectType)
+			{
+			case LoadableObjectsContainer::LoadableObjectType_Model:
+				queueForLoading(loadableObject.m_loadableObject.m_model);
+				loadableObject.m_loadableObject.m_model.setLoadedToVideoMemory(true);
+				break;
+
+			case LoadableObjectsContainer::LoadableObjectType_Shader:
+				queueForLoading(*loadableObject.m_loadableObject.m_shader);
+				loadableObject.m_loadableObject.m_shader->setLoadedToVideoMemory(true);
+				break;
+
+			case LoadableObjectsContainer::LoadableObjectType_Texture:
+				queueForLoading(loadableObject.m_loadableObject.m_texture);
+				loadableObject.m_loadableObject.m_texture.setLoadedToVideoMemory(true);
+				break;
+			}
 
-	glm::mat4 rotationOnly = p_sceneObjects.m_camera.m_spatialData.m_transformMat;
-	rotationOnly[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f);
+			component.m_objectsToLoad.pop();
+		}
 
-	//m_frameData.m_viewMatrix = rotationOnly * translate;
+		component.m_loaded = true;
+	}
 
+	jumpAfterLoading:
 
-	//glm::vec3 direction = glm::rotate(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationQuat, glm::vec3(0.0f, 0.0f, -1.0f));
-	glm::vec3 direction = glm::normalize(glm::rotate(orientation, glm::vec3(0.0f, 0.0f, -1.0f)));
-	//direction = glm::normalize(direction);
-	glm::vec3 up = glm::normalize(glm::rotate(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationQuat, glm::vec3(0.0f, 1.0f, 0.0f)));
+	// Handle loading before any rendering takes place
+	passLoadCommandsToBackend();
 
-	//glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), -p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position);
-	//glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler.x), glm::vec3(1.0f, 0.0f, 0.0f));
-	//glm::mat4 View = glm::rotate(ViewRotateX, glm::radians(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler.y), glm::vec3(0.0f, 1.0f, 0.0f));
+	// Clear the load-to-GPU queue, since everything in it has been processed
+	p_sceneObjects.m_loadToVideoMemory.clear();
+	
+	// Calculate the view rotation matrix
+	const glm::quat orientation = glm::normalize(glm::toQuat(p_sceneObjects.m_cameraViewMatrix));
+	const glm::mat4 rotate = glm::mat4_cast(orientation);
 
-	//m_frameData.m_viewMatrix = View;
+	// Calculate the view translation matrix
+	const glm::mat4 translate = glm::translate(glm::mat4(1.0f), -glm::vec3(p_sceneObjects.m_cameraViewMatrix[3]));
 
-	//m_frameData.m_viewMatrix = glm::lookAt(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position, direction, up);
-	//m_frameData.m_viewMatrix = glm::lookAt(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position, direction, up);
-	//m_frameData.m_viewMatrix = glm::lookAt(p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position, glm::vec3(0.0f, 0.0, -1.0f), glm::vec3(0.0f, 1.0, 0.0f));
+	// Set the full view matrix
+	m_frameData.m_viewMatrix = rotate * translate;
 
-	// Calculate view and view-projection matrix here, so it is only done once, since it only changes between frames
-	//m_frameData.m_viewMatrix = p_sceneObjects.m_camera.m_spatialData.m_transformMat;
+	// Calculate the view-projection matrix here, so it is only done once, since it only changes between frames
 	m_frameData.m_viewProjMatrix = m_frameData.m_projMatrix * m_frameData.m_viewMatrix;
 	
 	// Convert the view matrix to row major for the atmospheric scattering shaders
 	m_frameData.m_transposeViewMatrix = glm::transpose(m_frameData.m_viewMatrix);
 
-	/*auto tempMatrix = m_frameData.m_viewMatrix;
-	
-	m_frameData.m_viewMatrix.m[0] = tempMatrix.m[0];
-	m_frameData.m_viewMatrix.m[1] = tempMatrix.m[4];
-	m_frameData.m_viewMatrix.m[2] = tempMatrix.m[8];
-	m_frameData.m_viewMatrix.m[3] = tempMatrix.m[12];
-	m_frameData.m_viewMatrix.m[4] = tempMatrix.m[1];
-	m_frameData.m_viewMatrix.m[5] = tempMatrix.m[5];
-	m_frameData.m_viewMatrix.m[6] = tempMatrix.m[9];
-	m_frameData.m_viewMatrix.m[7] = tempMatrix.m[13];
-	m_frameData.m_viewMatrix.m[8] = tempMatrix.m[2];
-	m_frameData.m_viewMatrix.m[9] = tempMatrix.m[6];
-	m_frameData.m_viewMatrix.m[10] = tempMatrix.m[10];
-	m_frameData.m_viewMatrix.m[11] = tempMatrix.m[14];
-	m_frameData.m_viewMatrix.m[12] = tempMatrix.m[3];
-	m_frameData.m_viewMatrix.m[13] = tempMatrix.m[7];
-	m_frameData.m_viewMatrix.m[14] = tempMatrix.m[11];
-	m_frameData.m_viewMatrix.m[15] = tempMatrix.m[15];*/
-
-	/*std::cout << "VIEW MATRIX:" << std::endl;
-	std::cout << m_frameData.m_viewMatrix.m[0] << " : " << m_frameData.m_viewMatrix.m[1] << " : " << m_frameData.m_viewMatrix.m[2] << " : " << m_frameData.m_viewMatrix.m[3] << std::endl;
-	std::cout << m_frameData.m_viewMatrix.m[4] << " : " << m_frameData.m_viewMatrix.m[5] << " : " << m_frameData.m_viewMatrix.m[6] << " : " << m_frameData.m_viewMatrix.m[7] << std::endl;
-	std::cout << m_frameData.m_viewMatrix.m[8] << " : " << m_frameData.m_viewMatrix.m[9] << " : " << m_frameData.m_viewMatrix.m[10] << " : " << m_frameData.m_viewMatrix.m[11] << std::endl;
-	std::cout << m_frameData.m_viewMatrix.m[12] << " : " << m_frameData.m_viewMatrix.m[13] << " : " << m_frameData.m_viewMatrix.m[14] << " : " << m_frameData.m_viewMatrix.m[15] << std::endl;
-	*/
 	// Set the camera position
-	m_frameData.m_cameraPosition = p_sceneObjects.m_camera.m_spatialData.m_transformMat[3]; //p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_position;
-	
-	// Set the camera target vector
-	m_frameData.m_cameraTarget = p_sceneObjects.m_camera.m_spatialData.m_spatialData.m_rotationEuler;
-
-	// Assign directional light values and also normalize its direction, so it's not necessary to do it in a shader
-	m_frameData.m_dirLightColor = p_sceneObjects.m_directionalLight->m_color;
-	m_frameData.m_dirLightIntensity = p_sceneObjects.m_directionalLight->m_intensity;
-	m_frameData.m_dirLightDirection = p_sceneObjects.m_directionalLight->m_direction;
-	m_frameData.m_dirLightDirection = glm::normalize(m_frameData.m_dirLightDirection);
+	m_frameData.m_cameraPosition = p_sceneObjects.m_cameraViewMatrix[3];
 
-	// Set number of lights so they can be send to the shader
-	m_frameData.m_numPointLights = (decltype(m_frameData.m_numPointLights))p_sceneObjects.m_pointLights.size();
-	m_frameData.m_numSpotLights = (decltype(m_frameData.m_numSpotLights))p_sceneObjects.m_spotLights.size();
+	// Set the camera target vector
+	m_frameData.m_cameraTarget = normalize(glm::vec3(p_sceneObjects.m_cameraViewMatrix[2]));
 	
 	// Prepare the geometry buffer for a new frame and a geometry pass
 	m_backend.getGeometryBuffer()->initFrame();
@@ -419,8 +378,6 @@ void RendererFrontend::renderFrame(SceneObjects &p_sceneObjects, const float p_d
 	glDepthFunc(Config::rendererVar().depth_test_func);
 	//glDisable(GL_CULL_FACE);
 
-	//m_renderingPasses[0]->update(p_sceneObjects, p_deltaTime);
-
 	for(decltype(m_renderingPasses.size()) i = 0, size = m_renderingPasses.size(); i < size; i++)
 	{
 		m_renderingPasses[i]->update(*m_renderPassData, p_sceneObjects, p_deltaTime);

+ 173 - 148
Praxis3D/Source/RendererScene.cpp

@@ -10,13 +10,13 @@
 RendererScene::RendererScene(RendererSystem *p_system, SceneLoader *p_sceneLoader) : SystemScene(p_system, p_sceneLoader)
 {
 	m_renderTask = new RenderTask(this, p_system->getRenderer());
-	m_camera = nullptr;
-	m_skybox = nullptr;
+	//m_camera = nullptr;
+	//m_skybox = nullptr;
 }
 
 RendererScene::~RendererScene()
 {
-	delete m_camera;
+	//delete m_camera;
 }
 
 ErrorCode RendererScene::init()
@@ -24,10 +24,10 @@ ErrorCode RendererScene::init()
 	ErrorCode returnError = ErrorCode::Success;
 			
 	// Create a default camera, in case it is not created upon loading a scene
-	m_camera = new CameraObject(this, "Default Camera");
+	//m_camera = new CameraObject(this, "Default Camera");
 
 	// Create a default directional light, in case it is not created upon loading a scene
-	m_directionalLight = new DirectionalLightObject(this, "Default Directional Light", DirectionalLightDataSet());
+	//m_directionalLight = new DirectionalLightObject(this, "Default Directional Light", DirectionalLightDataSet());
 	
 	// Create a default static environment map, so it can be used while a real one hasn't been loaded yet
 	//m_sceneObjects.m_staticSkybox = new EnvironmentMapObject(this, "default", Loaders::textureCubemap().load());
@@ -42,6 +42,8 @@ ErrorCode RendererScene::setup(const PropertySet &p_properties)
 	
 	// Reserve every component type that belongs to this scene
 	worldScene->reserve<CameraComponent>(Config::objectPoolVar().camera_component_default_pool_size);
+	worldScene->reserve<GraphicsLoadToMemoryComponent>(Config::objectPoolVar().model_component_default_pool_size + Config::objectPoolVar().shader_component_default_pool_size);
+	worldScene->reserve<GraphicsLoadToVideoMemoryComponent>(Config::objectPoolVar().model_component_default_pool_size + Config::objectPoolVar().shader_component_default_pool_size);
 	worldScene->reserve<LightComponent>(Config::objectPoolVar().light_component_default_pool_size);
 	worldScene->reserve<ModelComponent>(Config::objectPoolVar().model_component_default_pool_size);
 	worldScene->reserve<ShaderComponent>(Config::objectPoolVar().shader_component_default_pool_size);
@@ -54,25 +56,16 @@ ErrorCode RendererScene::preload()
 	// Get the entity registry 
 	auto &entityRegistry = static_cast<WorldScene *>(m_sceneLoader->getSystemScene(Systems::World))->getEntityRegistry();
 
-	std::vector<SystemObject*> componentsToLoad;
-	for(auto &component : m_componentsLoadingToMemory)
-	{
-		switch(component.m_componentType)
-		{
-			case LoadableComponentContainer::ComponentType_Model:
-			{
-				componentsToLoad.push_back(&entityRegistry.get<ModelComponent>(component.m_entityID));
-			}
-			break;
+	std::vector<SystemObject *> componentsToLoad;
 
-			case LoadableComponentContainer::ComponentType_Shader:
-			{
-				componentsToLoad.push_back(&entityRegistry.get<ShaderComponent>(component.m_entityID));
-			}
-			break;
-		}
-	}	
-	
+	auto modelAndLoadView = entityRegistry.view<ModelComponent, GraphicsLoadToMemoryComponent>();
+	for(auto entity : modelAndLoadView)
+		componentsToLoad.push_back(&modelAndLoadView.get<ModelComponent>(entity));
+
+	auto shaderAndLoadView = entityRegistry.view<ShaderComponent, GraphicsLoadToMemoryComponent>();
+	for(auto entity : shaderAndLoadView)
+		componentsToLoad.push_back(&shaderAndLoadView.get<ShaderComponent>(entity));
+		
 	// Load every object to memory. It still works in parallel, however,
 	// it returns only when all objects have finished loading (simulating sequential call)
 	TaskManagerLocator::get().parallelFor(size_t(0), componentsToLoad.size(), size_t(1), [=](size_t i)
@@ -91,7 +84,7 @@ void RendererScene::loadInBackground()
 	// Get the entity registry 
 	auto &entityRegistry = worldScene->getEntityRegistry();
 
-	auto modelView = worldScene->getEntityRegistry().view<ModelComponent>();
+	auto modelView = entityRegistry.view<ModelComponent>();
 	for(auto entity : modelView)
 	{
 		auto &component = modelView.get<ModelComponent>(entity);
@@ -99,7 +92,7 @@ void RendererScene::loadInBackground()
 		TaskManagerLocator::get().startBackgroundThread(std::bind(&ModelComponent::loadToMemory, &component));
 	}
 
-	auto shaderView = worldScene->getEntityRegistry().view<ShaderComponent>();
+	auto shaderView = entityRegistry.view<ShaderComponent>();
 	for(auto entity : shaderView)
 	{
 		auto &component = shaderView.get<ShaderComponent>(entity);
@@ -110,13 +103,6 @@ void RendererScene::loadInBackground()
 
 void RendererScene::update(const float p_deltaTime)
 {
-	// Clear variables from previous frame
-	m_sceneObjects.m_directionalLight = &m_directionalLight->getLightDataSet();
-
-	// Clear arrays from previous frame
-	m_sceneObjects.m_pointLights.clear();
-	m_sceneObjects.m_spotLights.clear();
-
 	// Get the world scene required for getting the entity registry
 	WorldScene *worldScene = static_cast<WorldScene*>(m_sceneLoader->getSystemScene(Systems::World));
 
@@ -126,89 +112,168 @@ void RendererScene::update(const float p_deltaTime)
 	//	 _______________________________
 	//	|							    |
 	//	| CURRENTLY LOADING COMPONENTS	|
+	//	|		TO VIDEO MEMORY			|
 	//	|_______________________________|
 	//
-	bool componentHasBeenLoaded = false;
-	decltype(Config::rendererVar().objects_loaded_per_frame) objectsThatCanBeLoadedThisFrame = Config::rendererVar().objects_loaded_per_frame;
-	auto it = m_componentsLoadingToMemory.begin();
-	while(it != m_componentsLoadingToMemory.end() && objectsThatCanBeLoadedThisFrame != 0)
+	// Remove the load-to-video-memory component for entities that have already been loaded during the previous frame
+	auto loadToVideoMemoryView = entityRegistry.view<GraphicsLoadToVideoMemoryComponent>(entt::exclude<GraphicsLoadToMemoryComponent>);
+	for(auto entity : loadToVideoMemoryView)
 	{
-		switch(it->m_componentType)
+		auto &loadToVideoMemoryComponent = loadToVideoMemoryView.get<GraphicsLoadToVideoMemoryComponent>(entity);
+		if(loadToVideoMemoryComponent.m_loaded)
 		{
-			case LoadableComponentContainer::ComponentType_Model:
-			{
-				ModelComponent &modelComponent = entityRegistry.get<ModelComponent>(it->m_entityID);
+			// Set model component as loaded to video memory, if it is present
+			auto modelComponent = entityRegistry.try_get<ModelComponent>(entity);
+			if(modelComponent != nullptr)
+				modelComponent->setLoadedToVideoMemory(true);
+
+			// Set shader component as loaded to video memory, if it is present
+			auto shaderComponent = entityRegistry.try_get<ShaderComponent>(entity);
+			if(shaderComponent != nullptr)
+				shaderComponent->setLoadedToVideoMemory(true);
+
+			// Remove load-to-video-memory component to mark the entity as loaded to GPU
+			worldScene->removeComponent<GraphicsLoadToVideoMemoryComponent>(entity);
+		}
+	}
 
-				// Perform a check that marks an object if it is loaded to memory
-				modelComponent.performCheckIsLoadedToMemory();
+	//	 _______________________________
+	//	|							    |
+	//	| CURRENTLY LOADING COMPONENTS	|
+	//	|		   TO MEMORY			|
+	//	|_______________________________|
+	//
+	// Check the entities that are being loaded to memory
+	// If they have already been loaded, remove the load-to-memory component and add the load-to-video-memory component, so they can be loaded to GPU in the renderer
+	/*auto modelAndLoadView = entityRegistry.view<ModelComponent, GraphicsLoadToMemoryComponent>(entt::exclude<ShaderComponent>);
+	for(auto entity : modelAndLoadView)
+	{
+		auto &modelComponent = modelAndLoadView.get<ModelComponent>(entity);
 
-				// If the object has loaded to memory already, add to load queue
-				if(modelComponent.isLoadedToMemory())
-				{
-					componentHasBeenLoaded = true;
+		// Perform a check that marks an object if it is loaded to memory
+		modelComponent.performCheckIsLoadedToMemory();
 
-					// Make the component active, so it is processed in the renderer
-					modelComponent.setActive(modelComponent.m_setActiveAfterLoading);
+		// If the object has loaded to memory already, add to load queue
+		if(modelComponent.isLoadedToMemory())
+		{
+			// Remove the load-to-memory component, signifying that it has already been loaded to memory
+			worldScene->removeComponent<GraphicsLoadToMemoryComponent>(entity);
 
-					//if(!modelComponent.isLoadedToVideoMemory())
-					modelComponent.performCheckIsLoadedToVideoMemory();
+			// Make the component active, so it is processed in the renderer
+			modelComponent.setActive(modelComponent.m_setActiveAfterLoading);
 
-					if(!modelComponent.isLoadedToVideoMemory())
-					{
-						// Get all loadable objects from the model component
-						auto loadableObjectsFromModel = modelComponent.getLoadableObjects();
+			// Do not add the load-to-video-memory component if the object is already loaded to GPU
+			modelComponent.performCheckIsLoadedToVideoMemory();
+			if(!modelComponent.isLoadedToVideoMemory())
+			{
+				auto &loadToVideoMemoryComponent = worldScene->addComponent<GraphicsLoadToVideoMemoryComponent>(entity, entity);
 
-						// Iterate over all loadable objects from the model component, and if any of them are not loaded to video memory already, add them to the to-load list
-						for(decltype(loadableObjectsFromModel.size()) size = loadableObjectsFromModel.size(), i = 0; i < size; i++)
-							if(!loadableObjectsFromModel[i].isLoadedToVideoMemory())
-								m_sceneObjects.m_loadToVideoMemory.emplace_back(loadableObjectsFromModel[i]);
-					}
-				}
+				// Get all loadable objects from the model component
+				auto loadableObjectsFromModel = modelComponent.getLoadableObjects();
+
+				// Iterate over all loadable objects from the model component, and if any of them are not loaded to video memory already, add them to the to-load list
+				for(decltype(loadableObjectsFromModel.size()) size = loadableObjectsFromModel.size(), i = 0; i < size; i++)
+					if(!loadableObjectsFromModel[i].isLoadedToVideoMemory())
+						loadToVideoMemoryComponent.m_objectsToLoad.emplace(loadableObjectsFromModel[i]);
 			}
-			break;
+		}
+	}*/
 
-			case LoadableComponentContainer::ComponentType_Shader:
+	// Check the entities that are being loaded to memory
+	// If they have already been loaded, remove the load-to-memory component and add the load-to-video-memory component, so they can be loaded to GPU in the renderer
+	auto modelAndLoadView = entityRegistry.view<ModelComponent, GraphicsLoadToMemoryComponent>();
+	for(auto entity : modelAndLoadView)
+	{
+		auto &modelComponent = modelAndLoadView.get<ModelComponent>(entity);
+		auto shaderComponent = entityRegistry.try_get<ShaderComponent>(entity);
+
+		// In addition to model component, the entity might contain a shader component too
+		// In that case, process both model and shader components
+		if(shaderComponent == nullptr)
+		{
+			// Perform a check that marks an object if it is loaded to memory
+			if(!modelComponent.isLoadedToMemory())
+				modelComponent.performCheckIsLoadedToMemory();
+
+			// If the object has loaded to memory already, add to load queue
+			if(modelComponent.isLoadedToMemory())
 			{
-				ShaderComponent &shaderComponent = entityRegistry.get<ShaderComponent>(it->m_entityID);
+				// Remove the load-to-memory component, signifying that it has already been loaded to memory
+				worldScene->removeComponent<GraphicsLoadToMemoryComponent>(entity);
 
-				// Perform a check that marks an object if it is loaded to memory
-				shaderComponent.performCheckIsLoadedToMemory();
+				// Make the component active, so it is processed in the renderer
+				modelComponent.setActive(modelComponent.m_setActiveAfterLoading);
 
-				// If the object has loaded to memory already, add to load queue
-				if(shaderComponent.isLoadedToMemory())
+				// Do not add the load-to-video-memory component if the object is already loaded to GPU
+				modelComponent.performCheckIsLoadedToVideoMemory();
+				if(!modelComponent.isLoadedToVideoMemory())
 				{
-					componentHasBeenLoaded = true;
+					auto &loadToVideoMemoryComponent = worldScene->addComponent<GraphicsLoadToVideoMemoryComponent>(entity, entity);
 
-					// Make the component active, so it is processed in the renderer
-					shaderComponent.setActive(shaderComponent.m_setActiveAfterLoading);
-
-					// Get all loadable objects from the shader component
-					auto loadableObjectsFromShader = shaderComponent.getLoadableObjects();
+					// Get all loadable objects from the model component
+					auto loadableObjectsFromModel = modelComponent.getLoadableObjects();
 
 					// Iterate over all loadable objects from the model component, and if any of them are not loaded to video memory already, add them to the to-load list
-					for(decltype(loadableObjectsFromShader.size()) size = loadableObjectsFromShader.size(), i = 0; i < size; i++)
-						if(!loadableObjectsFromShader[i].isLoadedToVideoMemory())
-							m_sceneObjects.m_loadToVideoMemory.emplace_back(loadableObjectsFromShader[i]);
+					for(decltype(loadableObjectsFromModel.size()) size = loadableObjectsFromModel.size(), i = 0; i < size; i++)
+						if(!loadableObjectsFromModel[i].isLoadedToVideoMemory())
+							loadToVideoMemoryComponent.m_objectsToLoad.emplace(loadableObjectsFromModel[i]);
 				}
 			}
-			break;
 		}
-
-		// If the component has been loaded, remove it from the list; otherwise just increment the iterator to continue to the next element
-		if(componentHasBeenLoaded)
+		else
 		{
-			// Remove the element from the list since it has been loaded to memory
-			it = m_componentsLoadingToMemory.erase(it);
+			// Perform a check on model component that marks an object if it is loaded to memory
+			if(!modelComponent.isLoadedToMemory())
+				modelComponent.performCheckIsLoadedToMemory();
 
-			// Decrement the count of the allowed number of objects that can be loaded per frame
-			objectsThatCanBeLoadedThisFrame--;
+			// If the model component has loaded to memory already, add to load queue
+			if(shaderComponent->isLoadedToMemory())
+			{
+				// Perform a check on shader component that marks an object if it is loaded to memory
+				if(!shaderComponent->isLoadedToMemory())
+					shaderComponent->performCheckIsLoadedToMemory();
 
-			componentHasBeenLoaded = false;
-		}
-		else
-		{
-			// Increment iterator since no elements have been removed
-			++it;
+				// If the shader component has loaded to memory already, add to load queue
+				if(shaderComponent->isLoadedToMemory())
+				{
+					// Remove the load-to-memory component, signifying that it has already been loaded to memory
+					worldScene->removeComponent<GraphicsLoadToMemoryComponent>(entity);
+
+					// Make the components active, so it is processed in the renderer
+					modelComponent.setActive(modelComponent.m_setActiveAfterLoading);
+					shaderComponent->setActive(shaderComponent->m_setActiveAfterLoading);
+
+					// Do not add the load-to-video-memory component if the object is already loaded to GPU
+					modelComponent.performCheckIsLoadedToVideoMemory();
+					shaderComponent->performCheckIsLoadedToVideoMemory();
+					if(!modelComponent.isLoadedToVideoMemory() || !shaderComponent->isLoadedToVideoMemory())
+					{
+						auto &loadToVideoMemoryComponent = worldScene->addComponent<GraphicsLoadToVideoMemoryComponent>(entity, entity);
+
+						if(!modelComponent.isLoadedToVideoMemory())
+						{
+							// Get all loadable objects from the model component
+							auto loadableObjectsFromModel = modelComponent.getLoadableObjects();
+
+								// Iterate over all loadable objects from the model component, and if any of them are not loaded to video memory already, add them to the to-load list
+								for(decltype(loadableObjectsFromModel.size()) size = loadableObjectsFromModel.size(), i = 0; i < size; i++)
+									if(!loadableObjectsFromModel[i].isLoadedToVideoMemory())
+										loadToVideoMemoryComponent.m_objectsToLoad.emplace(loadableObjectsFromModel[i]);
+						}
+
+						if(!shaderComponent->isLoadedToVideoMemory())
+						{
+							// Get all loadable objects from the shader component
+							auto loadableObjectsFromShader = shaderComponent->getLoadableObjects();
+
+							// Iterate over all loadable objects from the shader component, and if any of them are not loaded to video memory already, add them to the to-load list
+							for(decltype(loadableObjectsFromShader.size()) size = loadableObjectsFromShader.size(), i = 0; i < size; i++)
+								if(!loadableObjectsFromShader[i].isLoadedToVideoMemory())
+									loadToVideoMemoryComponent.m_objectsToLoad.emplace(loadableObjectsFromShader[i]);
+						}
+					}
+				}
+			}
 		}
 	}
 
@@ -217,7 +282,7 @@ void RendererScene::update(const float p_deltaTime)
 	//	|	  COMPONENT UPDATES		|
 	//	|___________________________|
 	//
-	auto modelView = worldScene->getEntityRegistry().view<ModelComponent>();
+	/*auto modelView = entityRegistry.view<ModelComponent>();
 	for(auto entity : modelView)
 	{
 		auto &component = modelView.get<ModelComponent>(entity);
@@ -226,90 +291,46 @@ void RendererScene::update(const float p_deltaTime)
 			component.performCheckIsLoadedToVideoMemory();
 	}
 
-	auto shaderView = worldScene->getEntityRegistry().view<ShaderComponent>();
+	auto shaderView = entityRegistry.view<ShaderComponent>();
 	for(auto entity : shaderView)
 	{
 		auto &component = shaderView.get<ShaderComponent>(entity);
 
 		if(!component.isLoadedToVideoMemory())
 			component.performCheckIsLoadedToVideoMemory();
-	}
+	}*/
 
 	//	 ___________________________
 	//	|							|
 	//	|	  MODEL COMPONENTS		|
 	//	|___________________________|
 	//
-	m_sceneObjects.m_models = worldScene->getEntityRegistry().view<ModelComponent, SpatialComponent>(entt::exclude<ShaderComponent>);
-	m_sceneObjects.m_modelsWithShaders = worldScene->getEntityRegistry().view<ModelComponent, ShaderComponent, SpatialComponent>();
+	m_sceneObjects.m_models = entityRegistry.view<ModelComponent, SpatialComponent>(entt::exclude<ShaderComponent, GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>);
+	m_sceneObjects.m_modelsWithShaders = entityRegistry.view<ModelComponent, ShaderComponent, SpatialComponent>(entt::exclude<GraphicsLoadToMemoryComponent, GraphicsLoadToVideoMemoryComponent>);
+	m_sceneObjects.m_objectsToLoadToVideoMemory = entityRegistry.view<GraphicsLoadToVideoMemoryComponent>(entt::exclude<GraphicsLoadToMemoryComponent>);
 
 	//	 ___________________________
 	//	|							|
 	//	|	  LIGHT COMPONENTS		|
 	//	|___________________________|
 	//
-	auto lightsView = worldScene->getEntityRegistry().view<LightComponent, SpatialComponent>();
-	for(auto entity : lightsView)
-	{
-		auto &lightComponent = lightsView.get<LightComponent>(entity);
-		auto &spatialComponent = lightsView.get<SpatialComponent>(entity);
-
-		// Check if the light is enabled
-		if(lightComponent.isObjectActive())
-		{
-			// Add the light data to the corresponding array, based on the light type
-			switch(lightComponent.getLightType())
-			{
-			case LightComponent::LightComponentType_point:
-			{
-				// Update position of the light data set
-				PointLightDataSet *lightDataSet = lightComponent.getPointLight();
-				lightDataSet->m_position = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[3];
-
-				m_sceneObjects.m_pointLights.push_back(*lightDataSet);
-			}
-				break;
-			case LightComponent::LightComponentType_spot:
-			{
-				// Update position and rotation of the light data set
-				SpotLightDataSet *lightDataSet = lightComponent.getSpotLight();
-				lightDataSet->m_position = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[3];
-				lightDataSet->m_direction = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[2];
-
-				m_sceneObjects.m_spotLights.push_back(*lightDataSet);
-			}
-				break;
-			case LightComponent::LightComponentType_directional:
-			{
-
-				DirectionalLightDataSet *lightDataSet = lightComponent.getDirectionalLight();
-				lightDataSet->m_direction = spatialComponent.getSpatialDataChangeManager().getWorldTransform()[2];
-
-				m_sceneObjects.m_directionalLight = lightComponent.getDirectionalLight();
-			}
-				break;
-			}
-		}
-	}
+	m_sceneObjects.m_lights = entityRegistry.view<LightComponent, SpatialComponent>();
 
 	//	 ___________________________
 	//	|							|
 	//	|	  CAMERA COMPONENTS		|
 	//	|___________________________|
 	//
-	auto cameraView = worldScene->getEntityRegistry().view<CameraComponent, SpatialComponent>();
+	auto cameraView = entityRegistry.view<CameraComponent, SpatialComponent>();
 	for(auto entity : cameraView)
 	{
 		auto &cameraComponent = cameraView.get<CameraComponent>(entity);
 		auto &spatialComponent = cameraView.get<SpatialComponent>(entity);
 
-		m_sceneObjects.m_camera.m_spatialData.m_transformMat = spatialComponent.getSpatialDataChangeManager().getWorldTransform();
+		m_sceneObjects.m_cameraViewMatrix = spatialComponent.getSpatialDataChangeManager().getWorldTransform();
 
 		break;
 	}
-
-	// Update camera spatial data
-	calculateCamera(m_sceneObjects.m_camera.m_spatialData);
 }
 
 std::vector<SystemObject*> RendererScene::createComponents(const EntityID p_entityID, const ComponentsConstructionInfo &p_constructionInfo, const bool p_startLoading)
@@ -359,7 +380,7 @@ SystemObject *RendererScene::createComponent(const EntityID &p_entityID, const L
 
 		auto &component = worldScene->addComponent<LightComponent>(p_entityID, this, p_constructionInfo.m_name, p_entityID);
 
-		// Try to initialize the camera component
+		// Try to initialize the light component
 		auto componentInitError = component.init();
 		if(componentInitError == ErrorCode::Success)
 		{
@@ -432,7 +453,7 @@ SystemObject *RendererScene::createComponent(const EntityID &p_entityID, const M
 
 		auto &component = worldScene->addComponent<ModelComponent>(p_entityID, this, p_constructionInfo.m_name, p_entityID);
 
-		// Try to initialize the camera component
+		// Try to initialize the model component
 		auto componentInitError = component.init();
 		if(componentInitError == ErrorCode::Success)
 		{
@@ -442,8 +463,9 @@ SystemObject *RendererScene::createComponent(const EntityID &p_entityID, const M
 			component.m_modelsProperties = new ModelComponent::ModelsProperties(p_constructionInfo.m_modelsProperties);
 			component.m_materialsFromProperties = new ModelComponent::MeshMaterialsProperties(p_constructionInfo.m_materialsFromProperties);
 
-			// Add the component to an array signifying that it is currently being loaded to memory
-			m_componentsLoadingToMemory.emplace_back(component);
+			// Add the load-to-memory component signifying that it is currently being loaded to memory
+			//m_componentsLoadingToMemory.emplace_back(component);
+			worldScene->addComponent<GraphicsLoadToMemoryComponent>(p_entityID, p_entityID);
 
 			// Start loading the component to memory in the background if the flag is set to do so
 			if(p_startLoading)
@@ -476,7 +498,7 @@ SystemObject *RendererScene::createComponent(const EntityID &p_entityID, const S
 
 		auto &component = worldScene->addComponent<ShaderComponent>(p_entityID, this, p_constructionInfo.m_name, p_entityID);
 
-		// Try to initialize the camera component
+		// Try to initialize the shader component
 		auto componentInitError = component.init();
 		if(componentInitError == ErrorCode::Success)
 		{
@@ -505,6 +527,9 @@ SystemObject *RendererScene::createComponent(const EntityID &p_entityID, const S
 
 			// Set the component as loaded, because the load function was called
 			//component.setLoadedToMemory(true);
+			// 
+			// Add the load-to-memory component signifying that it is currently being loaded to memory
+			worldScene->addComponent<GraphicsLoadToMemoryComponent>(p_entityID, p_entityID);
 
 			// Start loading the component to memory in the background if the flag is set to do so
 			if(p_startLoading)

+ 7 - 70
Praxis3D/Source/RendererScene.h

@@ -6,18 +6,12 @@
 
 #include <list>
 
-#include "CameraGraphicsObject.h"
 #include "EntityViewDefinitions.h"
-#include "EnvironmentMapObjects.h"
 #include "GraphicsDataSets.h"
-#include "GraphicsObject.h"
-#include "LightComponent.h"
-#include "LightingGraphicsObjects.h"
+#include "GraphicsLoadComponents.h"
 #include "Loaders.h"
 #include "ObjectPool.h"
-#include "ModelGraphicsObjects.h"
 #include "RenderTask.h"
-#include "ShaderGraphicsObjects.h"
 #include "System.h"
 
 class RendererSystem;
@@ -90,23 +84,16 @@ struct LoadableComponentContainer
 // Used to store processed objects, so they can be sent to the renderer
 struct SceneObjects
 {
-	SceneObjects() : /*m_staticSkybox(nullptr),*/ m_directionalLight(nullptr) { }
+	SceneObjects() { }
 
+	// ECS registry views
 	ModelSpatialView m_models;
 	ModelShaderSpatialView m_modelsWithShaders;
+	LightSpatialView m_lights;
+	LoadToVideoMemoryView m_objectsToLoadToVideoMemory;
 
 	// Camera
-	CameraData m_camera;
-	//EnvironmentMapObject *m_staticSkybox;
-
-	// Lights
-	const DirectionalLightDataSet *m_directionalLight;
-	std::vector<PointLightDataSet> m_pointLights;
-	std::vector<SpotLightDataSet> m_spotLights;
-
-	// Models
-	std::vector<ModelAndSpatialData> m_modelData;
-	std::vector<ModelShaderSpatialData> m_modelDataWithShaders;
+	glm::mat4 m_cameraViewMatrix;
 
 	// Objects that need to be loaded to VRAM
 	std::vector<LoadableObjectsContainer> m_loadToVideoMemory;
@@ -172,60 +159,10 @@ public:
 	inline SceneObjects &getSceneObjects() { return m_sceneObjects; }
 	
 private:
-	inline void calculateCamera(SpatialTransformData &p_viewData)
-	{
-		/*p_viewData.m_spatialData.m_rotationEuler = Math::toRadian(p_viewData.m_spatialData.m_rotationEuler);
-		p_viewData.m_spatialData.m_rotationEuler.y = 0.5f;
-		p_viewData.m_spatialData.m_rotationEuler.z = 3.14f;
-
-		const glm::vec3 upVector = Math::cross(p_viewData.m_spatialData.m_rotationEuler.z, p_viewData.m_spatialData.m_rotationEuler.y);
-		const glm::vec3 targetVector(0.0f, p_viewData.m_spatialData.m_rotationEuler.y, p_viewData.m_spatialData.m_rotationEuler.z);
-
-		p_viewData.m_transformMat.initCamera(p_viewData.m_spatialData.m_position, targetVector + p_viewData.m_spatialData.m_position, upVector);*/
-
-		//p_viewData.m_transformMat.identity();
-		//p_viewData.m_transformMat.translate(-p_viewData.m_spatialData.m_position);
-		//p_viewData.m_transformMat.rotate(p_viewData.m_spatialData.m_rotationEuler);
-
-		/*/p_viewData.m_transformMat
-
-		p_viewData.m_transformMat = glm::translate(p_viewData.m_transformMat, p_viewData.m_spatialData.m_position);
-
-		//glm::quat quaternion(glm::radians(p_rotation));
-		//returnMatrix *= glm::toMat4(quaternion);
-
-		glm::quat yawQ = glm::quat(glm::vec3(0.0f, glm::radians(p_viewData.m_spatialData.m_rotationEuler.y), 0.0f));
-		yawQ = glm::normalize(yawQ);
-		glm::mat4 yawMat = glm::mat4_cast(yawQ);
-
-		glm::quat pitchQ = glm::quat(glm::vec3(glm::radians(p_viewData.m_spatialData.m_rotationEuler.z), 0.0f, 0.0f));
-		pitchQ = glm::normalize(pitchQ);
-		glm::mat4 pitchMat = glm::mat4_cast(pitchQ);
-
-		glm::quat rollQ = glm::quat(glm::vec3(0.0f, 0.0f, glm::radians(p_viewData.m_spatialData.m_rotationEuler.z)));
-		rollQ = glm::normalize(rollQ);
-		glm::mat4 rollMat = glm::mat4_cast(rollQ);
-
-		p_viewData.m_transformMat *= pitchMat * yawMat * rollMat;
-
-		p_viewData.m_transformMat = glm::scale(p_viewData.m_transformMat, p_viewData.m_spatialData.m_scale);*/
-
-		//p_viewData.m_transformMat = Math::createTransformMat(-p_viewData.m_spatialData.m_position, p_viewData.m_spatialData.m_rotationEuler, p_viewData.m_spatialData.m_scale);
-
-	}
-
 	MaterialData loadMaterialData(PropertySet &p_materialProperty, Model::MaterialArrays &p_materialArraysFromModel, MaterialType p_materialType, std::size_t p_meshIndex);
 
-	// Stores objects that are currently being loaded to memory in a background thread
-	std::list<LoadableComponentContainer> m_componentsLoadingToMemory;
-		
-	EnvironmentMapObject *m_skybox;
-
-	// Only one camera present at a time
-	CameraObject *m_camera;
-
 	// Only one directional light present at a time
-	DirectionalLightObject *m_directionalLight;
+	DirectionalLightDataSet m_directionalLight;
 
 	// Used to store processed objects
 	SceneObjects m_sceneObjects;

+ 3 - 3
Praxis3D/Source/ShaderUniforms.h

@@ -578,7 +578,7 @@ public:
 
 	void update(const UniformData &p_uniformData)
 	{
-		auto &dirLightColor = p_uniformData.m_frameData.m_dirLightColor;
+		auto &dirLightColor = p_uniformData.m_frameData.m_directionalLight.m_color;
 		glUniform3f(m_uniformHandle, dirLightColor.x, dirLightColor.y, dirLightColor.z);
 	}
 };
@@ -589,7 +589,7 @@ public:
 
 	void update(const UniformData &p_uniformData)
 	{
-		auto lightDirection = p_uniformData.m_frameData.m_dirLightDirection;
+		auto lightDirection = p_uniformData.m_frameData.m_directionalLight.m_direction;
 		glUniform3f(m_uniformHandle, lightDirection.x, lightDirection.y, lightDirection.z);
 	}
 };
@@ -600,7 +600,7 @@ public:
 
 	void update(const UniformData &p_uniformData)
 	{
-		glUniform1f(m_uniformHandle, p_uniformData.m_frameData.m_dirLightIntensity);
+		glUniform1f(m_uniformHandle, p_uniformData.m_frameData.m_directionalLight.m_intensity);
 	}
 };
 class NumPointLightsUniform : public BaseUniform

+ 1 - 1
Praxis3D/Source/SkyPass.h

@@ -58,7 +58,7 @@ public:
 		m_renderer.m_backend.getGeometryBuffer()->bindBufferForWriting(p_renderPassData.getColorOutputMap());
 
 		// Perform various visual effects in the post process shader
-		m_renderer.queueForDrawing(m_skyPassShader->getShaderHandle(), m_skyPassShader->getUniformUpdater(), p_sceneObjects.m_camera.m_spatialData.m_transformMat);
+		m_renderer.queueForDrawing(m_skyPassShader->getShaderHandle(), m_skyPassShader->getUniformUpdater(), p_sceneObjects.m_cameraViewMatrix);
 		
 		// Pass the draw command so it is executed
 		m_renderer.passScreenSpaceDrawCommandsToBackend();

+ 2 - 4
Praxis3D/Source/UniformData.h

@@ -1,12 +1,12 @@
 #pragma once
 
+#include "GraphicsDataSets.h"
 #include "Math.h"
 
 struct UniformFrameData
 {
 	UniformFrameData()
 	{
-		m_dirLightIntensity = 0.0f;
 		m_numPointLights = 0;
 		m_numSpotLights = 0;
 		m_deltaTime = 0.0f;
@@ -30,9 +30,7 @@ struct UniformFrameData
 				m_transposeViewMatrix;
 
 	// Parameters of direction light, since there can be only one of it
-	glm::vec3 m_dirLightColor,
-				m_dirLightDirection;
-	float		m_dirLightIntensity;
+	DirectionalLightDataSet m_directionalLight;
 
 	// Delta time of the last frame
 	float		m_deltaTime;

+ 8 - 0
Praxis3D/imgui.ini

@@ -223,3 +223,11 @@ Column 0  Sort=0v
 RefScale=13
 Column 0  Sort=0v
 
+[Table][0x43B90C98,4]
+RefScale=13
+Column 0  Sort=0v
+
+[Table][0xFF74E4BC,4]
+RefScale=13
+Column 0  Sort=0v
+