在Config中增加VSync开启选项
This commit is contained in:
		
							parent
							
								
									dda7e17347
								
							
						
					
					
						commit
						58af967968
					
				|  | @ -42,20 +42,7 @@ void e2d::Game::destroyInstance() | |||
| 
 | ||||
| void e2d::Game::start() | ||||
| { | ||||
| 	auto gc = GC::getInstance(); | ||||
| 	auto input = Input::getInstance(); | ||||
| 	auto window = Window::getInstance(); | ||||
| 	auto renderer = Renderer::getInstance(); | ||||
| 	auto timer = Timer::getInstance(); | ||||
| 	auto sceneManager = SceneManager::getInstance(); | ||||
| 	auto actionManager = ActionManager::getInstance(); | ||||
| 
 | ||||
| 	if (!input || !window || !renderer || !timer || !sceneManager || !actionManager) | ||||
| 	{ | ||||
| 		throw SystemException(L"³õʼ»¯Ê§°Ü"); | ||||
| 	} | ||||
| 
 | ||||
| 	HWND hWnd = window->getHWnd(); | ||||
| 	HWND hWnd = Window::getInstance()->getHWnd(); | ||||
| 	if (hWnd == nullptr) | ||||
| 	{ | ||||
| 		throw SystemException(L"无法创建窗口"); | ||||
|  | @ -64,7 +51,7 @@ void e2d::Game::start() | |||
| 	// 显示窗口
 | ||||
| 	::ShowWindow(hWnd, SW_SHOWNORMAL); | ||||
| 	::UpdateWindow(hWnd); | ||||
| 	window->poll(); | ||||
| 	Window::getInstance()->poll(); | ||||
| 
 | ||||
| 	// 开始游戏
 | ||||
| 	Duration interval; | ||||
|  | @ -76,31 +63,43 @@ void e2d::Game::start() | |||
| 	while (!_quit) | ||||
| 	{ | ||||
| 		_now = Time::now(); | ||||
| 		interval = _now - _last; | ||||
| 
 | ||||
| 		if (_frameInterval < interval) | ||||
| 		if (_config.isVSyncEnabled()) | ||||
| 		{ | ||||
| 			_last = _now; | ||||
| 
 | ||||
| 			input->update(); | ||||
| 			timer->update(); | ||||
| 			actionManager->update(); | ||||
| 			sceneManager->update(); | ||||
| 			renderer->render(); | ||||
| 			window->poll(); | ||||
| 			gc->flush(); | ||||
| 			__update(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			wait = (_frameInterval - interval).milliseconds() - 1; | ||||
| 			if (wait > 1) | ||||
| 			interval = _now - _last; | ||||
| 
 | ||||
| 			if (_frameInterval < interval) | ||||
| 			{ | ||||
| 				std::this_thread::sleep_for(milliseconds(wait)); | ||||
| 				_last = _now; | ||||
| 				__update(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				wait = (_frameInterval - interval).milliseconds() - 1; | ||||
| 				if (wait > 1) | ||||
| 				{ | ||||
| 					std::this_thread::sleep_for(milliseconds(wait)); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::__update() | ||||
| { | ||||
| 	Input::getInstance()->update(); | ||||
| 	Timer::getInstance()->update(); | ||||
| 	ActionManager::getInstance()->update(); | ||||
| 	SceneManager::getInstance()->update(); | ||||
| 	Renderer::getInstance()->render(); | ||||
| 	Window::getInstance()->poll(); | ||||
| 	GC::getInstance()->flush(); | ||||
| } | ||||
| 
 | ||||
| void e2d::Game::pause() | ||||
| { | ||||
| 	_paused = true; | ||||
|  | @ -124,18 +123,25 @@ bool e2d::Game::isPaused() | |||
| 
 | ||||
| void e2d::Game::setConfig(const Config& config) | ||||
| { | ||||
| 	_config = config; | ||||
| 	 | ||||
| 	if (_config.isSoundEnabled()) | ||||
| 	if (_config.isSoundEnabled() != config.isSoundEnabled()) | ||||
| 	{ | ||||
| 		Player::getInstance()->getXAudio2()->StartEngine(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		Player::getInstance()->getXAudio2()->StopEngine(); | ||||
| 		if (config.isSoundEnabled()) | ||||
| 			Player::getInstance()->getXAudio2()->StartEngine(); | ||||
| 		else | ||||
| 			Player::getInstance()->getXAudio2()->StopEngine(); | ||||
| 	} | ||||
| 
 | ||||
| 	_frameInterval = Duration(_config.getFrameInterval()); | ||||
| 	if (_config.getFrameInterval() != config.getFrameInterval()) | ||||
| 	{ | ||||
| 		_frameInterval = Duration(config.getFrameInterval()); | ||||
| 	} | ||||
| 
 | ||||
| 	if (_config.isVSyncEnabled() != config.isVSyncEnabled()) | ||||
| 	{ | ||||
| 		Renderer::getInstance()->discardDeviceResources(); | ||||
| 	} | ||||
| 
 | ||||
| 	_config = config; | ||||
| } | ||||
| 
 | ||||
| const e2d::Config& e2d::Game::getConfig() | ||||
|  |  | |||
|  | @ -45,8 +45,6 @@ e2d::Renderer::Renderer() | |||
| 	, _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) | ||||
| { | ||||
| 	CoInitialize(nullptr); | ||||
| 
 | ||||
| 	this->__createDeviceResources(); | ||||
| } | ||||
| 
 | ||||
| e2d::Renderer::~Renderer() | ||||
|  | @ -59,53 +57,7 @@ e2d::Renderer::~Renderer() | |||
| 	CoUninitialize(); | ||||
| } | ||||
| 
 | ||||
| bool e2d::Renderer::__createDeviceResources() | ||||
| { | ||||
| 	HRESULT hr = S_OK; | ||||
| 
 | ||||
| 	if (!_renderTarget) | ||||
| 	{ | ||||
| 		HWND hWnd = Window::getInstance()->getHWnd(); | ||||
| 
 | ||||
| 		// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建
 | ||||
| 		RECT rc; | ||||
| 		GetClientRect(hWnd, &rc); | ||||
| 
 | ||||
| 		D2D1_SIZE_U size = D2D1::SizeU( | ||||
| 			rc.right - rc.left, | ||||
| 			rc.bottom - rc.top | ||||
| 		); | ||||
| 
 | ||||
| 		// 创建一个 Direct2D 渲染目标
 | ||||
| 		hr = Renderer::getFactory()->CreateHwndRenderTarget( | ||||
| 			D2D1::RenderTargetProperties(), | ||||
| 			D2D1::HwndRenderTargetProperties(hWnd, size, D2D1_PRESENT_OPTIONS_IMMEDIATELY), | ||||
| 			&_renderTarget | ||||
| 		); | ||||
| 
 | ||||
| 		if (FAILED(hr)) | ||||
| 		{ | ||||
| 			throw SystemException(L"Create ID2D1HwndRenderTarget failed"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			// 创建画刷
 | ||||
| 			hr = _renderTarget->CreateSolidColorBrush( | ||||
| 				D2D1::ColorF(D2D1::ColorF::White), | ||||
| 				&_solidBrush | ||||
| 			); | ||||
| 		} | ||||
| 
 | ||||
| 		if (FAILED(hr)) | ||||
| 		{ | ||||
| 			throw SystemException(L"Create ID2D1SolidColorBrush failed"); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return SUCCEEDED(hr); | ||||
| } | ||||
| 
 | ||||
| void e2d::Renderer::__discardDeviceResources() | ||||
| void e2d::Renderer::discardDeviceResources() | ||||
| { | ||||
| 	SafeRelease(_renderTarget); | ||||
| 	SafeRelease(_solidBrush); | ||||
|  | @ -117,12 +69,12 @@ void e2d::Renderer::render() | |||
| 	HRESULT hr = S_OK; | ||||
| 
 | ||||
| 	// 创建设备相关资源
 | ||||
| 	Renderer::__createDeviceResources(); | ||||
| 	auto renderTarget = this->getRenderTarget(); | ||||
| 
 | ||||
| 	// 开始渲染
 | ||||
| 	_renderTarget->BeginDraw(); | ||||
| 	renderTarget->BeginDraw(); | ||||
| 	// 使用背景色清空屏幕
 | ||||
| 	_renderTarget->Clear(_clearColor); | ||||
| 	renderTarget->Clear(_clearColor); | ||||
| 
 | ||||
| 	// 渲染场景
 | ||||
| 	SceneManager::getInstance()->render(); | ||||
|  | @ -134,14 +86,14 @@ void e2d::Renderer::render() | |||
| 	} | ||||
| 
 | ||||
| 	// 终止渲染
 | ||||
| 	hr = _renderTarget->EndDraw(); | ||||
| 	hr = renderTarget->EndDraw(); | ||||
| 
 | ||||
| 	if (hr == D2DERR_RECREATE_TARGET) | ||||
| 	{ | ||||
| 		// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
 | ||||
| 		// 并在下一次调用时重建资源
 | ||||
| 		hr = S_OK; | ||||
| 		this->__discardDeviceResources(); | ||||
| 		this->discardDeviceResources(); | ||||
| 	} | ||||
| 
 | ||||
| 	if (FAILED(hr)) | ||||
|  | @ -225,11 +177,54 @@ void e2d::Renderer::setBackgroundColor(Color color) | |||
| 
 | ||||
| ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget() | ||||
| { | ||||
| 	if (!_renderTarget) | ||||
| 	{ | ||||
| 		HWND hWnd = Window::getInstance()->getHWnd(); | ||||
| 
 | ||||
| 		// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建
 | ||||
| 		RECT rc; | ||||
| 		GetClientRect(hWnd, &rc); | ||||
| 
 | ||||
| 		D2D1_SIZE_U size = D2D1::SizeU( | ||||
| 			rc.right - rc.left, | ||||
| 			rc.bottom - rc.top | ||||
| 		); | ||||
| 
 | ||||
| 		bool VSyncEnabled = Game::getInstance()->getConfig().isVSyncEnabled(); | ||||
| 
 | ||||
| 		// 创建一个 Direct2D 渲染目标
 | ||||
| 		HRESULT hr = Renderer::getFactory()->CreateHwndRenderTarget( | ||||
| 			D2D1::RenderTargetProperties(), | ||||
| 			D2D1::HwndRenderTargetProperties( | ||||
| 				hWnd, | ||||
| 				size, | ||||
| 				VSyncEnabled ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY), | ||||
| 			&_renderTarget | ||||
| 		); | ||||
| 
 | ||||
| 		if (FAILED(hr)) | ||||
| 		{ | ||||
| 			throw SystemException(L"Create ID2D1HwndRenderTarget failed"); | ||||
| 		} | ||||
| 	} | ||||
| 	return _renderTarget; | ||||
| } | ||||
| 
 | ||||
| ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush() | ||||
| { | ||||
| 	if (!_solidBrush) | ||||
| 	{ | ||||
| 		// 创建画刷
 | ||||
| 		HRESULT hr = this->getRenderTarget()->CreateSolidColorBrush( | ||||
| 			D2D1::ColorF(D2D1::ColorF::White), | ||||
| 			&_solidBrush | ||||
| 		); | ||||
| 
 | ||||
| 		if (FAILED(hr)) | ||||
| 		{ | ||||
| 			throw SystemException(L"Create ID2D1SolidColorBrush failed"); | ||||
| 		} | ||||
| 	} | ||||
| 	return _solidBrush; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ e2d::Config::Config() | |||
| 	, _soundEnabled(true) | ||||
| 	, _frameInterval(15) | ||||
| 	, _showFps(false) | ||||
| 	, _vSyncEnabled(false) | ||||
| 	, _outlineVisible(false) | ||||
| 	, _collisionEnabled(false) | ||||
| 	, _colliderVisible(false) | ||||
|  | @ -28,6 +29,11 @@ void e2d::Config::showFps(bool show) | |||
| 	_showFps = show; | ||||
| } | ||||
| 
 | ||||
| void e2d::Config::setVSyncEnabled(bool enabled) | ||||
| { | ||||
| 	_vSyncEnabled = enabled; | ||||
| } | ||||
| 
 | ||||
| void e2d::Config::setFrameInterval(int interval) | ||||
| { | ||||
| 	_frameInterval = interval; | ||||
|  | @ -76,6 +82,11 @@ bool e2d::Config::isSoundEnabled() const | |||
| 	return _soundEnabled; | ||||
| } | ||||
| 
 | ||||
| bool e2d::Config::isVSyncEnabled() const | ||||
| { | ||||
| 	return _vSyncEnabled; | ||||
| } | ||||
| 
 | ||||
| bool e2d::Config::isFpsShow() const | ||||
| { | ||||
| 	return _showFps; | ||||
|  |  | |||
|  | @ -56,6 +56,8 @@ private: | |||
| 
 | ||||
| 	E2D_DISABLE_COPY(Game); | ||||
| 
 | ||||
| 	void __update(); | ||||
| 
 | ||||
| private: | ||||
| 	bool		_quit; | ||||
| 	bool		_paused; | ||||
|  | @ -292,6 +294,9 @@ public: | |||
| 	// 渲染游戏画面
 | ||||
| 	void render(); | ||||
| 
 | ||||
| 	// 删除设备相关资源
 | ||||
| 	void discardDeviceResources(); | ||||
| 
 | ||||
| 	// 获取文字渲染器
 | ||||
| 	TextRenderer * getTextRenderer(); | ||||
| 
 | ||||
|  | @ -326,12 +331,6 @@ private: | |||
| 
 | ||||
| 	E2D_DISABLE_COPY(Renderer); | ||||
| 
 | ||||
| 	// 创建设备相关资源
 | ||||
| 	bool __createDeviceResources(); | ||||
| 
 | ||||
| 	// 删除设备相关资源
 | ||||
| 	void __discardDeviceResources(); | ||||
| 
 | ||||
| 	// 渲染 FPS
 | ||||
| 	void _renderFps(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1065,6 +1065,12 @@ public: | |||
| 		bool show | ||||
| 	); | ||||
| 
 | ||||
| 	// 打开或关闭垂直同步
 | ||||
| 	// 默认:关闭
 | ||||
| 	void setVSyncEnabled( | ||||
| 		bool enabled | ||||
| 	); | ||||
| 
 | ||||
| 	// 设置帧率刷新间隔
 | ||||
| 	// 默认:15
 | ||||
| 	void setFrameInterval( | ||||
|  | @ -1113,6 +1119,9 @@ public: | |||
| 	// 获取声音打开状态
 | ||||
| 	bool isSoundEnabled() const; | ||||
| 
 | ||||
| 	// 获取垂直同步打开状态
 | ||||
| 	bool isVSyncEnabled() const; | ||||
| 
 | ||||
| 	// 获取 FPS 显示状态
 | ||||
| 	bool isFpsShow() const; | ||||
| 
 | ||||
|  | @ -1136,6 +1145,7 @@ public: | |||
| 
 | ||||
| protected: | ||||
| 	bool			_showFps; | ||||
| 	bool			_vSyncEnabled; | ||||
| 	bool			_soundEnabled; | ||||
| 	bool			_outlineVisible; | ||||
| 	bool			_collisionEnabled; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue