《游戏引擎架构》学习笔记

《游戏引擎架构》学习笔记——第五章(一)

第五章 游戏支持系统

每个游戏都需要一些底层支持系统,以管理一些例行却关键的任务。

5.1 子系统的启动和终止

游戏引擎是复杂软件,由多个相互合作的子系统结合而成。当引擎启动时,必须一次配置及初始化每个子系统。各子系统间的相互依赖关系,隐含地定义了每个子系统所需的启动次序。(各子系统的终止通常会采用与启动时的反向次序)

1.C++的静态初始化次序(是不可用的)

C++中,在调用程序进入点(main()或Windows下的WinMain())之前,全局及静态对象已被构建,而这些构造函数的调用次序是无法预知的;在结束返回之后,全局静态对象的析构函数的调用次序也是无法预知的。

要实现游戏引擎中的子系统,常见的设计模式是为每个子系统定义单例类(通常称为管理器)。

若我们能够指明全局或静态实例的建构、析构次序,那么就可以把单例定义为全局变量,而不必使用动态内存分配。但由于没法直接控制建构及析构次序,此法不通。

1.1 按需构建

函数内声明的静态变量并不会与main()之前建构,而是在第一次调用该函数时才建构的。因此,若把全局单例改为静态变量,我们就可控制全局单例的建构次序。

class RenderManager
{
	public:
		//取得唯一实例
		static RenderManager& get()
		{
			//此函数中的静态变量将于函数被首次调用时构建
			static RenderManager sSingleton;
			return sSingleton;
		}
		
		RenderManager()
		{
			//对于需要依赖的管理器,先通过调用它们的get()启动它们
			VideoManager::get();
			TextureManager::get();
		}

	~RenderManager()
	{
		//终止管理器
	}
}

或:
(含动态分配单例的变种)

static RenderManager& get()
{
	static RenderManager* gpSingleton = NULL;
	if (gpSingleton == NULL)
	{
		gpSingleton = new RenderManager;
	}
	ASSERT(gpSingleton);
	return *gpSingleton;
} 

缺点:

1.此方法不能控制析构次序
2.RenderManager确切的建构时间难以预计(不知道第一次调用 RenderManager::get() 的时间)。3.get()函数可能会有很高的开销。

2.行之有效的简单方法

明确地为各单例管理器类定义启动和终止函数,这些函数取代了建构和析构函数。在建构和析构函数中不做任何事情。那么在main()中(或某个管理整个引擎的单例中),按所需的明确次序调用各启动和终止函数。
“蛮力方法”:

class RenderManager{
public:
    RenderManager(){}
    ~RenderManager(){}
    void startUp(){
        //自定义的启动函数
    }
    void shutDown(){
        //自定义的终止函数
    }
};

class PhysicsManager{/*同上面类似*/ };
class AnimationManager{/*同上面类似*/ };
class MemoryManager{/*同上面类似*/ };

RenderManager gRenderManager;
PhysicsManager gPhysicsManager;
AnimationManager gAnimationManager;
MemoryManager gMemoryManager;

int _tmain(int argc, _TCHAR* argv[])
{
    //启动各个子系统
    gMemoryManager.startUp();
    ...
    gRenderManager.startUp();
    gAnimationManager.startUp(); 
    gPhysicsManager.startUp();

    //运行游戏

    //终止各个子系统
    gPhysicsManager.shutDown();
    gAnimationManager.shutDown();
    gRenderManager.shutDown();
    ...
    gMemoryManager.shutDown();
    return 0;
}

其他方法

1.让各管理器把自己登记在一个全局的优先队列,之后再按恰当次序逐一启动所有管理器
2.通过每个管理器列举其依赖的管理器,定义一个管理器间的依赖图,然后按互相依赖关系计算最 优的启动次序
(该书作者推荐使用“蛮力方法”)

3.一些实际引擎的粒子

(略)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值