Exemple #1
0
	//------------------------------------------------------------------------------------------
	void CPreviewerView::Render()
	{
		CGraphicDevice* pDevice = CApp::GetInstance()->GetGraphicDevice(); MY_ASSERT( pDevice );

		// カメラ設定
		CCameraController *pCameraController = dynamic_cast<CCameraController*>( m_pMouseHandler );
		pDevice->SetCameraInfo( pCameraController->GetCameraInfo() );

		// ライト設定				
		// 0 Fill
		D3DXVECTOR3 vLightDir0( 1, -1, -1); D3DXVec3Normalize( &vLightDir0, &vLightDir0);		
		pDevice->SetDirLightDir( 0, vLightDir0.x, vLightDir0.y, vLightDir0.z );
		pDevice->SetDirLightColor( 0, 1.0f, 1.0f, 1.0f );		
		// 1 Back
		D3DXVECTOR3 vLightDir1( 0, 0, -1); D3DXVec3Normalize( &vLightDir1, &vLightDir1);		
		pDevice->SetDirLightDir( 1, vLightDir1.x, vLightDir1.y, vLightDir1.z );
		pDevice->SetDirLightColor( 1, 0.0f, 0.0f, 0.0f );		
		// 2 Key
		D3DXVECTOR3 vLightDir2( -1, -1, 0); D3DXVec3Normalize( &vLightDir2, &vLightDir2);		
		pDevice->SetDirLightDir( 2, vLightDir2.x, vLightDir2.y, vLightDir2.z );
		pDevice->SetDirLightColor( 2, 0.0f, 0.0f, 0.0f );		

		// モデルをレンダリング		
		m_pModel->Render();
	}
