Update Runner

This commit is contained in:
Nomango 2020-02-14 22:01:56 +08:00
parent 72f8fd5e12
commit 94915b87ff
20 changed files with 457 additions and 291 deletions

View File

@ -22,7 +22,6 @@
<ClInclude Include="..\..\src\kiwano\core\Exception.h" /> <ClInclude Include="..\..\src\kiwano\core\Exception.h" />
<ClInclude Include="..\..\src\kiwano\core\Keys.h" /> <ClInclude Include="..\..\src\kiwano\core\Keys.h" />
<ClInclude Include="..\..\src\kiwano\core\Library.h" /> <ClInclude Include="..\..\src\kiwano\core\Library.h" />
<ClInclude Include="..\..\src\kiwano\core\Runner.h" />
<ClInclude Include="..\..\src\kiwano\core\Singleton.h" /> <ClInclude Include="..\..\src\kiwano\core\Singleton.h" />
<ClInclude Include="..\..\src\kiwano\core\Time.h" /> <ClInclude Include="..\..\src\kiwano\core\Time.h" />
<ClInclude Include="..\..\src\kiwano\kiwano.h" /> <ClInclude Include="..\..\src\kiwano\kiwano.h" />
@ -61,9 +60,9 @@
<ClInclude Include="..\..\src\kiwano\platform\Application.h" /> <ClInclude Include="..\..\src\kiwano\platform\Application.h" />
<ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" /> <ClInclude Include="..\..\src\kiwano\platform\FileSystem.h" />
<ClInclude Include="..\..\src\kiwano\platform\Input.h" /> <ClInclude Include="..\..\src\kiwano\platform\Input.h" />
<ClInclude Include="..\..\src\kiwano\platform\Runner.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" /> <ClInclude Include="..\..\src\kiwano\platform\win32\ComPtr.hpp" />
<ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" /> <ClInclude Include="..\..\src\kiwano\platform\win32\libraries.h" />
<ClInclude Include="..\..\src\kiwano\platform\win32\WindowImpl.h" />
<ClInclude Include="..\..\src\kiwano\platform\Window.h" /> <ClInclude Include="..\..\src\kiwano\platform\Window.h" />
<ClInclude Include="..\..\src\kiwano\render\Brush.h" /> <ClInclude Include="..\..\src\kiwano\render\Brush.h" />
<ClInclude Include="..\..\src\kiwano\render\Color.h" /> <ClInclude Include="..\..\src\kiwano\render\Color.h" />
@ -136,6 +135,7 @@
<ClCompile Include="..\..\src\kiwano\platform\Application.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\Application.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\FileSystem.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Input.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\Input.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Runner.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\win32\libraries.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\win32\WindowImpl.cpp" />
<ClCompile Include="..\..\src\kiwano\platform\Window.cpp" /> <ClCompile Include="..\..\src\kiwano\platform\Window.cpp" />

View File

@ -285,9 +285,6 @@
<ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h"> <ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\win32\WindowImpl.h">
<Filter>platform\win32</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Exception.h"> <ClInclude Include="..\..\src\kiwano\core\Exception.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
@ -297,12 +294,12 @@
<ClInclude Include="..\..\src\kiwano\render\Layer.h"> <ClInclude Include="..\..\src\kiwano\render\Layer.h">
<Filter>render</Filter> <Filter>render</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Runner.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\core\Module.h"> <ClInclude Include="..\..\src\kiwano\core\Module.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\platform\Runner.h">
<Filter>platform</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -512,5 +509,8 @@
<ClCompile Include="..\..\src\kiwano\core\Module.cpp"> <ClCompile Include="..\..\src\kiwano\core\Module.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\platform\Runner.cpp">
<Filter>platform</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -5,7 +5,7 @@
#include <kiwano/core/event/KeyEvent.h> #include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h> #include <kiwano/core/event/MouseEvent.h>
#include <kiwano/platform/Input.h> #include <kiwano/platform/Input.h>
#include <kiwano/platform/win32/WindowImpl.h> #include <kiwano/platform/Application.h>
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#include <kiwano-imgui/ImGuiModule.h> #include <kiwano-imgui/ImGuiModule.h>
#include <kiwano-imgui/imgui_impl/imgui_impl.h> #include <kiwano-imgui/imgui_impl/imgui_impl.h>
@ -29,12 +29,14 @@ void ImGuiModule::SetupModule()
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
window_ = Application::GetInstance().GetMainWindow();
// Setup Platform/Renderer bindings // Setup Platform/Renderer bindings
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
io.BackendFlags |= io.BackendFlags |=
ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
io.BackendPlatformName = "imgui_impl_win32"; io.BackendPlatformName = "imgui_impl_win32";
io.ImeWindowHandle = WindowImpl::GetInstance().GetHandle(); io.ImeWindowHandle = window_->GetHandle();
// Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during
// the application lifetime. // the application lifetime.
@ -174,7 +176,7 @@ void ImGuiModule::UpdateMousePos()
if (io.WantSetMousePos) if (io.WantSetMousePos)
{ {
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
::ClientToScreen(WindowImpl::GetInstance().GetHandle(), &pos); ::ClientToScreen(window_->GetHandle(), &pos);
::SetCursorPos(pos.x, pos.y); ::SetCursorPos(pos.x, pos.y);
} }
@ -216,7 +218,7 @@ void ImGuiModule::UpdateMouseCursor()
break; break;
} }
Window::GetInstance().SetCursor(cursor); window_->SetCursor(cursor);
} }
} // namespace imgui } // namespace imgui

