DirectX 11 学习笔记-Part2-0

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Zealot_Alie/article/details/82713018

第二部分对应书本的Part 3。

这部分起主要是DirectX的几种常见的应用场景。因此实际上理论知识的部分将减少,更多关注算法和实现的部分。

因此笔记将结合实际的Demo代码来完成。

接下来的几篇文章中,每篇文章都将围绕一个或多个topic,根据书本和提供源码实习一个Demo,结合代码和书本来讲解相关的知识。

代码的地址依然是https://github.com/ZealotAlie/D11Demo0,所有的新Demo我都会放到同一个Solution中,选择不同的Project将可以运行不同的Demo。

为了避免每次新建Project都需要重新配置,我新建了一个项目配置表DemoPropertySheet,只需要在新建项目中使用配置好的项目配置表就可直接完成配置,极大的节省了时间。

项目配置表可以在View->OtherWindow->PropertyManager中打开

右键某个项目即可新建一个表,双击之后可以像一般项目一样编辑表的属性。当新建项目时,只需要右键新项目,选择Add Existing Property Sheet即可将配置表应用到新项目中,从而避免重复配置。

另外,由于接下来的Demo中会有许多新的shader,或者要使用到之前的shader,所以我在项目中添加了一个单例类用于管理所有的Effect/InputLayout/RenderState,具体实现看UnknownInstance.h。

class IUnknownInstance
{
public:
	virtual ~IUnknownInstance(){}
};

template< class T, bool AUTO_INSTANCE = false, class TInstance = T >
class UnknownInstance : public IUnknownInstance
{
public:
	UnknownInstance()
	{
		if( sm_pWarpInstance == nullptr )
		{
			sm_pWarpInstance = static_cast<T*>( this );
		}
	}
	~UnknownInstance()
	{
		if( sm_pWarpInstance == this )
		{
			sm_pWarpInstance = nullptr;
		}
	}

	static TInstance* Ptr()
	{
		return PtrWithInitialization< AUTO_INSTANCE >();
	}
private:

	template< bool DoInstance >
	static TInstance* PtrWithInitialization()
	{
		return sm_pWarpInstance? static_cast<TInstance*>( sm_pWarpInstance->GetResource() ) : nullptr;
	}

	template<> 
	static TInstance* PtrWithInitialization<true>()
	{
		if( !sm_pWarpInstance )
		{
			sm_pWarpInstance = new T( D3DApp::GetInstance()->GetDevice() );
			D3DApp::GetInstance()->AddUnknownInstance(sm_pWarpInstance);
		}
		return static_cast<TInstance*>( sm_pWarpInstance->GetResource() );
	}

	static T* sm_pWarpInstance;
};

基本思路是,在App中添加一个列表用于存放这些单例,在App关闭的时候释放它们的资源。

单例分为两类,一类是可以自动完成初始化的,这类资源直接在第一次调用Ptr()函数时就会自动初始化。

而如果你需要在初始化时使用一些额外参数(如effect需要路径信息),则需要手动用new构造一个实例并添加到D3DApp中

AddUnknownInstance( new BasicEffect( md3dDevice, L"FX/Basic.fx" ) );

所有的UnknownInstance都继承自IUnknownInstance。这个接口只定义了一个虚析构函数,因为我们需要在D3DApp中存放单例的指针,所以需要一个统一的基类,并且需要虚析构函数,否则资源将无法被正确释放(这里不能使用void*作为存放的指针,因为delete void* 是不会调用析构函数的)。

猜你喜欢

转载自blog.csdn.net/Zealot_Alie/article/details/82713018