Exemple #2
0
void CCameraHandler::SetCameraMode(unsigned int mode)
{
	if ((mode >= camControllers.size()) || (mode == static_cast<unsigned int>(currCamCtrlNum))) {
		return;
	}

	CameraTransition(1.0f);

	CCameraController* oldCamCtrl = currCamCtrl;

	currCamCtrlNum = mode;
	currCamCtrl = camControllers[mode];
	currCamCtrl->SetPos(oldCamCtrl->SwitchFrom());
	currCamCtrl->SwitchTo();
}
void CMouseHandler::SetCameraMode(int mode)
{
	if ((mode < 0)
	 || (mode >= camControllers.size())
	 || (mode == currentCamControllerNum)
	 || (!camControllers[currentCamControllerNum]->enabled)) {
		return;
	}

	currentCamControllerNum = mode;
	CameraTransition(1.0f);

	CCameraController* oldc = currentCamController;
	currentCamController = camControllers[currentCamControllerNum];
	currentCamController->SetPos(oldc->SwitchFrom());
	currentCamController->SwitchTo();
}
void CApplication::SetupScene()
{
	RenderPass = new CRenderPass(GraphicsContext);
	RenderPass->SetRenderTarget(RenderTarget);
	SceneManager->AddRenderPass(RenderPass);

	FreeCamera = new CPerspectiveCamera(Window->GetAspectRatio());
	FreeCamera->SetPosition(vec3f(0, 3, -5));
	FreeCamera->SetFocalLength(0.4f);
	FreeCamera->SetFarPlane(10000.f);

	CCameraController * Controller = new CCameraController(FreeCamera);
	Controller->SetTheta(15.f * Constants32::Pi / 48.f);
	Controller->SetPhi(-Constants32::Pi / 16.f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);

	RenderPass->SetActiveCamera(FreeCamera);
}
Exemple #5
0
void CCameraHandler::UpdateController(CCameraController& camCon, bool keyMove, bool wheelMove, bool edgeMove)
{
	if (keyMove) {
		// NOTE: z-component contains speed scaling factor, xy is movement
		const float3 camMoveVector = camera->GetMoveVectorFromState(true);

		// key scrolling
		if ((camMoveVector * XYVector).SqLength() > 0.0f) {
			if (camCon.DisableTrackingByKey())
				unitTracker.Disable();

			camCon.KeyMove(camMoveVector);
		}
	}

	if (edgeMove) {
		const float3 camMoveVector = camera->GetMoveVectorFromState(false);

		// screen edge scrolling
		if ((camMoveVector * XYVector).SqLength() > 0.0f) {
			unitTracker.Disable();
			camCon.ScreenEdgeMove(camMoveVector);
		}
	}

	if (wheelMove) {
		// mouse wheel zoom
		float mouseWheelDist = 0.0f;
		mouseWheelDist +=  float(camera->GetMovState()[CCamera::MOVE_STATE_UP]);
		mouseWheelDist += -float(camera->GetMovState()[CCamera::MOVE_STATE_DWN]);
		mouseWheelDist *= 0.2f * globalRendering->lastFrameTime;

		if (mouseWheelDist == 0.0f)
			return;

		camCon.MouseWheelMove(mouseWheelDist);
	}
}
Exemple #6
0
void CCameraHandler::ToggleState()
{
	CameraTransition(1.0f);

	CCameraController* oldCamCtrl = currCamCtrl;
	currCamCtrlNum++;
	if (currCamCtrlNum >= camControllers.size()) {
		currCamCtrlNum = 0;
	}

	int a = 0;
	const int maxTries = camControllers.size() - 1;
	while ((a < maxTries) && !camControllers[currCamCtrlNum]->enabled) {
		currCamCtrlNum++;
		if (currCamCtrlNum >= camControllers.size()) {
			currCamCtrlNum = 0;
		}
		a++;
	}

	currCamCtrl = camControllers[currCamCtrlNum];
	currCamCtrl->SetPos(oldCamCtrl->SwitchFrom());
	currCamCtrl->SwitchTo();
}
Exemple #7
0
void CCameraHandler::SetCameraMode(unsigned int newMode)
{
	if ((newMode >= camControllers.size()) || (newMode == currCamCtrlNum))
		return;

	CameraTransition(1.0f);

	const unsigned int oldMode = currCamCtrlNum;

	CCameraController* oldCamCtrl = camControllers[currCamCtrlNum          ];
	CCameraController* newCamCtrl = camControllers[currCamCtrlNum = newMode];

	newCamCtrl->SetPos(oldCamCtrl->SwitchFrom());
	newCamCtrl->SwitchTo(oldMode);
	newCamCtrl->Update();
}
int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;
	SingletonPointer<CGUIManager> GUIManager;

	GraphicsAPI->Init(new COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	CWindow * Window = WindowManager->CreateWindow(vec2i(1920, 1080), "Shadow Maps", EWindowType::Windowed);

	GUIManager->Init(Window);
	Window->AddListener(GUIManager);

	AssetManager->AddAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> BackBuffer = Context->GetBackBuffer();
	BackBuffer->SetClearColor(color3f(0.3f));

	SharedPointer<IFrameBuffer> ShadowBuffer = Context->CreateFrameBuffer();

	SharedPointer<ITexture2D> ShadowTexture = GraphicsAPI->CreateTexture2D(vec2i(4096), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGBA, ITexture::EInternalFormatType::Fix8);
	SharedPointer<ITexture2D> ShadowDepth = GraphicsAPI->CreateTexture2D(vec2i(4096), ITexture::EMipMaps::False, ITexture::EFormatComponents::R, ITexture::EInternalFormatType::Depth);
	ShadowBuffer->AttachColorTexture(ShadowTexture, 0);
	ShadowBuffer->AttachDepthTexture(ShadowDepth);
	if (! ShadowBuffer->CheckCorrectness())
	{
		Log::Error("Frame buffer not valid!");
	}


	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));
	CSimpleMesh * CubeMesh = CGeometryCreator::CreateCube();

	SharedPointer<IShader> DiffuseShader = AssetManager->LoadShader("Diffuse");
	SharedPointer<IShader> ColorShader = AssetManager->LoadShader("Color");
	SharedPointer<IShader> QuadCopyShader = AssetManager->LoadShader("QuadCopy");


	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * ShadowPass = new CRenderPass(Context);
	ShadowPass->SetRenderTarget(ShadowBuffer);
	SceneManager->AddRenderPass(ShadowPass);

	CRenderPass * ColorPass = new CRenderPass(Context);
	ColorPass->SetRenderTarget(BackBuffer);
	SceneManager->AddRenderPass(ColorPass);

	CRenderPass * PostProcess = new CRenderPass(Context);
	PostProcess->SetRenderTarget(BackBuffer);
	SceneManager->AddRenderPass(PostProcess);

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(15.25f, 7.3f, -11.85f));
	Camera->SetFocalLength(0.4f);
	Camera->SetFarPlane(1000.f);
	ColorPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(2.347f);
	Controller->SetPhi(-0.326f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);

	COrthographicCamera * LightCamera = new COrthographicCamera(-1, 1, -1, 1);
	ShadowPass->SetActiveCamera(LightCamera);


	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * Sphere1 = new CSimpleMeshSceneObject();
	Sphere1->SetMesh(SphereMesh);
	Sphere1->SetShader(DiffuseShader);
	Sphere1->SetPosition(vec3f(0, 1, 0));
	Sphere1->SetScale(2.f);
	ColorPass->AddSceneObject(Sphere1);
	ShadowPass->AddSceneObject(Sphere1);

	CSimpleMeshSceneObject * Sphere2 = new CSimpleMeshSceneObject();
	Sphere2->SetMesh(SphereMesh);
	Sphere2->SetShader(DiffuseShader);
	Sphere2->SetPosition(vec3f(4, 4, 0));
	Sphere2->SetScale(3.f);
	Sphere2->GetMaterial().Ambient *= Color::Basic::Yellow;
	Sphere2->GetMaterial().Diffuse *= Color::Basic::Yellow;
	ColorPass->AddSceneObject(Sphere2);
	ShadowPass->AddSceneObject(Sphere2);

	CSimpleMeshSceneObject * Sphere3 = new CSimpleMeshSceneObject();
	Sphere3->SetMesh(SphereMesh);
	Sphere3->SetShader(DiffuseShader);
	Sphere3->SetPosition(vec3f(12, 2, 0));
	Sphere3->SetScale(4.f);
	ColorPass->AddSceneObject(Sphere3);
	ShadowPass->AddSceneObject(Sphere3);

	CSimpleMeshSceneObject * Sphere4 = new CSimpleMeshSceneObject();
	Sphere4->SetMesh(SphereMesh);
	Sphere4->SetShader(DiffuseShader);
	Sphere4->SetPosition(vec3f(3, 4, 6));
	Sphere4->GetMaterial().Ambient *= Color::Basic::Red;
	Sphere4->GetMaterial().Diffuse *= Color::Basic::Red;
	ColorPass->AddSceneObject(Sphere4);
	ShadowPass->AddSceneObject(Sphere4);

	CSimpleMeshSceneObject * Cube1 = new CSimpleMeshSceneObject();
	Cube1->SetMesh(CubeMesh);
	Cube1->SetShader(DiffuseShader);
	Cube1->SetPosition(vec3f(-4, 4, 0));
	Cube1->SetScale(3.f);
	Cube1->GetMaterial().Ambient *= Color::Basic::Cyan;
	Cube1->GetMaterial().Diffuse *= Color::Basic::Cyan;
	ColorPass->AddSceneObject(Cube1);
	ShadowPass->AddSceneObject(Cube1);

	CSimpleMeshSceneObject * Cube2 = new CSimpleMeshSceneObject();
	Cube2->SetMesh(CubeMesh);
	Cube2->SetShader(DiffuseShader);
	Cube2->SetPosition(vec3f(-12, 2, 0));
	Cube2->SetScale(4.f);
	Cube2->GetMaterial().Ambient *= Color::Basic::Blue;
	Cube2->GetMaterial().Diffuse *= Color::Basic::Blue;
	ColorPass->AddSceneObject(Cube2);
	ShadowPass->AddSceneObject(Cube2);

	CSimpleMeshSceneObject * Plane = new CSimpleMeshSceneObject();
	Plane->SetMesh(PlaneMesh);
	Plane->SetShader(DiffuseShader);
	Plane->GetMaterial().Ambient *= Color::Basic::Green;
	Plane->GetMaterial().Diffuse *= Color::Basic::Green;
	ColorPass->AddSceneObject(Plane);
	ShadowPass->AddSceneObject(Plane);

	vector<CSimpleMesh *> Meshes = CGeometryCreator::LoadOBJFile("bunny.obj");
	for (auto Mesh : Meshes)
	{
		CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
		PlaneObject->SetMesh(Mesh);
		PlaneObject->SetShader(DiffuseShader);
		PlaneObject->SetPosition(vec3f(3, -1.f, -6));
		PlaneObject->SetScale(vec3f(2.5f));
		PlaneObject->SetRotation(vec3f(0, 3.14f / 4.f, 0));
		ColorPass->AddSceneObject(PlaneObject);
		ShadowPass->AddSceneObject(PlaneObject);
	}

	CLineSceneObject * Lines = new CLineSceneObject();
	Lines->SetShader(ColorShader);
	ColorPass->AddSceneObject(Lines);

	CSimpleMeshSceneObject * PostProcessObject = new CSimpleMeshSceneObject();
	PostProcessObject->SetMesh(CreateScreenQuad());
	PostProcessObject->SetShader(QuadCopyShader);
	PostProcessObject->SetTexture("uTexture", ShadowDepth);
	PostProcess->AddSceneObject(PostProcessObject);

	CDirectionalLight * Light1 = new CDirectionalLight();
	ColorPass->AddLight(Light1);
	ShadowPass->AddLight(Light1);

	CSimpleMeshSceneObject * LightSphere = new CSimpleMeshSceneObject();
	LightSphere->SetMesh(SphereMesh);
	LightSphere->SetShader(DiffuseShader);
	LightSphere->SetScale(0.4f);
	LightSphere->GetMaterial().Ambient = 1.f / 0.75f;
	LightSphere->GetMaterial().Diffuse = 0;
	ColorPass->AddSceneObject(LightSphere);


	CUniform<bool> uDebugShadows = false;
	CUniform<float> uShadowBias = 0.005f;
	CUniform<glm::mat4> uLightMatrix;

	ColorPass->SetUniform("uLightMatrix", uLightMatrix);
	ColorPass->SetUniform("uDebugShadows", uDebugShadows);
	ColorPass->SetUniform("uShadowBias", uShadowBias);
	ColorPass->SetTexture("uShadowMap", ShadowDepth);

	// Obviously the shadow pass does not need these, but this will suppress warnings
	// An object that supports different shaders for different passes is needed
	ShadowPass->SetUniform("uLightMatrix", uLightMatrix);
	ShadowPass->SetUniform("uDebugShadows", uDebugShadows);
	ShadowPass->SetUniform("uShadowBias", uShadowBias);
	ShadowPass->SetTexture("uShadowMap", ShadowDepth);


	///////////////
	// Main Loop //
	///////////////

	vec3f LightDirection = Normalize( vec3f(2, -12, 2) );
	float LightViewSize = 20.f;
	float LightNear = 1.f;
	float LightFar = 30.f;
	float LightDistance = 15.f;


	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		PostProcessObject->SetVisible(Window->IsKeyDown(EKey::F1));

		GUIManager->NewFrame();
		ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiSetCond_Once);
		ImGui::SetNextWindowSize(ImVec2(400, 300), ImGuiSetCond_Once);
		if (ImGui::Begin("Settings"))
		{
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
			ImGui::Text("Camera position: %.3f %.3f %.3f", Camera->GetPosition().X, Camera->GetPosition().Y, Camera->GetPosition().Z);
			ImGui::Text("Camera rotation: %.3f %.3f", Controller->GetTheta(), Controller->GetPhi());

			ImGui::Separator();

			ImGui::SliderFloat("Light Camera Size", &LightViewSize, 1.f, 200.f);
			ImGui::SliderFloat("Light Near Plane", &LightNear, 1.f, 300.f);
			ImGui::SliderFloat("Light Far Plane", &LightFar, 1.f, 600.f);

			ImGui::SliderFloat("Light Camera Distance", &LightDistance, 1.f, 200.f);
			ImGui::Text("Light Position: %.3f %.3f %.3f", LightCamera->GetPosition().X, LightCamera->GetPosition().Y, LightCamera->GetPosition().Z);

			ImGui::Separator();

			ImGui::Checkbox("Debug Shadows", &uDebugShadows.Get());
			ImGui::SliderFloat("Shadow Bias", &uShadowBias.Get(), 0.0f, 0.5f, "%.6f", 2.f);
		}
		ImGui::End();

		ImGui::SetNextWindowPos(vec2f(600, 10), ImGuiSetCond_Once);
		ImGui::SetNextWindowSize(vec2f(300), ImGuiSetCond_Once);
		if (ImGui::Begin("Shadow Map"))
		{
			vec2f const AvailableSpace = ImGui::GetContentRegionAvail();
			ImGui::Image(GUIManager->GetTextureID(ShadowDepth), AvailableSpace);
		}
		ImGui::End();

		Light1->SetDirection(LightDirection);
		LightSphere->SetPosition(LightDirection * LightDistance);

		LightCamera->SetLeft(-LightViewSize);
		LightCamera->SetRight(LightViewSize);
		LightCamera->SetBottom(-LightViewSize);
		LightCamera->SetTop(LightViewSize);
		LightCamera->SetPosition(-LightDirection * LightDistance);
		LightCamera->SetLookDirection(LightDirection);
		LightCamera->SetNearPlane(LightNear);
		LightCamera->SetFarPlane(LightFar);
		LightCamera->Update();
		uLightMatrix = LightCamera->GetProjectionMatrix() * LightCamera->GetViewMatrix();

		vec3f const W = - Normalize(LightCamera->GetLookDirecton());
		vec3f const U = Normalize(Cross(LightCamera->GetUpVector(), W));
		vec3f const V = Cross(W, U);
		vec3f const P = LightCamera->GetPosition();

		vec3f Box[8];

		float const BoxSize = LightViewSize;
		Box[0] = P - U * BoxSize - V * BoxSize - W * LightNear;
		Box[1] = P + U * BoxSize - V * BoxSize - W * LightNear;
		Box[2] = P - U * BoxSize + V * BoxSize - W * LightNear;
		Box[3] = P + U * BoxSize + V * BoxSize - W * LightNear;

		Box[4] = P - U * BoxSize - V * BoxSize - W * LightFar;
		Box[5] = P + U * BoxSize - V * BoxSize - W * LightFar;
		Box[6] = P - U * BoxSize + V * BoxSize - W * LightFar;
		Box[7] = P + U * BoxSize + V * BoxSize - W * LightFar;

		Lines->ResetLines();
		Lines->AddLine(vec3f(0, 0, 0), P, Color::Basic::Cyan);
		Lines->AddLine(P, P + U, Color::Basic::Red);
		Lines->AddLine(P, P + V, Color::Basic::Green);
		Lines->AddLine(P, P + W, Color::Basic::Blue);

		Lines->AddLine(Box[0], Box[1], Color::Basic::White);
		Lines->AddLine(Box[0], Box[2], Color::Basic::White);
		Lines->AddLine(Box[1], Box[3], Color::Basic::White);
		Lines->AddLine(Box[2], Box[3], Color::Basic::White);

		Lines->AddLine(Box[4], Box[5], Color::Basic::White);
		Lines->AddLine(Box[4], Box[6], Color::Basic::White);
		Lines->AddLine(Box[5], Box[7], Color::Basic::White);
		Lines->AddLine(Box[6], Box[7], Color::Basic::White);

		Lines->AddLine(Box[0], Box[4], Color::Basic::White);
		Lines->AddLine(Box[1], Box[5], Color::Basic::White);
		Lines->AddLine(Box[2], Box[6], Color::Basic::White);
		Lines->AddLine(Box[3], Box[7], Color::Basic::White);
		//Lines->AddLine(vec3f(0, 0, 0), vec3f(0, 10, 0), Color::Basic::Blue);

		ShadowBuffer->ClearColorAndDepth();
		BackBuffer->ClearColorAndDepth();
		SceneManager->DrawAll();


		GUIManager->Draw();

		Window->SwapBuffers();
	}

	return 0;
}
Exemple #9
0
bool CEngine::Update(float ElapsedTime)
{
	if (!m_PhysXManager->Simulating())
	{
		UpdateLevels();
	}

	ElapsedTime *= m_TimeScale;

	m_ElapsedTime = ElapsedTime;

	CAnimatorControllerManager* l_AnimatorControllerManager = CEngine::GetSingleton().GetAnimatorControllerManager();

	CScriptManager* l_ScriptManager = CEngine::GetSingleton().GetScriptManager();

	CCameraControllerManager* l_CameraController = CEngine::GetSingleton().GetCameraControllerManager();

	std::stringstream l_Ss;
	l_Ss << "Update(" << ElapsedTime << ")";
	std::string l_Code = l_Ss.str();
	m_LuabindManager->RunCode(l_Code);
	
	/*m_RenderManager->GetContextManager()->SetTimeParameters(ElapsedTime);

	l_CameraController->Update(ElapsedTime);

	m_PhysXManager->Update(ElapsedTime);

	m_LayerManager->Update(ElapsedTime);

	l_AnimatorControllerManager->Update(ElapsedTime);

	l_ScriptManager->Update(ElapsedTime);*/

	if (!m_Paused)
	{
		m_RenderManager->GetContextManager()->SetTimeParameters(ElapsedTime);

		l_AnimatorControllerManager->Update(ElapsedTime);

		l_ScriptManager->Update(ElapsedTime);

		//l_CameraController->Update(ElapsedTime);

		m_PhysXManager->Update(ElapsedTime);

		m_LayerManager->Update(ElapsedTime);

		l_CameraController->Update(ElapsedTime);
	}

	CCameraController* l = CEngine::GetSingleton().GetCameraControllerManager()->GetCurrentCameraController();
	CCamera l_Camera = CEngine::GetSingleton().GetRenderManager()->GetCurrentCamera();
	Vect3f x = l->GetUp();
	m_SoundManager->Update(&l_Camera, l->GetForward().Normalize(), ElapsedTime);

	m_LuaGameObjectHandleManager->Update();

	m_GraphicsStats->Update(ElapsedTime);

	m_Profiler->Update();

	return true;
}
Exemple #10
0
int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;
	SingletonPointer<CGUIManager> GUIManager;

	GraphicsAPI->Init(new Graphics::COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	//CWindow * Window = WindowManager->CreateWindow(vec2i(1600, 900), "DemoApplication", EWindowType::Windowed);
	CWindow * Window = WindowManager->CreateWindowOnMonitor(2, "SSAO");

	GUIManager->Init(Window);
	Window->AddListener(GUIManager);

	AssetManager->AddAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> BackBuffer = Context->GetBackBuffer();
	BackBuffer->SetClearColor(color3f(0.3f));

	SharedPointer<IFrameBuffer> SceneFrameBuffer = Context->CreateFrameBuffer();

	SharedPointer<ITexture2D> SceneColor = GraphicsAPI->CreateTexture2D(Window->GetSize(), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGB, ITexture::EInternalFormatType::Fix8);
	SceneColor->SetMinFilter(ITexture::EFilter::Nearest);
	SceneColor->SetMagFilter(ITexture::EFilter::Nearest);
	SceneColor->SetWrapMode(ITexture::EWrapMode::Clamp);
	SharedPointer<ITexture2D> SceneNormal = GraphicsAPI->CreateTexture2D(Window->GetSize(), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGB, ITexture::EInternalFormatType::Fix8);
	SceneNormal->SetMinFilter(ITexture::EFilter::Nearest);
	SceneNormal->SetMagFilter(ITexture::EFilter::Nearest);
	SceneNormal->SetWrapMode(ITexture::EWrapMode::Clamp);
	SharedPointer<ITexture2D> SceneDepth = GraphicsAPI->CreateTexture2D(Window->GetSize(), ITexture::EMipMaps::False, ITexture::EFormatComponents::R, ITexture::EInternalFormatType::Depth);
	SceneFrameBuffer->AttachColorTexture(SceneColor, 0);
	SceneFrameBuffer->AttachColorTexture(SceneNormal, 1);
	SceneFrameBuffer->AttachDepthTexture(SceneDepth);
	if (! SceneFrameBuffer->CheckCorrectness())
	{
		Log::Error("Frame buffer not valid!");
	}

	SharedPointer<IFrameBuffer> PingFrameBuffer = Context->CreateFrameBuffer();

	SharedPointer<ITexture2D> PingColor = GraphicsAPI->CreateTexture2D(Window->GetSize(), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGB, ITexture::EInternalFormatType::Fix8);
	PingColor->SetMinFilter(ITexture::EFilter::Nearest);
	PingColor->SetMagFilter(ITexture::EFilter::Nearest);
	PingColor->SetWrapMode(ITexture::EWrapMode::Clamp);
	PingFrameBuffer->AttachColorTexture(PingColor, 0);
	if (! PingFrameBuffer->CheckCorrectness())
	{
		Log::Error("Frame buffer not valid!");
	}

	SharedPointer<IFrameBuffer> PongFrameBuffer = Context->CreateFrameBuffer();

	SharedPointer<ITexture2D> PongColor = GraphicsAPI->CreateTexture2D(Window->GetSize(), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGB, ITexture::EInternalFormatType::Fix8);
	PongColor->SetMinFilter(ITexture::EFilter::Nearest);
	PongColor->SetMagFilter(ITexture::EFilter::Nearest);
	PongColor->SetWrapMode(ITexture::EWrapMode::Clamp);
	PongFrameBuffer->AttachColorTexture(PongColor, 0);
	if (! PongFrameBuffer->CheckCorrectness())
	{
		Log::Error("Frame buffer not valid!");
	}

	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));

	SharedPointer<IShader> GeometryShader = AssetManager->LoadShader("Geometry");
	SharedPointer<IShader> SSAOShader = AssetManager->LoadShader("SSAO");
	SharedPointer<IShader> BlurHShader = AssetManager->LoadShader("BlurH");
	SharedPointer<IShader> BlurVShader = AssetManager->LoadShader("BlurV");


	std::uniform_real_distribution<float> randomFloats(0.0, 1.0); // generates random floats between 0.0 and 1.0
	std::default_random_engine generator;

	// Sample kernel
	int const numSamples = 64;
	std::vector<vec3f> ssaoKernel;
	for (uint i = 0; i < numSamples; ++i)
	{
		float const VerticalBias = 0.1f;

		bool random = true;

		int const sampleRegionWidth = (int) sqrt((float) numSamples);

		float const a = random ? randomFloats(generator) : (float) (i / sampleRegionWidth) / (float) (sampleRegionWidth - 1);
		float const b = random ? randomFloats(generator) : (float) (i % sampleRegionWidth) / (float) (sampleRegionWidth - 1);
		float const c = random ? randomFloats(generator) : (float) (i % 3) / 2.f;

		vec3f sample = vec3f(a * 2 - 1, b * 2 - 1, c * (1.f - VerticalBias) + VerticalBias);
		sample.Normalize();
		sample *= randomFloats(generator);
		float scale = float(i) / numSamples;

		// Scale samples s.t. they're more aligned to center of kernel
		scale = lerp(0.1f, 1.0f, scale * scale);
		sample *= scale;
		ssaoKernel.push_back(sample);
	}

	// Noise texture
	std::vector<float> NoiseData;
	uint const NoiseTexSize = 4;
	for (uint i = 0; i < NoiseTexSize * NoiseTexSize; i++)
	{
		NoiseData.push_back(randomFloats(generator) * 2 - 1);
		NoiseData.push_back(randomFloats(generator) * 2 - 1);
		NoiseData.push_back(0.0);
	}
	SharedPointer<ITexture2D> SSAONoise = GraphicsAPI->CreateTexture2D(vec2i(NoiseTexSize), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGB, ITexture::EInternalFormatType::Float16);
	SSAONoise->Upload(NoiseData.data(), vec2i(NoiseTexSize), ITexture::EFormatComponents::RGB, EScalarType::Float);
	SSAONoise->SetMinFilter(ITexture::EFilter::Nearest);
	SSAONoise->SetMagFilter(ITexture::EFilter::Nearest);


	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * RenderPass = new CRenderPass(Context);
	RenderPass->SetRenderTarget(SceneFrameBuffer);
	SceneManager->AddRenderPass(RenderPass);

	CRenderPass * SSAOPass = new CRenderPass(Context);
	SSAOPass->SetRenderTarget(PingFrameBuffer);
	SceneManager->AddRenderPass(SSAOPass);

	int const BlurPasses = 2;

	CRenderPass * BlurHPasses[BlurPasses] =  { nullptr };
	CRenderPass * BlurVPasses[BlurPasses] =  { nullptr };

	for (int i = 0; i < BlurPasses; ++ i)
	{
		BlurHPasses[i] = new CRenderPass(Context);
		BlurHPasses[i]->SetRenderTarget(PongFrameBuffer);
		SceneManager->AddRenderPass(BlurHPasses[i]);

		BlurVPasses[i] = new CRenderPass(Context);
		BlurVPasses[i]->SetRenderTarget(i + 1 == BlurPasses ? BackBuffer : PingFrameBuffer);
		SceneManager->AddRenderPass(BlurVPasses[i]);
	}
	

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(-1.7f, 2.8f, 3.4f));
	Camera->SetFocalLength(0.4f);
	Camera->SetNearPlane(0.1f);
	Camera->SetFarPlane(50.f);
	RenderPass->SetActiveCamera(Camera);
	SSAOPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(-0.08f);
	Controller->SetPhi(-0.26f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);


	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * Sphere1 = new CSimpleMeshSceneObject();
	Sphere1->SetMesh(SphereMesh);
	Sphere1->SetShader(GeometryShader);
	Sphere1->SetPosition(vec3f(0, 0, 0));
	Sphere1->SetScale(2.f);
	Sphere1->GetMaterial().Diffuse *= color3f(1.0, 0.8f, 0.8f);
	RenderPass->AddSceneObject(Sphere1);

	CSimpleMeshSceneObject * Sphere2 = new CSimpleMeshSceneObject();
	Sphere2->SetMesh(SphereMesh);
	Sphere2->SetShader(GeometryShader);
	Sphere2->SetPosition(vec3f(4, 0, 0));
	Sphere2->SetScale(3.f);
	Sphere2->GetMaterial().Diffuse *= color3f(0.8f, 1, 0.8f);
	RenderPass->AddSceneObject(Sphere2);

	CSimpleMeshSceneObject * Sphere3 = new CSimpleMeshSceneObject();
	Sphere3->SetMesh(SphereMesh);
	Sphere3->SetShader(GeometryShader);
	Sphere3->SetPosition(vec3f(12, 0, 0));
	Sphere3->SetScale(4.f);
	Sphere3->GetMaterial().Diffuse *= color3f(0.8f, 0.9f, 1);
	RenderPass->AddSceneObject(Sphere3);

	CSimpleMeshSceneObject * Sphere4 = new CSimpleMeshSceneObject();
	Sphere4->SetMesh(SphereMesh);
	Sphere4->SetShader(GeometryShader);
	Sphere4->SetPosition(vec3f(3, 0, 6));
	Sphere4->GetMaterial().Diffuse *= color3f(0.9f, 1, 1);
	RenderPass->AddSceneObject(Sphere4);

	CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
	PlaneObject->SetMesh(PlaneMesh);
	PlaneObject->SetShader(GeometryShader);
	RenderPass->AddSceneObject(PlaneObject);

	CSimpleMesh * DragonMesh = AssetManager->LoadMeshMerged("dragon10k.obj");
	CSimpleMeshSceneObject * DragonObject = new CSimpleMeshSceneObject();
	DragonObject->SetMesh(DragonMesh);
	DragonObject->SetShader(GeometryShader);
	DragonObject->SetPosition(vec3f(6.f, 1.1f, 4.f));
	DragonObject->SetScale(4.f);
	RenderPass->AddSceneObject(DragonObject);

	CSimpleMesh * StairMesh = AssetManager->LoadMeshMerged("SM_StairCase_02.obj");
	CSimpleMeshSceneObject * StairObject = new CSimpleMeshSceneObject();
	StairObject->SetMesh(StairMesh);
	StairObject->SetShader(GeometryShader);
	StairObject->SetPosition(vec3f(12.f, 0.f, 5.f));
	StairObject->SetScale(1.f);
	StairObject->SetRotation(vec3f(0.f, DegToRad(90.f), 0.f));
	RenderPass->AddSceneObject(StairObject);

	float SSAORadius = 1.0f;

	CSimpleMeshSceneObject * PostProcessObject = new CSimpleMeshSceneObject();
	PostProcessObject->SetMesh(CGeometryCreator::CreateScreenTriangle());
	PostProcessObject->SetShader(SSAOShader);
	PostProcessObject->SetTexture("tSceneNormals", SceneNormal);
	PostProcessObject->SetTexture("tSceneDepth", SceneDepth);
	PostProcessObject->SetTexture("texNoise", SSAONoise);
	PostProcessObject->SetUniform("samples[0]", CUniform<vector<vec3f>>(ssaoKernel));
	PostProcessObject->SetUniform("radius", std::make_shared<CUniformReference<float>>(&SSAORadius));
	SSAOPass->AddSceneObject(PostProcessObject);

	CUniform<bool> uDoBlur = true;
	CUniform<bool> uUnconstrained = false;
	CUniform<float> uNormalThreshold = 0.5f;

	for (int i = 0; i < BlurPasses; ++ i)
	{
		CSimpleMeshSceneObject * BlurHObject = new CSimpleMeshSceneObject();
		BlurHObject->SetMesh(CGeometryCreator::CreateScreenTriangle());
		BlurHObject->SetShader(BlurHShader);
		BlurHObject->SetTexture("uTexture", PingColor);
		BlurHObject->SetTexture("tSceneNormals", SceneNormal);
		BlurHObject->SetUniform("uDoBlur", uDoBlur);
		BlurHObject->SetUniform("uUnconstrained", uUnconstrained);
		BlurHObject->SetUniform("uNormalThreshold", uNormalThreshold);
		BlurHPasses[i]->AddSceneObject(BlurHObject);

		CSimpleMeshSceneObject * BlurVObject = new CSimpleMeshSceneObject();
		BlurVObject->SetMesh(CGeometryCreator::CreateScreenTriangle());
		BlurVObject->SetShader(BlurVShader);
		BlurVObject->SetTexture("uTexture", PongColor);
		BlurVObject->SetTexture("tSceneNormals", SceneNormal);
		BlurVObject->SetUniform("uDoBlur", uDoBlur);
		BlurVObject->SetUniform("uUnconstrained", uUnconstrained);
		BlurVObject->SetUniform("uNormalThreshold", uNormalThreshold);
		BlurVPasses[i]->AddSceneObject(BlurVObject);
	}

	CPointLight * Light1 = new CPointLight();
	Light1->SetPosition(vec3f(0, 6, 0));
	RenderPass->AddLight(Light1);


	///////////////
	// Main Loop //
	///////////////

	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		GUIManager->NewFrame();
		ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiSetCond_Once);
		if (ImGui::Begin("Settings"))
		{
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
			ImGui::Text("Camera position: %.3f %.3f %.3f", Camera->GetPosition().X, Camera->GetPosition().Y, Camera->GetPosition().Z);
			ImGui::Text("Camera rotation: %.3f %.3f", Controller->GetTheta(), Controller->GetPhi());

			ImGui::Separator();

			ImGui::SliderFloat("SSAO Radius", &SSAORadius, 0.1f, 20.f);
			ImGui::Checkbox("Do Blur", &uDoBlur.Get());
			ImGui::SameLine();
			ImGui::Checkbox("Unconstrained", &uUnconstrained.Get());
			ImGui::SliderFloat("Normal Threshold", &uNormalThreshold.Get(), -1.f, 1.f);

			ImGui::End();
		}

		SceneFrameBuffer->ClearColorAndDepth();
		BackBuffer->ClearColorAndDepth();
		SceneManager->DrawAll();
		GUIManager->Draw();
		Window->SwapBuffers();
	}

	return 0;
}
int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;

	GraphicsAPI->Init(new Graphics::COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	CWindow * Window = WindowManager->CreateWindow(vec2i(1600, 900), "DemoApplication", EWindowType::Windowed);

	AssetManager->SetAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> RenderTarget = Context->GetBackBuffer();
	RenderTarget->SetClearColor(color3f(0.3f));


	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * SkySphereMesh = CGeometryCreator::CreateSkySphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));

	SharedPointer<IShaderProgram> DiffuseShader = AssetManager->LoadShader("Diffuse");
	SharedPointer<IShaderProgram> SimpleShader = AssetManager->LoadShader("Simple");
	SharedPointer<IShaderProgram> SpecularShader = AssetManager->LoadShader("Specular");
	SharedPointer<IShaderProgram> SkySphereShader = AssetManager->LoadShader("SkySphere");

	SharedPointer<ITexture2D> SkyMap = AssetManager->LoadTexture("SkyMap.jpg");
	SkyMap->SetMagFilter(ITexture::EFilter::Nearest);


	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * RenderPass = new CRenderPass(Context);
	RenderPass->SetRenderTarget(RenderTarget);
	SceneManager->AddRenderPass(RenderPass);

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(0, 3, -5));
	Camera->SetFocalLength(0.4f);
	RenderPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(15.f * Constants32::Pi / 48.f);
	Controller->SetPhi(-Constants32::Pi / 16.f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);


	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * LightSphere1 = new CSimpleMeshSceneObject();
	LightSphere1->SetMesh(SphereMesh);
	LightSphere1->SetShader(SimpleShader);
	LightSphere1->SetPosition(vec3f(0, 1, 0));
	RenderPass->AddSceneObject(LightSphere1);

	CSimpleMeshSceneObject * LightSphere2 = new CSimpleMeshSceneObject();
	LightSphere2->SetMesh(SphereMesh);
	LightSphere2->SetShader(SimpleShader);
	LightSphere2->SetPosition(vec3f(4, 2, 0));
	RenderPass->AddSceneObject(LightSphere2);

	CSimpleMeshSceneObject * LightSphere3 = new CSimpleMeshSceneObject();
	LightSphere3->SetMesh(SphereMesh);
	LightSphere3->SetShader(SimpleShader);
	LightSphere3->SetPosition(vec3f(12, 3, 0));
	RenderPass->AddSceneObject(LightSphere3);

	CSimpleMeshSceneObject * SpecularSphere = new CSimpleMeshSceneObject();
	SpecularSphere->SetMesh(SphereMesh);
	SpecularSphere->SetShader(SpecularShader);
	SpecularSphere->SetPosition(vec3f(3, 3, 6));
	SpecularSphere->GetMaterial().Ambient = vec3f(0.05f);
	RenderPass->AddSceneObject(SpecularSphere);

	CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
	PlaneObject->SetMesh(PlaneMesh);
	PlaneObject->SetShader(DiffuseShader);
	PlaneObject->GetMaterial().Ambient = vec3f(0.05f);
	RenderPass->AddSceneObject(PlaneObject);

	CSimpleMeshSceneObject * SkySphereObject = new CSimpleMeshSceneObject();
	SkySphereObject->SetMesh(SkySphereMesh);
	SkySphereObject->SetShader(SkySphereShader);
	SkySphereObject->SetTexture("uTexture", SkyMap);
	RenderPass->AddSceneObject(SkySphereObject);

	CPointLight * Light1 = new CPointLight();
	Light1->SetPosition(vec3f(0, 1, 0));
	Light1->SetColor(Colors::Red);
	RenderPass->AddLight(Light1);

	CPointLight * Light2 = new CPointLight();
	Light2->SetPosition(vec3f(4, 2, 0));
	Light2->SetColor(Colors::Green);
	RenderPass->AddLight(Light2);

	CPointLight * Light3 = new CPointLight();
	Light3->SetPosition(vec3f(12, 3, 0));
	Light3->SetColor(Colors::Blue);
	RenderPass->AddLight(Light3);


	///////////////
	// Main Loop //
	///////////////

	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		float const MinimumBrightness = 0.2f;
		float const MaximumBrightness = 1.f - MinimumBrightness;
		float const Brightness = (Sin<float>((float) TimeManager->GetRunTime()) / 2.f + 0.5f) * MaximumBrightness + MinimumBrightness;
		float const Radius = Brightness * 10.f;
		Light1->SetRadius(Radius);
		Light2->SetRadius(Radius);
		Light3->SetRadius(Radius);

		float const Bright = 1;
		float const Dim = 0.5f;
		LightSphere1->GetMaterial().Diffuse = color3f(Bright, Dim, Dim) * Brightness;
		LightSphere2->GetMaterial().Diffuse = color3f(Dim, Bright, Dim) * Brightness;
		LightSphere3->GetMaterial().Diffuse = color3f(Dim, Dim, Bright) * Brightness;
		LightSphere1->SetScale(Brightness);
		LightSphere2->SetScale(Brightness);
		LightSphere3->SetScale(Brightness);

		SkySphereObject->SetPosition(Camera->GetPosition());

		RenderTarget->ClearColorAndDepth();
		SceneManager->DrawAll();
		Window->SwapBuffers();
	}

	return 0;
}
Exemple #12
0
    void run(CSettings *pSettings) {
      CProgress *pProg=new CProgress(m_pDevice);

      ode::CIrrOdeEventProgress *p=new ode::CIrrOdeEventProgress(0,0);
      pProg->onEvent(p);
      delete p;

      //register the IrrOde scene node factory
      ode::CIrrOdeSceneNodeFactory cFactory(m_pSmgr);
      m_pSmgr->registerSceneNodeFactory(&cFactory);

      if (pSettings->isActive(4)) {
        CEventInstallRandomForestPlugin *p=new CEventInstallRandomForestPlugin();
        ode::CIrrOdeManager::getSharedInstance()->getOdeThread()->getOutputQueue()->postEvent(p);
        //delete p;
      }

#ifdef WITH_PARTICLES
      CAdvancedParticleSystemNodeFactory *cParticleFactory=new CAdvancedParticleSystemNodeFactory(m_pSmgr);
      m_pSmgr->registerSceneNodeFactory(cParticleFactory);
      cParticleFactory->drop();
#endif

      CRoadMeshLoader *pLoader=new CRoadMeshLoader(m_pDevice);
      m_pSmgr->addExternalMeshLoader(pLoader);

      //init the ODE
      ode::CIrrOdeManager::getSharedInstance()->initODE();

      //load the scene
      ode::CIrrOdeManager::getSharedInstance()->loadScene(DATADIR "/scenes/IrrOdeCar.xml",m_pSmgr);

      for (u32 i=0; i<m_pSmgr->getMeshCache()->getMeshCount(); i++) {
        scene::IAnimatedMesh *p=m_pSmgr->getMeshCache()->getMeshByIndex(i);
        for (u32 j=0; j<p->getMeshBufferCount(); j++) {
          p->getMeshBuffer(j)->setHardwareMappingHint(scene::EHM_STATIC);
        }
      }

      u32 iCars   = pSettings->getCountOf(0),
               iPlanes = pSettings->getCountOf(1),
               iTanks  = pSettings->getCountOf(2),
               iHelis  = pSettings->getCountOf(3);

      bool bRearCam=pSettings->isActive(6);

      core::dimension2du cScreenSize=m_pDevice->getVideoDriver()->getScreenSize();

      m_pCtrlReceiver = new CControlReceiver(m_pDevice, m_pSndEngine, cScreenSize.Width / (2.0f * cScreenSize.Height));

      if (!pSettings->isActive(0)) m_pCtrlReceiver->removeFromScene("roads"       ,m_pSmgr);
      if (!pSettings->isActive(2)) m_pCtrlReceiver->removeFromScene("targets"     ,m_pSmgr);
      if (!pSettings->isActive(3)) m_pCtrlReceiver->removeFromScene("plane_course",m_pSmgr);
      if (!pSettings->isActive(1)) {
        m_pCtrlReceiver->removeFromScene("ActiveSigns" ,m_pSmgr);
        m_pCtrlReceiver->removeFromScene("PassiveSigns",m_pSmgr);
      }
      if ( pSettings->isActive(4)) {
       const c8 sForests[][255]={ "RandomForest1", "RandomForest2", "Forest1", "Forest2" };

        for (u32 i=0; i<2; i++) {
          printf("merging \"%s\"...\n",sForests[i]);
          scene::ISceneNode *p=m_pSmgr->getSceneNodeFromName(sForests[i]);
          CRandomForest *pForest=(CRandomForest *)p;
          if (pForest!=NULL) {
            CMeshCombiner *pCombine=new CMeshCombiner(0.8f);
            core::array<scene::IMeshSceneNode *> aMeshSceneNodes;
            core::array<scene::ISceneNode *> aTrees=pForest->getGeneratedTrees();

            for (u32 j=0; j<aTrees.size(); j++) {
              scene::IMeshSceneNode *p=(scene::IMeshSceneNode *)aTrees[j];
              aMeshSceneNodes.push_back(p);
            }

            printf("%i trees\n",aMeshSceneNodes.size());

            if (aMeshSceneNodes.size()>0) {
              c8 s[0xFF];
              sprintf(s,"MyCombinedTrees_%i",i);
              scene::IMesh *pCombined=pCombine->combineMeshes(m_pSmgr,m_pDriver,aMeshSceneNodes,s);
              if (pCombined!=NULL) {
                scene::ISceneNode *pRoot=m_pSmgr->getSceneNodeFromName(sForests[i+2]);
                scene::IMeshSceneNode *pNode=m_pSmgr->addMeshSceneNode(pCombined,pRoot==NULL?m_pSmgr->getRootSceneNode():pRoot);
                for (u32 i=0; i<pNode->getMaterialCount(); i++) {
                  pNode->getMaterial(i).setFlag(video::EMF_LIGHTING,false);
                  pNode->getMaterial(i).MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
                }
              }
            }
          }
        }
      }
      if (!pSettings->isActive(5)) {
        printf("removing terrain trimesh...\n");
        m_pCtrlReceiver->removeFromScene("terrain_trimesh",m_pSmgr);
      }
      else {
        printf("removing terrain heightfield...\n");
        m_pCtrlReceiver->removeFromScene("terrain_heightfield",m_pSmgr);
      }

      bool bUseShader=pSettings->getSelectedDriver()==video::EDT_OPENGL;

      if (bUseShader) {
        if (!m_pDriver->queryFeature(video::EVDF_PIXEL_SHADER_1_1)) {
          printf("Pixel shader disabled!\n");
          bUseShader=false;
        }

        if (!m_pDriver->queryFeature(video::EVDF_VERTEX_SHADER_1_1)) {
          printf("Vertex shader disabled!\n");
          bUseShader=false;
        }
      }

      //I can only add shaders for OpenGL
      if (bUseShader) {
        video::IGPUProgrammingServices *pGpu=m_pDriver->getGPUProgrammingServices();
        if (pGpu) {
          printf("\n**** compiling GLSL shader ... \n\n");
          CShaderCallBack *pCallback=new CShaderCallBack(m_pDevice);
          s32 iNewMaterial=pGpu->addHighLevelShaderMaterialFromFiles(
              DATADIR "/shaders/opengl.vert","vertexMain", video::EVST_VS_1_1,
              DATADIR "/shaders/opengl.frag", "pixelMain", video::EPST_PS_1_1,
              pCallback,video::EMT_SOLID);

          replaceMaterials(m_pSmgr->getRootSceneNode(),iNewMaterial);
          pCallback->drop();
          printf("Ready.\n\n");
        }
      }

      delete pSettings;

      //modify the textures of the car segment and the tank segment to
      scene::IAnimatedMeshSceneNode *pNode=(scene::IAnimatedMeshSceneNode *)m_pSmgr->getSceneNodeFromName("car_segment");
      if (pNode) pNode->getMaterial(0).getTextureMatrix(0).setTextureScale(50.0f,50.0f);
      pNode=(scene::IAnimatedMeshSceneNode *)m_pSmgr->getSceneNodeFromName("tank_segment");
      if (pNode) pNode->getMaterial(0).getTextureMatrix(0).setTextureScale(50.0f,50.0f);

      int lastFPS=-1;

      //create the necessary state objects
      core::array<CIrrOdeCarState *> aStates;

      m_pCtrlReceiver->createMenu(iCars, iPlanes, iHelis, iTanks, bRearCam);

      //phyiscs initialization
      ode::CIrrOdeManager::getSharedInstance()->initPhysics();

      delete pProg;

      m_pDriver->setFog(g_cFogColor,video::EFT_FOG_LINEAR,g_fMinFog,g_fMaxFog,0.00001f,true,false);
      enableFog(m_pSmgr->getRootSceneNode());

      u32 iFrames=0,iTotalFps=0;
      m_pCtrlReceiver->start();

      CCameraController *pCamCtrl = m_pCtrlReceiver->getCameraController();

      //let's run the loop
      while(m_pDevice->run()) {
        //step the simulation
        ode::CIrrOdeManager::getSharedInstance()->step();

        m_pCtrlReceiver->update();

        //now for the normal Irrlicht stuff ... begin, draw and end scene and update window caption
        m_pDriver->beginScene(true,true,video::SColor(0xFF,0xA0,0xA0,0xC0));
        pCamCtrl->render();
        m_pDriver->setMaterial(m_pDriver->getMaterial2D());   //Fix the flipped texture problem
        m_pGui->drawAll();
        m_pCtrlReceiver->drawSpecifics();

        m_pDriver->endScene();
        int fps = m_pDriver->getFPS();

        if (lastFPS != fps) {
          iFrames++;
          iTotalFps+=fps;

          core::stringw str = L"Irrlicht Engine - IrrODE Car Demo [";
          str += m_pDriver->getName();
          str += "] FPS:";
          str += fps;
          str += " (avg: ";
          str += (iTotalFps/iFrames);
          str += ")";

          m_pDevice->setWindowCaption(str.c_str());
          lastFPS = fps;

          pCamCtrl->setFps(str.c_str());
        }
      }

      ode::CIrrOdeWorldObserver::getSharedInstance()->destall();

      CConfigFileManager::getSharedInstance()->writeConfig(m_pDevice,DATADIR "/irrOdeCarControls.xml");

#ifndef NO_IRRKLANG
      //drop the world so it is destroyed
      m_pDevice->drop();

      if (m_pSndEngine) m_pSndEngine->drop();
#endif

      //and now some more cleanup...
      for (u32 i=0; i<aStates.size(); i++) {
        delete aStates[i];
      }
      aStates.clear();
    }