View File

@ -21,6 +21,7 @@
#pragma once #pragma once
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Module.h> #include <kiwano/core/Module.h>
#include <kiwano/platform/Window.h>
namespace kiwano namespace kiwano
{ {
@ -58,6 +59,9 @@ private:
void UpdateMousePos(); void UpdateMousePos();
void UpdateMouseCursor(); void UpdateMouseCursor();
private:
WindowPtr window_;
}; };
} // namespace imgui } // namespace imgui

View File

@ -30,7 +30,7 @@ namespace network
{ {
/** /**
* \~chinese * \~chinese
* \defgroup Network * \defgroup Network
*/ */
/** /**

View File

@ -30,7 +30,7 @@ KGE_DECLARE_SMART_PTR(World);
/** /**
* \~chinese * \~chinese
* \defgroup Physics * \defgroup Physics
*/ */
/** /**

View File

@ -20,7 +20,7 @@
#include <kiwano/2d/Button.h> #include <kiwano/2d/Button.h>
#include <kiwano/2d/Stage.h> #include <kiwano/2d/Stage.h>
#include <kiwano/platform/Window.h> #include <kiwano/platform/Application.h>
namespace kiwano namespace kiwano
{ {
@ -73,14 +73,14 @@ void Button::SetStatus(Status status)
if (status == Status::Normal) if (status == Status::Normal)
{ {
Window::GetInstance().SetCursor(CursorType::Arrow); Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Arrow);
if (mouse_out_callback_) if (mouse_out_callback_)
mouse_out_callback_(this); mouse_out_callback_(this);
} }
else if (status == Status::Hover) else if (status == Status::Hover)
{ {
Window::GetInstance().SetCursor(CursorType::Hand); Application::GetInstance().GetMainWindow()->SetCursor(CursorType::Hand);
if (old_status != Status::Pressed) if (old_status != Status::Pressed)
{ {

View File

@ -105,10 +105,11 @@
// platform // platform
// //
#include <kiwano/platform/Window.h>
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
#include <kiwano/platform/FileSystem.h> #include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/Input.h> #include <kiwano/platform/Input.h>
#include <kiwano/platform/Window.h>
// //
// utils // utils

View File

@ -22,6 +22,7 @@
#include <kiwano/platform/Input.h> #include <kiwano/platform/Input.h>
#include <kiwano/core/Director.h> #include <kiwano/core/Director.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/TextureCache.h> #include <kiwano/render/TextureCache.h>
#include <kiwano/utils/ResourceCache.h> #include <kiwano/utils/ResourceCache.h>
@ -39,8 +40,11 @@ Application::Application()
Application::~Application() {} Application::~Application() {}
void Application::Run(Runner& runner, bool debug) void Application::Run(Runner* runner, bool debug)
{ {
KGE_ASSERT(runner);
runner_ = runner;
// Setup all modules // Setup all modules
for (auto c : modules_) for (auto c : modules_)
{ {
@ -54,38 +58,18 @@ void Application::Run(Runner& runner, bool debug)
} }
// Everything is ready // Everything is ready
runner.OnReady(); runner->OnReady();
runner->SetLastUpdateTime(Time::Now());
// Initialize variables quiting_ = false;
quiting_ = false;
last_update_time_ = Time::Now();
Window& window = Window::GetInstance();
while (!quiting_) while (!quiting_)
{ {
if (window.ShouldClose()) quiting_ = !runner->MainLoop();
{
if (runner.OnClosing())
break;
else
window.SetShouldClose(false);
}
while (EventPtr evt = window.PollEvent())
{
this->DispatchEvent(evt.get());
}
this->Update();
this->Render();
} }
// Destroy all resources // Destroy all resources
runner.OnDestroy(); runner->OnDestroy();
this->Destroy(); this->Destroy();
// Destroy window
window.Destroy();
} }
void Application::Quit() void Application::Quit()
@ -123,7 +107,7 @@ void Application::SetTimeScale(float scale_factor)
time_scale_ = scale_factor; time_scale_ = scale_factor;
} }
void Application::Update() void Application::Update(Duration dt)
{ {
// Before update // Before update
for (auto comp : modules_) for (auto comp : modules_)
@ -155,18 +139,12 @@ void Application::Update()
} }
// Updating // Updating
Duration scaled_dt = dt * time_scale_;
for (auto comp : modules_)
{ {
const Time now = Time::Now(); if (auto update_comp = comp->Cast<UpdateModule>())
const Duration dt = (now - last_update_time_) * time_scale_;
last_update_time_ = now;
for (auto comp : modules_)
{ {
if (auto update_comp = comp->Cast<UpdateModule>()) update_comp->OnUpdate(scaled_dt);
{
update_comp->OnUpdate(dt);
}
} }
} }

View File

@ -23,11 +23,10 @@
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Module.h> #include <kiwano/core/Module.h>
#include <kiwano/core/Time.h> #include <kiwano/core/Time.h>
#include <kiwano/core/Runner.h>
#include <kiwano/core/Singleton.h> #include <kiwano/core/Singleton.h>
#include <kiwano/core/event/Event.h> #include <kiwano/core/event/Event.h>
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Window.h> #include <kiwano/platform/Window.h>
#include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
@ -47,11 +46,20 @@ public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param[in] runner * @param runner
* @param debug * @param debug
* @note * @note
*/ */
void Run(Runner& runner, bool debug = false); void Run(RunnerPtr runner, bool debug = false);
/**
* \~chinese
* @brief
* @param runner
* @param debug
* @note
*/
void Run(Runner* runner, bool debug = false);
/** /**
* \~chinese * \~chinese
@ -65,6 +73,18 @@ public:
*/ */
void Destroy(); void Destroy();
/**
* \~chinese
* @brief
*/
RunnerPtr GetRunner() const;
/**
* \~chinese
* @brief
*/
WindowPtr GetMainWindow() const;
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -97,26 +117,42 @@ public:
*/ */
void PreformInMainThread(Function<void()> func); void PreformInMainThread(Function<void()> func);
private:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param dt
*/ */
void Update(); void Update(Duration dt);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
void Render(); void Render();
private: private:
bool quiting_; bool quiting_;
float time_scale_; float time_scale_;
Time last_update_time_; RunnerPtr runner_;
List<Module*> modules_; List<Module*> modules_;
std::mutex perform_mutex_; std::mutex perform_mutex_;
Queue<Function<void()>> functions_to_perform_; Queue<Function<void()>> functions_to_perform_;
}; };
inline void Application::Run(RunnerPtr runner, bool debug)
{
this->Run(runner.get(), debug);
}
inline RunnerPtr Application::GetRunner() const
{
return runner_;
}
inline WindowPtr Application::GetMainWindow() const
{
KGE_ASSERT(runner_);
return runner_->GetMainWindow();
}
} // namespace kiwano } // namespace kiwano

View File

@ -0,0 +1,100 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include <kiwano/platform/Runner.h>
#include <kiwano/platform/Application.h>
namespace kiwano
{
RunnerPtr Runner::Create(WindowPtr main_window)
{
RunnerPtr ptr = new (std::nothrow) Runner;
if (ptr)
{
ptr->SetMainWindow(main_window);
}
return ptr;
}
RunnerPtr Runner::Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy)
{
class CallbackRunner : public Runner
{
public:
void OnReady() override
{
if (on_ready)
on_ready();
}
void OnDestroy() override
{
if (on_destroy)
on_destroy();
}
Function<void()> on_ready;
Function<void()> on_destroy;
};
SmartPtr<CallbackRunner> ptr = new (std::nothrow) CallbackRunner;
if (ptr)
{
ptr->on_ready = on_ready;
ptr->on_destroy = on_destroy;
ptr->SetMainWindow(main_window);
}
return ptr;
}
Runner::Runner() {}
Runner::~Runner() {}
bool Runner::MainLoop()
{
if (main_window_->ShouldClose())
{
if (this->OnClosing())
return false;
main_window_->SetShouldClose(false);
}
Application& app = Application::GetInstance();
// Poll events
while (EventPtr evt = main_window_->PollEvent())
{
app.DispatchEvent(evt.get());
}
// Update & render
const Time now = Time::Now();
const Duration dt = (now - last_update_time_);
last_update_time_ = now;
app.Update(dt);
app.Render();
return true;
}
} // namespace kiwano

View File

@ -20,25 +20,36 @@
#pragma once #pragma once
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/Timer.h>
#include <kiwano/platform/Window.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Runner);
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Runner class KGE_API Runner : public virtual ObjectBase
{ {
public: public:
typedef Function<void()> Callback; /// \~chinese
/// @brief 创建程序运行器
/// @param main_window 主窗口
static RunnerPtr Create(WindowPtr main_window);
/// \~chinese
/// @brief 创建程序运行器
/// @param main_window 主窗口
/// @param on_ready 应用程序初始化完成后执行的回调函数
/// @param on_destroy 应用程序销毁时执行的回调函数
static RunnerPtr Create(WindowPtr main_window, Function<void()> on_ready, Function<void()> on_destroy = nullptr);
Runner(); Runner();
/// \~chinese virtual ~Runner();
/// @brief 构造程序运行器
/// @param on_ready 应用程序初始化完成后执行的回调函数
/// @param on_destroy 应用程序销毁时执行的回调函数
Runner(const Callback& on_ready, const Callback& on_destroy = nullptr);
/// \~chinese /// \~chinese
/// @brief 初始化完成处理 /// @brief 初始化完成处理
@ -51,44 +62,65 @@ public:
virtual void OnDestroy(); virtual void OnDestroy();
/// \~chinese /// \~chinese
/// @brief 窗口关闭处理 /// @brief 应用程序关闭处理
/// @details 重载该函数以处理用户关闭窗口时的行为,如保存用户数据等 /// @details 重载该函数以处理用户关闭应用程序时的行为,如保存用户数据等
/// @return 返回true允许用户关闭窗口,否则阻止窗口关闭 /// @return 返回true允许用户关闭程序,否则阻止程序关闭
virtual bool OnClosing(); virtual bool OnClosing();
/// \~chinese
/// @brief 应用程序主循环
/// @details 重载该函数以
/// @return 返回false退出主循环否则继续运行主循环
virtual bool MainLoop();
/// \~chinese
/// @brief 获取主窗口
WindowPtr GetMainWindow() const;
/// \~chinese
/// @brief 设置主窗口
void SetMainWindow(WindowPtr window);
/// \~chinese
/// @brief 获取上一次更新时间
Time GetLastUpdateTime() const;
/// \~chinese
/// @brief 设置上一次更新时间
void SetLastUpdateTime(Time time);
private: private:
Callback on_ready_; WindowPtr main_window_;
Callback on_destroy_; Time last_update_time_;
}; };
inline void Runner::OnReady() {}
inline Runner::Runner() {} inline void Runner::OnDestroy() {}
inline Runner::Runner(const Callback& on_ready, const Callback& on_destroy)
: on_ready_(on_ready)
, on_destroy_(on_destroy)
{
}
inline void Runner::OnReady()
{
if (on_ready_)
{
on_ready_();
}
}
inline void Runner::OnDestroy()
{
if (on_destroy_)
{
on_destroy_();
}
}
inline bool Runner::OnClosing() inline bool Runner::OnClosing()
{ {
return true; return true;
} }
inline WindowPtr Runner::GetMainWindow() const
{
return main_window_;
}
inline void Runner::SetMainWindow(WindowPtr window)
{
main_window_ = window;
}
inline Time Runner::GetLastUpdateTime() const
{
return last_update_time_;
}
inline void Runner::SetLastUpdateTime(Time time)
{
last_update_time_ = time;
}
} // namespace kiwano } // namespace kiwano

View File

