#include "Common\StepTimer.h"
#include "Common\DeviceResources.h"
#include "Content\Sample3DSceneRenderer.h"

// Renders Direct3D content on the screen.
namespace ExampleCreation
{
	class ExampleCreationMain
	{
	public:
		ExampleCreationMain();
		void CreateRenderers(const std::shared_ptr<DX::DeviceResources>& deviceResources);
		void Update();
		bool Render();

		void OnWindowSizeChanged();
		void OnSuspending();
		void OnResuming();
		void OnDeviceRemoved();

	private:
		// TODO: Replace with your own content renderers.
		std::unique_ptr<Sample3DSceneRenderer> m_sceneRenderer;

		// Rendering loop timer.
		DX::StepTimer m_timer;
	};
}

Direct3D Content를 화면에 출력하는 코드들을 엮은 ExampleCreationMain class이다.

Function은 구현체를 보면서 이야기 할테니, Field들을 살펴보자.

 

StepTimer는 MS에서 제공하는 코드이다.

https://github.com/microsoft/DirectXTK/wiki/StepTimer

 

microsoft/DirectXTK

The DirectX Tool Kit (aka DirectXTK) is a collection of helper classes for writing DirectX 11.x code in C++ - microsoft/DirectXTK

github.com

대부분의 기능은 Tick과 관련되어 있으며, 여타 다른 함수들과 마찬가지로 상시 적용을 해야 하는 부분이다.

 

Sample3DSceneRenderer는 TODO에 적혀있는대로, 화면에 출력 될 내용에 관한 함수이다.

즉, ExampleCreationMain도 결국 주어진 함수를 출력만 하는 코드라는 것이다.

밑에 Function 별 기능에 대해 설명은 하겠지만, 보면 실질적으로 직접 무언가 하는 작업은 없다.

다른 Function 호출이 대부분이다.

 

그런 의미에서 빠르게 Function별 설명으로 넘어가자.

해당 Function이 어떤 기능을 하고, 내부에서 어떤 구현이 있는지를 주로 볼 것이다.

 

// Loads and initializes application assets when the application is loaded.
ExampleCreationMain::ExampleCreationMain()
{
	// TODO: Change the timer settings if you want something other than the default variable timestep mode.
	// e.g. for 60 FPS fixed timestep update logic, call:
	/*
	m_timer.SetFixedTimeStep(true);
	m_timer.SetTargetElapsedSeconds(1.0 / 60);
	*/
}

생성자 안에는 아무런 선언이 없다. 

다만, FPS 고정 수치를 변경하는 등의 기능을 생성자 안에서 어떻게 할 수 있는지 주석으로 설명이 되어 있다.

 

// Creates and initializes the renderers.
void ExampleCreationMain::CreateRenderers(const std::shared_ptr<DX::DeviceResources>& deviceResources)
{
	// TODO: Replace this with your app's content initialization.
	m_sceneRenderer = std::unique_ptr<Sample3DSceneRenderer>(new Sample3DSceneRenderer(deviceResources));

	OnWindowSizeChanged();
}

CreateRenderes는 Renderer를 생성하고 초기화 하는 구문이다.

App class에서 GetDeviceREsources에서 호출이 되는 함수로, Sample3DSceneRenderer 객체를 생성하고,

내용물에 따른 화면 크기 변화에 대비한 OnWindowSizeChanged를 호출한다.

 

// Updates the application state once per frame.
void ExampleCreationMain::Update()
{
	// Update scene objects.
	m_timer.Tick([&]()
	{
		// TODO: Replace this with your app's content update functions.
		m_sceneRenderer->Update(m_timer);
	});
}

Update는 매 프레임마다 바뀌는 위상에 대한 정보를 연산하는 기능을 한다.

App의 Run 함수에서 호출이 되며, m_timer의 Tick 함수에

Sample3DSceneREnderer의 Update 함수에 m_timer를 인자로 넘기는 것을 lambda로 호출한다.

 

// Renders the current frame according to the current application state.
// Returns true if the frame was rendered and is ready to be displayed.
bool ExampleCreationMain::Render()
{
	// Don't try to render anything before the first Update.
	if (m_timer.GetFrameCount() == 0)
	{
		return false;
	}

	// Render the scene objects.
	// TODO: Replace this with your app's content rendering functions.
	return m_sceneRenderer->Render();
}

역시나 App의 Run 함수에서 호출되는 Render는 매 프레임마다 바뀌는 정보로

해당 프레임에 적절한 위상을 변경하는 역할을 한다.

단, 첫 프레임일 때에는 이 작업을 하지 않는다.

 

// Updates application state when the window's size changes (e.g. device orientation change)
void ExampleCreationMain::OnWindowSizeChanged()
{
	// TODO: Replace this with the size-dependent initialization of your app's content.
	m_sceneRenderer->CreateWindowSizeDependentResources();
}

Window 크기가 조절될 때 호출되는 OnWindowSizeChanged는 우리가 구현했던

Sample3DSceneRenderer의 CreateWindowSizeDependentResources를 호출한다.

뒤에 설명을 하겠지만, 이는 화면 크기가 변할 때마다 바뀌어야 할 관련 수치들을 변경해주는 역할을 한다.

 

// Notifies the app that it is being suspended.
void ExampleCreationMain::OnSuspending()
{
	// TODO: Replace this with your app's suspending logic.

	// Process lifetime management may terminate suspended apps at any time, so it is
	// good practice to save any state that will allow the app to restart where it left off.

	m_sceneRenderer->SaveState();

	// If your application uses video memory allocations that are easy to re-create,
	// consider releasing that memory to make it available to other applications.
}

App이 종료 될 때 호출되는 OnSuspending이다.

현재까지 적용된 상태들이 온전히 적용될 수 있도록 저장을 한다.

 

// Notifes the app that it is no longer suspended.
void ExampleCreationMain::OnResuming()
{
	// TODO: Replace this with your app's resuming logic.
}

Suspend 상태가 해제 될 때 호출되는 OnResuming이다.

현재 아무런 구현이 되어있지 않다.

 

// Notifies renderers that device resources need to be released.
void ExampleCreationMain::OnDeviceRemoved()
{
	// TODO: Save any necessary application or renderer state and release the renderer
	// and its resources which are no longer valid.
	m_sceneRenderer->SaveState();
	m_sceneRenderer = nullptr;
}

마지막으로 device resources가 해제 될 때 Renderer에 이벤트를 넣는 OnDeviceRemoved이다.

이 경우에도 Suspend와 마찬가지로 SaveState를 통해 상태저장을 하고, 더 나아가 SceneRender를 해제하기까지 한다.

 

결국 ExampleCreationMain까지도 코드에서 제공하는 일종의 Frame 중 하나였다.

예시만 따라한다면, 무엇 하나 바꿀 필요가 없다. m_sceneRenderer를 제외하고는.

 

이렇게 일주일이 더 지났고, 예시를 적용하기 위해서 우리가 변경해야 할 코드는 Sample3DSceneRenderer로 좁혀졌다.

가능하면 더 시간을 끌고 싶지 않았지만, Sample3DSceneRenderer가 꽤 길고 복잡하다.

게다가 C++/CX를 사용하는 구문도 조금 있어서 지금 컨디션에 바로 하기 힘들 것 같다.

 

때문에 금요일로 조금 미루겠습니다.

+ Recent posts