int main()
{
	////////////////////
	// ionEngine Init //
	////////////////////

	Log::AddDefaultOutputs();

	SingletonPointer<CGraphicsAPI> GraphicsAPI;
	SingletonPointer<CWindowManager> WindowManager;
	SingletonPointer<CTimeManager> TimeManager;
	SingletonPointer<CSceneManager> SceneManager;
	SingletonPointer<CAssetManager> AssetManager;
	SingletonPointer<CGUIManager> GUIManager;

	GraphicsAPI->Init(new COpenGLImplementation());
	WindowManager->Init(GraphicsAPI);
	TimeManager->Init(WindowManager);
	SceneManager->Init(GraphicsAPI);
	AssetManager->Init(GraphicsAPI);

	CWindow * Window = WindowManager->CreateWindow(vec2i(1600, 900), "Shadow Maps", EWindowType::Windowed);

	GUIManager->Init(Window);

	AssetManager->AddAssetPath("Assets/");
	AssetManager->SetShaderPath("Shaders/");
	AssetManager->SetTexturePath("Images/");

	SharedPointer<IGraphicsContext> Context = GraphicsAPI->GetWindowContext(Window);
	SharedPointer<IRenderTarget> BackBuffer = Context->GetBackBuffer();
	BackBuffer->SetClearColor(color3f(0.3f));

	SharedPointer<IFrameBuffer> ShadowBuffer = Context->CreateFrameBuffer();

	SharedPointer<ITexture2D> ShadowTexture = GraphicsAPI->CreateTexture2D(vec2u(4096), ITexture::EMipMaps::False, ITexture::EFormatComponents::RGBA, ITexture::EInternalFormatType::Fix8);
	SharedPointer<ITexture2D> ShadowDepth = GraphicsAPI->CreateTexture2D(vec2u(4096), ITexture::EMipMaps::False, ITexture::EFormatComponents::R, ITexture::EInternalFormatType::Depth);
	ShadowBuffer->AttachColorTexture(ShadowTexture, 0);
	ShadowBuffer->AttachDepthTexture(ShadowDepth);
	if (! ShadowBuffer->CheckCorrectness())
	{
		Log::Error("Frame buffer not valid!");
	}


	/////////////////
	// Load Assets //
	/////////////////

	CSimpleMesh * SphereMesh = CGeometryCreator::CreateSphere();
	CSimpleMesh * PlaneMesh = CGeometryCreator::CreatePlane(vec2f(100.f));
	CSimpleMesh * CubeMesh = CGeometryCreator::CreateCube();

	SharedPointer<IShaderProgram> DiffuseShader = AssetManager->LoadShader("Diffuse");
	SharedPointer<IShaderProgram> QuadCopyShader = AssetManager->LoadShader("QuadCopy");


	////////////////////
	// ionScene Setup //
	////////////////////

	CRenderPass * ShadowPass = new CRenderPass(Context);
	ShadowPass->SetRenderTarget(ShadowBuffer);
	SceneManager->AddRenderPass(ShadowPass);

	CRenderPass * ColorPass = new CRenderPass(Context);
	ColorPass->SetRenderTarget(BackBuffer);
	SceneManager->AddRenderPass(ColorPass);

	CRenderPass * PostProcess = new CRenderPass(Context);
	PostProcess->SetRenderTarget(BackBuffer);
	SceneManager->AddRenderPass(PostProcess);

	CPerspectiveCamera * Camera = new CPerspectiveCamera(Window->GetAspectRatio());
	Camera->SetPosition(vec3f(0, 3, -5));
	Camera->SetFocalLength(0.4f);
	ColorPass->SetActiveCamera(Camera);

	CCameraController * Controller = new CCameraController(Camera);
	Controller->SetTheta(15.f * Constants32::Pi / 48.f);
	Controller->SetPhi(-Constants32::Pi / 16.f);
	Window->AddListener(Controller);
	TimeManager->MakeUpdateTick(0.02)->AddListener(Controller);

	vec3f LightDirection = vec3f(2, -12, 2);
	float LightViewSize = 20.f;
	float LightNear = 50.f;
	float LightFar = 200.f;

	COrthographicCamera * LightCamera = new COrthographicCamera(-LightViewSize, LightViewSize, -LightViewSize, LightViewSize);
	LightCamera->SetPosition(-LightDirection * 10.f);
	LightCamera->SetLookDirection(LightDirection);
	LightCamera->SetNearPlane(LightNear);
	LightCamera->SetFarPlane(LightFar);
	ShadowPass->SetActiveCamera(LightCamera);


	/////////////////
	// Add Objects //
	/////////////////

	CSimpleMeshSceneObject * Sphere1 = new CSimpleMeshSceneObject();
	Sphere1->SetMesh(SphereMesh);
	Sphere1->SetShader(DiffuseShader);
	Sphere1->SetPosition(vec3f(0, 1, 0));
	Sphere1->SetScale(2.f);
	ColorPass->AddSceneObject(Sphere1);
	ShadowPass->AddSceneObject(Sphere1);

	CSimpleMeshSceneObject * Sphere2 = new CSimpleMeshSceneObject();
	Sphere2->SetMesh(SphereMesh);
	Sphere2->SetShader(DiffuseShader);
	Sphere2->SetPosition(vec3f(4, 4, 0));
	Sphere2->SetScale(3.f);
	ColorPass->AddSceneObject(Sphere2);
	ShadowPass->AddSceneObject(Sphere2);

	CSimpleMeshSceneObject * Sphere3 = new CSimpleMeshSceneObject();
	Sphere3->SetMesh(SphereMesh);
	Sphere3->SetShader(DiffuseShader);
	Sphere3->SetPosition(vec3f(12, 2, 0));
	Sphere3->SetScale(4.f);
	ColorPass->AddSceneObject(Sphere3);
	ShadowPass->AddSceneObject(Sphere3);

	CSimpleMeshSceneObject * Sphere4 = new CSimpleMeshSceneObject();
	Sphere4->SetMesh(SphereMesh);
	Sphere4->SetShader(DiffuseShader);
	Sphere4->SetPosition(vec3f(3, 4, 6));
	ColorPass->AddSceneObject(Sphere4);
	ShadowPass->AddSceneObject(Sphere4);

	CSimpleMeshSceneObject * Cube1 = new CSimpleMeshSceneObject();
	Cube1->SetMesh(CubeMesh);
	Cube1->SetShader(DiffuseShader);
	Cube1->SetPosition(vec3f(-4, 4, 0));
	Cube1->SetScale(3.f);
	ColorPass->AddSceneObject(Cube1);
	ShadowPass->AddSceneObject(Cube1);

	CSimpleMeshSceneObject * Cube2 = new CSimpleMeshSceneObject();
	Cube2->SetMesh(CubeMesh);
	Cube2->SetShader(DiffuseShader);
	Cube2->SetPosition(vec3f(-12, 2, 0));
	Cube2->SetScale(4.f);
	ColorPass->AddSceneObject(Cube2);
	ShadowPass->AddSceneObject(Cube2);

	CSimpleMeshSceneObject * Plane = new CSimpleMeshSceneObject();
	Plane->SetMesh(PlaneMesh);
	Plane->SetShader(DiffuseShader);
	Plane->GetMaterial().Ambient *= Colors::Green;
	Plane->GetMaterial().Diffuse *= Colors::Green;
	ColorPass->AddSceneObject(Plane);
	ShadowPass->AddSceneObject(Plane);

	//vector<CSimpleMesh *> Meshes = CGeometryCreator::LoadOBJFile("terrain.obj");
	//for (auto Mesh : Meshes)
	//{
	//	CSimpleMeshSceneObject * PlaneObject = new CSimpleMeshSceneObject();
	//	PlaneObject->SetMesh(Mesh);
	//	PlaneObject->SetShader(DiffuseShader);
	//	ColorPass->AddSceneObject(PlaneObject);
	//	ShadowPass->AddSceneObject(PlaneObject);
	//}

	CSimpleMeshSceneObject * PostProcessObject = new CSimpleMeshSceneObject();
	PostProcessObject->SetMesh(CGeometryCreator::CreateScreenTriangle());
	PostProcessObject->SetShader(QuadCopyShader);
	PostProcessObject->SetTexture("uTexture", ShadowDepth);
	PostProcess->AddSceneObject(PostProcessObject);

	CDirectionalLight * Light1 = new CDirectionalLight();
	Light1->SetDirection(LightDirection);
	ColorPass->AddLight(Light1);
	ShadowPass->AddLight(Light1);

	CUniform<glm::mat4> uLightMatrix;
	ColorPass->SetUniform("uLightMatrix", uLightMatrix);
	ColorPass->SetTexture("uShadowMap", ShadowDepth);


	///////////////
	// Main Loop //
	///////////////

	TimeManager->Init(WindowManager);
	while (WindowManager->Run())
	{
		TimeManager->Update();

		PostProcessObject->SetVisible(Window->IsKeyDown(EKey::F1));

		GUIManager->NewFrame();
		ImGui::SetNextWindowPos(ImVec2(10, 10), ImGuiSetCond_Once);
		if (ImGui::Begin("Settings"))
		{
			ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
			ImGui::Text("Camera position: %.3f %.3f %.3f", Camera->GetPosition().X, Camera->GetPosition().Y, Camera->GetPosition().Z);
			ImGui::Text("Camera rotation: %.3f %.3f", Controller->GetTheta(), Controller->GetPhi());

			ImGui::Separator();

			ImGui::SliderFloat("Light Camera Size", &LightViewSize, 1.f, 200.f);
			ImGui::SliderFloat("Light Near Plane", &LightNear, 1.f, 300.f);
			ImGui::SliderFloat("Light Far Plane", &LightFar, 1.f, 600.f);
			ImGui::SliderFloat3("Light Direction", LightDirection.Values, -30.f, 30.f);
			ImGui::Text("Light Position: %.3f %.3f %.3f", LightCamera->GetPosition().X, LightCamera->GetPosition().Y, LightCamera->GetPosition().Z);

			ImGui::End();
		}

		LightCamera->SetLeft(-LightViewSize);
		LightCamera->SetRight(LightViewSize);
		LightCamera->SetBottom(-LightViewSize);
		LightCamera->SetTop(LightViewSize);
		LightCamera->SetPosition(-LightDirection * 10.f);
		LightCamera->SetLookDirection(LightDirection);
		LightCamera->SetNearPlane(LightNear);
		LightCamera->SetFarPlane(LightFar);
		uLightMatrix = LightCamera->GetProjectionMatrix() * LightCamera->GetViewMatrix();

		ShadowBuffer->ClearColorAndDepth();
		BackBuffer->ClearColorAndDepth();
		SceneManager->DrawAll();


		GUIManager->Draw();

		Window->SwapBuffers();
	}

	return 0;
}