From 0088bd88a3ed190527cad57abf0cc1df4b2b230b Mon Sep 17 00:00:00 2001 From: Haibo Date: Wed, 21 Nov 2018 16:26:52 +0800 Subject: [PATCH] add graphics options --- core/base/Game.cpp | 15 ++++------ core/base/Game.h | 15 ++++++---- core/base/Input.cpp | 6 ++-- core/base/Input.h | 2 +- core/base/audio.cpp | 6 ++-- core/base/audio.h | 2 +- core/base/render.cpp | 69 +++++++++++++++++++++++++++++++------------- core/base/render.h | 31 ++++++++++++++++---- core/base/window.cpp | 11 +++---- core/base/window.h | 2 +- 10 files changed, 103 insertions(+), 56 deletions(-) diff --git a/core/base/Game.cpp b/core/base/Game.cpp index c6a8ae58..b9f46c4a 100644 --- a/core/base/Game.cpp +++ b/core/base/Game.cpp @@ -20,7 +20,6 @@ #include "Game.h" #include "logs.h" -#include "render.h" #include "input.h" #include "audio.h" #include "modules.h" @@ -35,8 +34,7 @@ namespace easy2d { Game::Game() - : quit_(true) - , curr_scene_(nullptr) + : curr_scene_(nullptr) , next_scene_(nullptr) , transition_(nullptr) , debug_enabled_(false) @@ -79,7 +77,7 @@ namespace easy2d ::SetWindowLongW(hwnd_, GWLP_USERDATA, PtrToUlong(this)); - devices::Graphics::Instance()->Init(hwnd_, debug_enabled_); + devices::Graphics::Instance()->Init(hwnd_, options.graphics_options, debug_enabled_); devices::Input::Instance()->Init(hwnd_, window->GetContentScaleX(), window->GetContentScaleY(), debug_enabled_); devices::Audio::Instance()->Init(debug_enabled_); @@ -121,8 +119,6 @@ namespace easy2d void Game::Run() { - quit_ = false; - if (next_scene_) { next_scene_->OnEnter(); @@ -134,7 +130,7 @@ namespace easy2d ::UpdateWindow(hwnd_); MSG msg = {}; - while (::GetMessageW(&msg, nullptr, 0, 0) && !quit_) + while (::GetMessageW(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessageW(&msg); @@ -143,7 +139,7 @@ namespace easy2d void Game::Quit() { - quit_ = true; + ::DestroyWindow(hwnd_); } bool Game::EnterScene(spScene const & scene) @@ -367,7 +363,7 @@ namespace easy2d { if (game->OnClose()) { - game->Quit(); + ::DestroyWindow(hwnd); } } result = 0; @@ -376,6 +372,7 @@ namespace easy2d case WM_DESTROY: { + game->OnExit(); ::PostQuitMessage(0); } result = 1; diff --git a/core/base/Game.h b/core/base/Game.h index de6cb005..00bd95c3 100644 --- a/core/base/Game.h +++ b/core/base/Game.h @@ -22,6 +22,7 @@ #include "base.hpp" #include "window.h" #include "time.h" +#include "render.h" #include "KeyEvent.h" #include "MouseEvent.h" @@ -29,11 +30,13 @@ namespace easy2d { struct Options { - String title; /* 标题 */ - int width; /* 宽度 */ - int height; /* 高度 */ - LPCWSTR icon; /* 图标 */ - bool debug; /* 调试模式 */ + String title; // 标题 + int width; // 宽度 + int height; // 高度 + LPCWSTR icon; // 图标 + bool debug; // 调试模式 + + GraphicsOptions graphics_options; // 图形渲染选项 Options() : title(L"Easy2D Game") @@ -41,6 +44,7 @@ namespace easy2d , height(480) , icon(nullptr) , debug(false) + , graphics_options() {} }; @@ -107,7 +111,6 @@ namespace easy2d private: bool initialized_; bool debug_enabled_; - bool quit_; bool window_inactived_; HWND hwnd_; spScene curr_scene_; diff --git a/core/base/Input.cpp b/core/base/Input.cpp index f524f76c..915b9911 100644 --- a/core/base/Input.cpp +++ b/core/base/Input.cpp @@ -27,7 +27,7 @@ namespace easy2d namespace devices { InputDevice::InputDevice() - : initialized(false) + : initialized_(false) , hwnd_(nullptr) , scale_x_(1.f) , scale_y_(1.f) @@ -43,7 +43,7 @@ namespace easy2d void InputDevice::Init(HWND hwnd, float scale_x, float scale_y, bool debug) { - if (initialized) + if (initialized_) return; E2D_LOG("Initing input device"); @@ -52,7 +52,7 @@ namespace easy2d scale_x_ = scale_x; scale_y_ = scale_y; - initialized = true; + initialized_ = true; } void InputDevice::Update() diff --git a/core/base/Input.h b/core/base/Input.h index ce62f780..9833f63d 100644 --- a/core/base/Input.h +++ b/core/base/Input.h @@ -71,7 +71,7 @@ namespace easy2d ~InputDevice(); protected: - bool initialized; + bool initialized_; HWND hwnd_; float scale_x_; float scale_y_; diff --git a/core/base/audio.cpp b/core/base/audio.cpp index ee17b8a2..7a88c569 100644 --- a/core/base/audio.cpp +++ b/core/base/audio.cpp @@ -164,7 +164,7 @@ namespace easy2d AudioDevice::AudioDevice() : x_audio2_(nullptr) , mastering_voice_(nullptr) - , initialized(false) + , initialized_(false) { } @@ -187,7 +187,7 @@ namespace easy2d void AudioDevice::Init(bool debug) { - if (initialized) + if (initialized_) return; E2D_LOG("Initing audio device"); @@ -204,7 +204,7 @@ namespace easy2d x_audio2_->CreateMasteringVoice(&mastering_voice_) ); - initialized = true; + initialized_ = true; } HRESULT AudioDevice::CreateVoice(Voice& voice, const WAVEFORMATEX* wfx) diff --git a/core/base/audio.h b/core/base/audio.h index c5b12246..a89939b5 100644 --- a/core/base/audio.h +++ b/core/base/audio.h @@ -105,7 +105,7 @@ namespace easy2d ~AudioDevice(); protected: - bool initialized; + bool initialized_; IXAudio2* x_audio2_; IXAudio2MasteringVoice* mastering_voice_; std::set voice_cache_; diff --git a/core/base/render.cpp b/core/base/render.cpp index 8c528851..6d00aaf2 100644 --- a/core/base/render.cpp +++ b/core/base/render.cpp @@ -35,8 +35,9 @@ namespace easy2d , fps_text_layout_(nullptr) , clear_color_(D2D1::ColorF(D2D1::ColorF::Black)) , opacity_(1.f) - , window_occluded(false) - , initialized(false) + , window_occluded_(false) + , initialized_(false) + , options_() { ZeroMemory(&d2d, sizeof(D2DResources)); } @@ -48,19 +49,22 @@ namespace easy2d ClearImageCache(); } - void GraphicsDevice::Init(HWND hwnd, bool debug) + void GraphicsDevice::Init(HWND hwnd, GraphicsOptions options, bool debug) { - if (initialized) + if (initialized_) return; E2D_LOG("Initing graphics device"); - D2D1_FACTORY_OPTIONS options{ debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE }; + options_ = options; + + D2D1_FACTORY_OPTIONS fact_options; + fact_options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE; ThrowIfFailed( modules::DirectX().D2D1CreateFactory( D2D1_FACTORY_TYPE_SINGLE_THREADED, __uuidof(ID2D1Factory), - &options, + &fact_options, reinterpret_cast(&d2d.factory) ) ); @@ -124,16 +128,16 @@ namespace easy2d CreateDeviceResources(hwnd); - initialized = true; + initialized_ = true; } void GraphicsDevice::BeginDraw(HWND hwnd) { CreateDeviceResources(hwnd); - window_occluded = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); + window_occluded_ = !!(d2d.render_target->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED); - if (!window_occluded) + if (!window_occluded_) { d2d.render_target->BeginDraw(); d2d.render_target->Clear(clear_color_); @@ -142,7 +146,7 @@ namespace easy2d void GraphicsDevice::EndDraw() { - if (!window_occluded) + if (!window_occluded_) { HRESULT hr = d2d.render_target->EndDraw(); @@ -425,7 +429,7 @@ namespace easy2d !d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.solid_brush->SetColor(stroke_color); @@ -444,7 +448,7 @@ namespace easy2d !d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.solid_brush->SetColor(fill_color); @@ -463,7 +467,7 @@ namespace easy2d if (!image->GetBitmap()) return S_OK; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.render_target->DrawBitmap( @@ -500,7 +504,7 @@ namespace easy2d if (!d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; // Do not crop bitmap @@ -520,7 +524,7 @@ namespace easy2d if (!d2d.text_renderer) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; return text_layout->Draw(nullptr, d2d.text_renderer.Get(), 0, 0); @@ -531,7 +535,7 @@ namespace easy2d if (!d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.render_target->SetTransform(ConvertToD2DMatrix(clip_matrix)); @@ -547,7 +551,7 @@ namespace easy2d if (!d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.render_target->PopAxisAlignedClip(); @@ -560,7 +564,7 @@ namespace easy2d !d2d.solid_brush) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.render_target->PushLayer( @@ -583,7 +587,7 @@ namespace easy2d if (!d2d.render_target) return E_UNEXPECTED; - if (window_occluded) + if (window_occluded_) return S_OK; d2d.render_target->PopLayer(); @@ -863,10 +867,35 @@ namespace easy2d D2D1::HwndRenderTargetProperties( hwnd, size, - D2D1_PRESENT_OPTIONS_NONE), + options_.vsync ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY + ), &d2d.render_target ) ); + + d2d.render_target->SetAntialiasMode( + options_.antialias ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED + ); + + D2D1_TEXT_ANTIALIAS_MODE mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; + switch (options_.text_antialias) + { + case TextAntialias::Default: + mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; + break; + case TextAntialias::ClearType: + mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; + break; + case TextAntialias::GrayScale: + mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; + break; + case TextAntialias::None: + mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; + break; + default: + break; + } + d2d.render_target->SetTextAntialiasMode(mode); } if (!d2d.solid_brush) diff --git a/core/base/render.h b/core/base/render.h index 0eaeadc9..3d218428 100644 --- a/core/base/render.h +++ b/core/base/render.h @@ -29,7 +29,27 @@ namespace easy2d { - class Image; + enum class TextAntialias + { + Default, // 系统默认 + ClearType, // ClearType 抗锯齿 + GrayScale, // 灰度抗锯齿 + None // 不启用抗锯齿 + }; + + // 图形渲染选项 + struct GraphicsOptions + { + bool vsync; // 垂直同步 + bool antialias; // 抗锯齿 + TextAntialias text_antialias; // 文字抗锯齿模式 + + GraphicsOptions() + : vsync(true) + , antialias(true) + , text_antialias(TextAntialias::ClearType) + {} + }; namespace devices { @@ -40,7 +60,7 @@ namespace easy2d cpWriteFactory write_factory; cpTextRenderer text_renderer; cpSolidColorBrush solid_brush; - cpHwndRenderTarget render_target; + cpHwndRenderTarget render_target; cpStrokeStyle miter_stroke_style; cpStrokeStyle bevel_stroke_style; cpStrokeStyle round_stroke_style; @@ -53,7 +73,7 @@ namespace easy2d E2D_DECLARE_SINGLETON(GraphicsDevice); public: - void Init(HWND hwnd, bool debug); + void Init(HWND hwnd, GraphicsOptions options, bool debug); // 开始渲染 void BeginDraw(HWND hwnd); @@ -214,9 +234,10 @@ namespace easy2d ~GraphicsDevice(); protected: - bool initialized; - bool window_occluded; + bool initialized_; + bool window_occluded_; float opacity_; + GraphicsOptions options_; D2DResources d2d; D2D1_COLOR_F clear_color_; cpTextFormat fps_text_format_; diff --git a/core/base/window.cpp b/core/base/window.cpp index 4507351d..2e760420 100644 --- a/core/base/window.cpp +++ b/core/base/window.cpp @@ -39,24 +39,21 @@ namespace easy2d : handle(nullptr) , scale_x(1.f) , scale_y(1.f) - , initialized(false) + , initialized_(false) { } WindowImpl::~WindowImpl() { E2D_LOG("Destroying window"); - - if (handle) - ::DestroyWindow(handle); } void WindowImpl::Init(String title, int width, int height, LPCWSTR icon, WNDPROC proc, bool debug) { - if (initialized) + if (initialized_) return; - E2D_LOG("Initing window"); + E2D_LOG("Creating window"); HINSTANCE hinstance = GetModuleHandle(nullptr); WNDCLASSEX wcex = { 0 }; @@ -116,7 +113,7 @@ namespace easy2d throw std::runtime_error(err); } - initialized = true; + initialized_ = true; } String WindowImpl::GetTitle() const diff --git a/core/base/window.h b/core/base/window.h index ef4b6b25..38440114 100644 --- a/core/base/window.h +++ b/core/base/window.h @@ -72,7 +72,7 @@ namespace easy2d ~WindowImpl(); private: - bool initialized; + bool initialized_; HWND handle; float scale_x; float scale_y;