@ -24,13 +24,17 @@ namespace kiwano
{ {
Window::Window() Window::Window()
: should_close_(false) : handle_(nullptr)
, should_close_(false)
, width_(0) , width_(0)
, height_(0) , height_(0)
{ {
} }
Window::~Window() {} Window::~Window()
{
Destroy();
}
EventPtr Window::PollEvent() EventPtr Window::PollEvent()
{ {
@ -65,6 +69,11 @@ uint32_t Window::GetHeight() const
return height_; return height_;
} }
WindowHandle Window::GetHandle() const
{
return handle_;
}
bool Window::ShouldClose() bool Window::ShouldClose()
{ {
return should_close_; return should_close_;

View File

@ -20,12 +20,15 @@
#pragma once #pragma once
#include <kiwano/core/Common.h> #include <kiwano/core/Common.h>
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/event/Event.h> #include <kiwano/core/event/Event.h>
#include <kiwano/math/Math.h> #include <kiwano/math/Math.h>
namespace kiwano namespace kiwano
{ {
KGE_DECLARE_SMART_PTR(Window);
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -43,19 +46,18 @@ enum class CursorType
}; };
#if defined(KGE_WIN32)
typedef HWND WindowHandle;
#endif
/** /**
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Window : protected Noncopyable class KGE_API Window : public ObjectBase
{ {
public: public:
/**
* \~chinese
* @brief
*/
static Window& GetInstance();
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -67,8 +69,8 @@ public:
* @param fullscreen * @param fullscreen
* @throw std::system_error * @throw std::system_error
*/ */
virtual void Create(String const& title, uint32_t width, uint32_t height, uint32_t icon = 0, bool resizable = false, static WindowPtr Create(String const& title, uint32_t width, uint32_t height, uint32_t icon = 0,
bool fullscreen = false) = 0; bool resizable = false, bool fullscreen = false);
/** /**
* \~chinese * \~chinese
@ -98,6 +100,12 @@ public:
*/ */
uint32_t GetHeight() const; uint32_t GetHeight() const;
/**
* \~chinese
* @brief
*/
WindowHandle GetHandle() const;
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -146,11 +154,17 @@ public:
/** /**
* \~chinese * \~chinese
* @brief * @brief
* @param evt * @param evt
*/ */
void PushEvent(EventPtr evt); void PushEvent(EventPtr evt);
/**
* \~chinese
* @brief
*/
virtual void PumpEvents() = 0;
/** /**
* \~chinese * \~chinese
* @brief * @brief
@ -172,14 +186,13 @@ public:
protected: protected:
Window(); Window();
~Window(); virtual ~Window();
virtual void PumpEvents() = 0;
protected: protected:
bool should_close_; bool should_close_;
uint32_t width_; uint32_t width_;
uint32_t height_; uint32_t height_;
WindowHandle handle_;
String title_; String title_;
std::queue<EventPtr> event_queue_; std::queue<EventPtr> event_queue_;
}; };

View File

@ -18,37 +18,87 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/platform/win32/WindowImpl.h> #include <kiwano/platform/Window.h>
#if defined(KGE_WIN32) #if defined(KGE_WIN32)
#include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM #include <kiwano/core/Keys.h>
#include <imm.h> // ImmAssociateContext
#include <kiwano/core/Exception.h> #include <kiwano/core/Exception.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/core/event/KeyEvent.h> #include <kiwano/core/event/KeyEvent.h>
#include <kiwano/core/event/MouseEvent.h> #include <kiwano/core/event/MouseEvent.h>
#include <kiwano/core/event/WindowEvent.h> #include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
#include <Windowsx.h> // GET_X_LPARAM, GET_Y_LPARAM
#include <imm.h> // ImmAssociateContext
#pragma comment(lib, "imm32.lib") #pragma comment(lib, "imm32.lib")
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
#define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
namespace kiwano namespace kiwano
{ {
Window& Window::GetInstance() KGE_DECLARE_SMART_PTR(WindowWin32Impl);
class KGE_API WindowWin32Impl : public Window
{ {
return WindowImpl::GetInstance(); public:
WindowWin32Impl();
virtual ~WindowWin32Impl();
void Init(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, bool fullscreen);
void SetTitle(String const& title) override;
void SetIcon(uint32_t icon_resource) override;
void Resize(uint32_t width, uint32_t height) override;
void SetFullscreen(bool fullscreen) override;
void SetCursor(CursorType cursor) override;
void Destroy() override;
void PumpEvents() override;
DWORD GetStyle() const;
void UpdateCursor();
void SetActive(bool actived);
LRESULT MessageProc(HWND, UINT32, WPARAM, LPARAM);
static LRESULT CALLBACK StaticWndProc(HWND, UINT32, WPARAM, LPARAM);
private:
bool resizable_;
bool is_fullscreen_;
wchar_t* device_name_;
CursorType mouse_cursor_;
std::array<KeyCode, 256> key_map_;
};
WindowPtr Window::Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen)
{
WindowWin32ImplPtr ptr = new (std::nothrow) WindowWin32Impl;
if (ptr)
{
ptr->Init(title, width, height, icon, resizable, fullscreen);
}
return ptr;
} }
WindowImpl& WindowImpl::GetInstance() } // namespace kiwano
namespace kiwano
{ {
static WindowImpl instance;
return instance; #define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
} #define WINDOW_RESIZABLE_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX
#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP
namespace namespace
{ {
@ -106,9 +156,8 @@ void RestoreResolution(WCHAR* device_name)
} }
} // namespace } // namespace
WindowImpl::WindowImpl() WindowWin32Impl::WindowWin32Impl()
: handle_(nullptr) : device_name_(nullptr)
, device_name_(nullptr)
, is_fullscreen_(false) , is_fullscreen_(false)
, resizable_(false) , resizable_(false)
, mouse_cursor_(CursorType::Arrow) , mouse_cursor_(CursorType::Arrow)
@ -156,17 +205,17 @@ WindowImpl::WindowImpl()
key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i); key_map_[VK_F1 + i] = KeyCode(size_t(KeyCode::F1) + i);
} }
WindowImpl::~WindowImpl() {} WindowWin32Impl::~WindowWin32Impl() {}
void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable, void WindowWin32Impl::Init(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen) bool fullscreen)
{ {
HINSTANCE hinst = GetModuleHandleW(nullptr); HINSTANCE hinst = GetModuleHandleW(nullptr);
WNDCLASSEX wcex = { 0 }; WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX); wcex.cbSize = sizeof(WNDCLASSEX);
wcex.lpszClassName = L"KiwanoAppWnd"; wcex.lpszClassName = L"KiwanoAppWnd";
wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */;
wcex.lpfnWndProc = WindowImpl::StaticWndProc; wcex.lpfnWndProc = WindowWin32Impl::StaticWndProc;
wcex.hIcon = nullptr; wcex.hIcon = nullptr;
wcex.cbClsExtra = 0; wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR); wcex.cbWndExtra = sizeof(LONG_PTR);
@ -257,12 +306,7 @@ void WindowImpl::Create(String const& title, uint32_t width, uint32_t height, ui
} }
} }
HWND WindowImpl::GetHandle() const void WindowWin32Impl::PumpEvents()
{
return handle_;
}
void WindowImpl::PumpEvents()
{ {
MSG msg; MSG msg;
while (::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE)) while (::PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
@ -272,7 +316,7 @@ void WindowImpl::PumpEvents()
} }
} }
void WindowImpl::SetTitle(String const& title) void WindowWin32Impl::SetTitle(String const& title)
{ {
if (handle_) if (handle_)
{ {
@ -281,7 +325,7 @@ void WindowImpl::SetTitle(String const& title)
} }
} }
void WindowImpl::SetIcon(uint32_t icon_resource) void WindowWin32Impl::SetIcon(uint32_t icon_resource)
{ {
if (handle_) if (handle_)
{ {
@ -294,7 +338,7 @@ void WindowImpl::SetIcon(uint32_t icon_resource)
} }
} }
void WindowImpl::Resize(uint32_t width, uint32_t height) void WindowWin32Impl::Resize(uint32_t width, uint32_t height)
{ {
if (handle_ && !is_fullscreen_) if (handle_ && !is_fullscreen_)
{ {
@ -307,7 +351,7 @@ void WindowImpl::Resize(uint32_t width, uint32_t height)
} }
} }
void WindowImpl::SetFullscreen(bool fullscreen) void WindowWin32Impl::SetFullscreen(bool fullscreen)
{ {
if (is_fullscreen_ != fullscreen) if (is_fullscreen_ != fullscreen)
{ {
@ -349,12 +393,12 @@ void WindowImpl::SetFullscreen(bool fullscreen)
} }
} }
void WindowImpl::SetCursor(CursorType cursor) void WindowWin32Impl::SetCursor(CursorType cursor)
{ {
mouse_cursor_ = cursor; mouse_cursor_ = cursor;
} }
void WindowImpl::Destroy() void WindowWin32Impl::Destroy()
{ {
if (is_fullscreen_) if (is_fullscreen_)
RestoreResolution(device_name_); RestoreResolution(device_name_);
@ -374,12 +418,12 @@ void WindowImpl::Destroy()
Window::Destroy(); Window::Destroy();
} }
DWORD WindowImpl::GetStyle() const DWORD WindowWin32Impl::GetStyle() const
{ {
return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE)); return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (resizable_ ? (WINDOW_RESIZABLE_STYLE) : (WINDOW_FIXED_STYLE));
} }
void WindowImpl::UpdateCursor() void WindowWin32Impl::UpdateCursor()
{ {
LPTSTR win32_cursor = IDC_ARROW; LPTSTR win32_cursor = IDC_ARROW;
switch (mouse_cursor_) switch (mouse_cursor_)
@ -412,7 +456,7 @@ void WindowImpl::UpdateCursor()
::SetCursor(::LoadCursorW(nullptr, win32_cursor)); ::SetCursor(::LoadCursorW(nullptr, win32_cursor));
} }
void WindowImpl::SetActive(bool actived) void WindowWin32Impl::SetActive(bool actived)
{ {
if (!handle_) if (!handle_)
return; return;
@ -437,7 +481,7 @@ void WindowImpl::SetActive(bool actived)
} }
} }
LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) LRESULT WindowWin32Impl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{ {
switch (msg) switch (msg)
{ {
@ -553,7 +597,7 @@ LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lpa
{ {
// KGE_SYS_LOG("Window resized"); // KGE_SYS_LOG("Window resized");
this->width_ = ((uint32_t)(short)LOWORD(lparam)); this->width_ = ((uint32_t)(short)LOWORD(lparam));
this->height_ = ((uint32_t)(short)HIWORD(lparam)); this->height_ = ((uint32_t)(short)HIWORD(lparam));
WindowResizedEventPtr evt = new WindowResizedEvent; WindowResizedEventPtr evt = new WindowResizedEvent;
@ -641,12 +685,12 @@ LRESULT WindowImpl::MessageProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lpa
return ::DefWindowProcW(hwnd, msg, wparam, lparam); return ::DefWindowProcW(hwnd, msg, wparam, lparam);
} }
LRESULT CALLBACK WindowImpl::StaticWndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) LRESULT CALLBACK WindowWin32Impl::StaticWndProc(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam)
{ {
LONG_PTR ptr = static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA)); LONG_PTR ptr = static_cast<LONG_PTR>(::GetWindowLongPtrW(hwnd, GWLP_USERDATA));
if (ptr) if (ptr)
{ {
WindowImpl* window = reinterpret_cast<WindowImpl*>(ptr); WindowWin32Impl* window = reinterpret_cast<WindowWin32Impl*>(ptr);
return window->MessageProc(hwnd, msg, wparam, lparam); return window->MessageProc(hwnd, msg, wparam, lparam);
} }
return ::DefWindowProcW(hwnd, msg, wparam, lparam); return ::DefWindowProcW(hwnd, msg, wparam, lparam);

View File

@ -1,81 +0,0 @@
// Copyright (c) 2016-2020 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#pragma once
#include <kiwano/platform/Window.h>
#include <kiwano/core/Keys.h>
#if defined(KGE_WIN32)
namespace kiwano
{
class KGE_API WindowImpl : public Window
{
public:
static WindowImpl& GetInstance();
HWND GetHandle() const;
void Create(String const& title, uint32_t width, uint32_t height, uint32_t icon, bool resizable,
bool fullscreen) override;
void SetTitle(String const& title) override;
void SetIcon(uint32_t icon_resource) override;
void Resize(uint32_t width, uint32_t height) override;
void SetFullscreen(bool fullscreen) override;
void SetCursor(CursorType cursor) override;
void Destroy() override;
private:
WindowImpl();
~WindowImpl();
void PumpEvents() override;
DWORD GetStyle() const;
void UpdateCursor();
void SetActive(bool actived);
LRESULT MessageProc(HWND, UINT32, WPARAM, LPARAM);
static LRESULT CALLBACK StaticWndProc(HWND, UINT32, WPARAM, LPARAM);
private:
bool resizable_;
bool is_fullscreen_;
wchar_t* device_name_;
HWND handle_;
CursorType mouse_cursor_;
std::array<KeyCode, 256> key_map_;
};
} // namespace kiwano
#endif

View File

@ -22,7 +22,7 @@
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/core/event/WindowEvent.h> #include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/FileSystem.h> #include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/win32/WindowImpl.h> #include <kiwano/platform/Application.h>
#include <kiwano/render/ShapeSink.h> #include <kiwano/render/ShapeSink.h>
#include <kiwano/render/DirectX/TextureRenderContextImpl.h> #include <kiwano/render/DirectX/TextureRenderContextImpl.h>
#include <kiwano/render/DirectX/RendererImpl.h> #include <kiwano/render/DirectX/RendererImpl.h>
@ -46,14 +46,14 @@ RendererImpl::RendererImpl()
render_ctx_ = new RenderContextImpl; render_ctx_ = new RenderContextImpl;
} }
void RendererImpl::SetupModule() void RendererImpl::MakeContextForWindow(WindowPtr window)
{ {
KGE_SYS_LOG("Creating device resources"); KGE_SYS_LOG("Creating device resources");
ThrowIfFailed(::CoInitialize(nullptr), "CoInitialize failed"); ThrowIfFailed(::CoInitialize(nullptr), "CoInitialize failed");
HWND target_window = WindowImpl::GetInstance().GetHandle(); HWND target_window = window->GetHandle();
output_size_ = Window::GetInstance().GetSize(); output_size_ = window->GetSize();
d2d_res_ = nullptr; d2d_res_ = nullptr;
d3d_res_ = nullptr; d3d_res_ = nullptr;
@ -115,7 +115,7 @@ void RendererImpl::SetupModule()
ThrowIfFailed(hr, "Create render resources failed"); ThrowIfFailed(hr, "Create render resources failed");
} }
void RendererImpl::DestroyModule() void RendererImpl::Destroy()
{ {
KGE_SYS_LOG("Destroying device resources"); KGE_SYS_LOG("Destroying device resources");
@ -168,15 +168,6 @@ void RendererImpl::Present()
ThrowIfFailed(hr, "Unexpected DXGI exception"); ThrowIfFailed(hr, "Unexpected DXGI exception");
} }
void RendererImpl::HandleEvent(Event* evt)
{
if (evt->IsType<WindowResizedEvent>())
{
auto window_evt = dynamic_cast<WindowResizedEvent*>(evt);
Resize(window_evt->width, window_evt->height);
}
}
HRESULT RendererImpl::HandleDeviceLost() HRESULT RendererImpl::HandleDeviceLost()
{ {
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_); KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_);

View File

@ -44,55 +44,55 @@ class KGE_API RendererImpl
public: public:
static RendererImpl& GetInstance(); static RendererImpl& GetInstance();
void CreateTexture(Texture& texture, String const& file_path); void CreateTexture(Texture& texture, String const& file_path) override;
void CreateTexture(Texture& texture, Resource const& resource); void CreateTexture(Texture& texture, Resource const& resource) override;
void CreateGifImage(GifImage& gif, String const& file_path); void CreateGifImage(GifImage& gif, String const& file_path) override;
void CreateGifImage(GifImage& gif, Resource const& resource); void CreateGifImage(GifImage& gif, Resource const& resource) override;
void CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, size_t frame_index); void CreateGifImageFrame(GifImage::Frame& frame, GifImage const& gif, size_t frame_index) override;
void CreateFontCollection(Font& font, String const& file_path); void CreateFontCollection(Font& font, String const& file_path) override;
void CreateFontCollection(Font& font, Resource const& res); void CreateFontCollection(Font& font, Resource const& res) override;
void CreateTextFormat(TextLayout& layout); void CreateTextFormat(TextLayout& layout) override;
void CreateTextLayout(TextLayout& layout); void CreateTextLayout(TextLayout& layout) override;
void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos); void CreateLineShape(Shape& shape, Point const& begin_pos, Point const& end_pos) override;
void CreateRectShape(Shape& shape, Rect const& rect); void CreateRectShape(Shape& shape, Rect const& rect) override;
void CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius); void CreateRoundedRectShape(Shape& shape, Rect const& rect, Vec2 const& radius) override;
void CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius); void CreateEllipseShape(Shape& shape, Point const& center, Vec2 const& radius) override;
void CreateShapeSink(ShapeSink& sink); void CreateShapeSink(ShapeSink& sink) override;
void CreateBrush(Brush& brush, Color const& color); void CreateBrush(Brush& brush, Color const& color) override;
void CreateBrush(Brush& brush, LinearGradientStyle const& style); void CreateBrush(Brush& brush, LinearGradientStyle const& style) override;
void CreateBrush(Brush& brush, RadialGradientStyle const& style); void CreateBrush(Brush& brush, RadialGradientStyle const& style) override;
void CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, LineJoinStyle line_join, const float* dash_array, void CreateStrokeStyle(StrokeStyle& stroke_style, CapStyle cap, LineJoinStyle line_join, const float* dash_array,
size_t dash_size, float dash_offset); size_t dash_size, float dash_offset) override;
TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr); TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) override;
public: public:
void BeginDraw(); void BeginDraw() override;
void EndDraw(); void EndDraw() override;
void Clear(); void Clear() override;
void Present(); void Present() override;
RenderContext& GetContext(); RenderContext& GetContext() override;
/// \~chinese /// \~chinese
/// @brief 获取Direct2D设备资源 /// @brief 获取Direct2D设备资源
@ -102,19 +102,18 @@ public:
/// @brief 获取Direct3D设备资源 /// @brief 获取Direct3D设备资源
ID3DDeviceResources* GetD3DDeviceResources(); ID3DDeviceResources* GetD3DDeviceResources();
public: /// \~chinese
void SetupModule() override; /// @brief 重设渲染输出大小
void Resize(uint32_t width, uint32_t height) override;
void DestroyModule() override; protected:
void HandleEvent(Event* evt) override;
private:
RendererImpl(); RendererImpl();
HRESULT HandleDeviceLost(); void MakeContextForWindow(WindowPtr window) override;
void Resize(uint32_t width, uint32_t height); void Destroy() override;
HRESULT HandleDeviceLost();
private: private:
RenderContextImplPtr render_ctx_; RenderContextImplPtr render_ctx_;

