在Config中增加VSync开启选项

This commit is contained in:
Nomango 2018-07-24 20:21:25 +08:00
parent dda7e17347
commit 58af967968
5 changed files with 119 additions and 98 deletions

View File

@ -42,20 +42,7 @@ void e2d::Game::destroyInstance()
void e2d::Game::start() void e2d::Game::start()
{ {
auto gc = GC::getInstance(); HWND hWnd = Window::getInstance()->getHWnd();
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();
if (hWnd == nullptr) if (hWnd == nullptr)
{ {
throw SystemException(L"无法创建窗口"); throw SystemException(L"无法创建窗口");
@ -64,7 +51,7 @@ void e2d::Game::start()
// 显示窗口 // 显示窗口
::ShowWindow(hWnd, SW_SHOWNORMAL); ::ShowWindow(hWnd, SW_SHOWNORMAL);
::UpdateWindow(hWnd); ::UpdateWindow(hWnd);
window->poll(); Window::getInstance()->poll();
// 开始游戏 // 开始游戏
Duration interval; Duration interval;
@ -76,31 +63,43 @@ void e2d::Game::start()
while (!_quit) while (!_quit)
{ {
_now = Time::now(); _now = Time::now();
interval = _now - _last;
if (_frameInterval < interval) if (_config.isVSyncEnabled())
{ {
_last = _now; __update();
input->update();
timer->update();
actionManager->update();
sceneManager->update();
renderer->render();
window->poll();
gc->flush();
} }
else else
{ {
wait = (_frameInterval - interval).milliseconds() - 1; interval = _now - _last;
if (wait > 1)
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() void e2d::Game::pause()
{ {
_paused = true; _paused = true;
@ -124,18 +123,25 @@ bool e2d::Game::isPaused()
void e2d::Game::setConfig(const Config& config) void e2d::Game::setConfig(const Config& config)
{ {
if (_config.isSoundEnabled() != config.isSoundEnabled())
{
if (config.isSoundEnabled())
Player::getInstance()->getXAudio2()->StartEngine();
else
Player::getInstance()->getXAudio2()->StopEngine();
}
if (_config.getFrameInterval() != config.getFrameInterval())
{
_frameInterval = Duration(config.getFrameInterval());
}
if (_config.isVSyncEnabled() != config.isVSyncEnabled())
{
Renderer::getInstance()->discardDeviceResources();
}
_config = config; _config = config;
if (_config.isSoundEnabled())
{
Player::getInstance()->getXAudio2()->StartEngine();
}
else
{
Player::getInstance()->getXAudio2()->StopEngine();
}
_frameInterval = Duration(_config.getFrameInterval());
} }
const e2d::Config& e2d::Game::getConfig() const e2d::Config& e2d::Game::getConfig()

View File

@ -45,8 +45,6 @@ e2d::Renderer::Renderer()
, _clearColor(D2D1::ColorF(D2D1::ColorF::Black)) , _clearColor(D2D1::ColorF(D2D1::ColorF::Black))
{ {
CoInitialize(nullptr); CoInitialize(nullptr);
this->__createDeviceResources();
} }
e2d::Renderer::~Renderer() e2d::Renderer::~Renderer()
@ -59,53 +57,7 @@ e2d::Renderer::~Renderer()
CoUninitialize(); CoUninitialize();
} }
bool e2d::Renderer::__createDeviceResources() void e2d::Renderer::discardDeviceResources()
{
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()
{ {
SafeRelease(_renderTarget); SafeRelease(_renderTarget);
SafeRelease(_solidBrush); SafeRelease(_solidBrush);
@ -117,12 +69,12 @@ void e2d::Renderer::render()
HRESULT hr = S_OK; HRESULT hr = S_OK;
// 创建设备相关资源 // 创建设备相关资源
Renderer::__createDeviceResources(); auto renderTarget = this->getRenderTarget();
// 开始渲染 // 开始渲染
_renderTarget->BeginDraw(); renderTarget->BeginDraw();
// 使用背景色清空屏幕 // 使用背景色清空屏幕
_renderTarget->Clear(_clearColor); renderTarget->Clear(_clearColor);
// 渲染场景 // 渲染场景
SceneManager::getInstance()->render(); SceneManager::getInstance()->render();
@ -134,14 +86,14 @@ void e2d::Renderer::render()
} }
// 终止渲染 // 终止渲染
hr = _renderTarget->EndDraw(); hr = renderTarget->EndDraw();
if (hr == D2DERR_RECREATE_TARGET) if (hr == D2DERR_RECREATE_TARGET)
{ {
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源 // 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
// 并在下一次调用时重建资源 // 并在下一次调用时重建资源
hr = S_OK; hr = S_OK;
this->__discardDeviceResources(); this->discardDeviceResources();
} }
if (FAILED(hr)) if (FAILED(hr))
@ -225,11 +177,54 @@ void e2d::Renderer::setBackgroundColor(Color color)
ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget() 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; return _renderTarget;
} }
ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush() 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; return _solidBrush;
} }

View File

@ -7,6 +7,7 @@ e2d::Config::Config()
, _soundEnabled(true) , _soundEnabled(true)
, _frameInterval(15) , _frameInterval(15)
, _showFps(false) , _showFps(false)
, _vSyncEnabled(false)
, _outlineVisible(false) , _outlineVisible(false)
, _collisionEnabled(false) , _collisionEnabled(false)
, _colliderVisible(false) , _colliderVisible(false)
@ -28,6 +29,11 @@ void e2d::Config::showFps(bool show)
_showFps = show; _showFps = show;
} }
void e2d::Config::setVSyncEnabled(bool enabled)
{
_vSyncEnabled = enabled;
}
void e2d::Config::setFrameInterval(int interval) void e2d::Config::setFrameInterval(int interval)
{ {
_frameInterval = interval; _frameInterval = interval;
@ -76,6 +82,11 @@ bool e2d::Config::isSoundEnabled() const
return _soundEnabled; return _soundEnabled;
} }
bool e2d::Config::isVSyncEnabled() const
{
return _vSyncEnabled;
}
bool e2d::Config::isFpsShow() const bool e2d::Config::isFpsShow() const
{ {
return _showFps; return _showFps;

View File

@ -56,6 +56,8 @@ private:
E2D_DISABLE_COPY(Game); E2D_DISABLE_COPY(Game);
void __update();
private: private:
bool _quit; bool _quit;
bool _paused; bool _paused;
@ -292,6 +294,9 @@ public:
// 渲染游戏画面 // 渲染游戏画面
void render(); void render();
// 删除设备相关资源
void discardDeviceResources();
// 获取文字渲染器 // 获取文字渲染器
TextRenderer * getTextRenderer(); TextRenderer * getTextRenderer();
@ -326,12 +331,6 @@ private:
E2D_DISABLE_COPY(Renderer); E2D_DISABLE_COPY(Renderer);
// 创建设备相关资源
bool __createDeviceResources();
// 删除设备相关资源
void __discardDeviceResources();
// 渲染 FPS // 渲染 FPS
void _renderFps(); void _renderFps();

View File

@ -1065,6 +1065,12 @@ public:
bool show bool show
); );
// 打开或关闭垂直同步
// 默认:关闭
void setVSyncEnabled(
bool enabled
);
// 设置帧率刷新间隔 // 设置帧率刷新间隔
// 默认15 // 默认15
void setFrameInterval( void setFrameInterval(
@ -1113,6 +1119,9 @@ public:
// 获取声音打开状态 // 获取声音打开状态
bool isSoundEnabled() const; bool isSoundEnabled() const;
// 获取垂直同步打开状态
bool isVSyncEnabled() const;
// 获取 FPS 显示状态 // 获取 FPS 显示状态
bool isFpsShow() const; bool isFpsShow() const;
@ -1136,6 +1145,7 @@ public:
protected: protected:
bool _showFps; bool _showFps;
bool _vSyncEnabled;
bool _soundEnabled; bool _soundEnabled;
bool _outlineVisible; bool _outlineVisible;
bool _collisionEnabled; bool _collisionEnabled;