View File

@ -19,6 +19,8 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#include <kiwano/core/event/WindowEvent.h>
#include <kiwano/platform/Application.h>
namespace kiwano namespace kiwano
{ {
@ -29,4 +31,24 @@ Renderer::Renderer()
{ {
} }
void Renderer::SetupModule()
{
WindowPtr window = Application::GetInstance().GetMainWindow();
MakeContextForWindow(window);
}
void Renderer::DestroyModule()
{
Destroy();
}
void Renderer::HandleEvent(Event* evt)
{
if (evt->IsType<WindowResizedEvent>())
{
auto window_evt = dynamic_cast<WindowResizedEvent*>(evt);
Resize(window_evt->width, window_evt->height);
}
}
} // namespace kiwano } // namespace kiwano

View File

@ -25,13 +25,14 @@
#include <kiwano/render/TextStyle.hpp> #include <kiwano/render/TextStyle.hpp>
#include <kiwano/render/RenderContext.h> #include <kiwano/render/RenderContext.h>
#include <kiwano/render/TextureRenderContext.h> #include <kiwano/render/TextureRenderContext.h>
#include <kiwano/platform/Window.h>
namespace kiwano namespace kiwano
{ {
/** /**
* \~chinese * \~chinese
* \defgroup Render * \defgroup Render
*/ */
/** /**
@ -202,6 +203,14 @@ public:
virtual TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) = 0; virtual TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) = 0;
public: public:
/// \~chinese
/// @brief 获取渲染上下文
virtual RenderContext& GetContext() = 0;
/// \~chinese
/// @brief 获取渲染输出大小
virtual Size GetOutputSize() const;
/// \~chinese /// \~chinese
/// @brief 开始渲染 /// @brief 开始渲染
virtual void BeginDraw() = 0; virtual void BeginDraw() = 0;
@ -220,20 +229,27 @@ public:
virtual void Present() = 0; virtual void Present() = 0;
/// \~chinese /// \~chinese
/// @brief 获取渲染上下文 /// @brief 重设渲染输出大小
virtual RenderContext& GetContext() = 0; virtual void Resize(uint32_t width, uint32_t height) = 0;
/// \~chinese public:
/// @brief 获取渲染输出大小 void SetupModule() override;
virtual Size GetOutputSize() const;
void DestroyModule() override;
void HandleEvent(Event* evt) override;
protected: protected:
Renderer(); Renderer();
virtual void MakeContextForWindow(WindowPtr window) = 0;
virtual void Destroy() = 0;
protected: protected:
bool vsync_; bool vsync_;
Color clear_color_; Color clear_color_;
Size output_size_; Size output_size_;
}; };
/** @} */ /** @} */