[deploy] Separating Renderer from the RenderContext
This commit is contained in:
parent
dff97d8249
commit
9ea6781f0e
5
Doxyfile
5
Doxyfile
|
|
@ -56,7 +56,10 @@ EXCLUDE = src/3rd-party \
|
|||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = YES
|
||||
PREDEFINED = KGE_API= \
|
||||
KGE_DOXYGEN_DO_NOT_INCLUDE=
|
||||
KGE_DOXYGEN_DO_NOT_INCLUDE= \
|
||||
_Out_= \
|
||||
_In_= \
|
||||
_In_opt_=
|
||||
|
||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||
# contain include files that are not input files but should be processed by the
|
||||
|
|
|
|||
|
|
@ -90,12 +90,23 @@ void ImGuiModule::OnUpdate(Duration dt)
|
|||
|
||||
void ImGuiModule::BeforeRender()
|
||||
{
|
||||
NewFrame();
|
||||
ImGui_Impl_NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
Size display_size = Renderer::Instance().GetOutputSize();
|
||||
io.DisplaySize = ImVec2(display_size.x, display_size.y);
|
||||
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void ImGuiModule::AfterRender()
|
||||
{
|
||||
Render();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void ImGuiModule::HandleEvent(Event* evt)
|
||||
|
|
@ -157,27 +168,6 @@ void ImGuiModule::HandleEvent(Event* evt)
|
|||
}
|
||||
}
|
||||
|
||||
void ImGuiModule::NewFrame()
|
||||
{
|
||||
ImGui_Impl_NewFrame();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
Size display_size = Renderer::Instance().GetOutputSize();
|
||||
io.DisplaySize = ImVec2(display_size.x, display_size.y);
|
||||
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void ImGuiModule::Render()
|
||||
{
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_Impl_RenderDrawData(ImGui::GetDrawData());
|
||||
}
|
||||
|
||||
void ImGuiModule::UpdateMousePos()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
|
|
|||
|
|
@ -54,10 +54,6 @@ public:
|
|||
void OnUpdate(Duration dt) override;
|
||||
|
||||
private:
|
||||
void NewFrame();
|
||||
|
||||
void Render();
|
||||
|
||||
void UpdateMousePos();
|
||||
|
||||
void UpdateMouseCursor();
|
||||
|
|
|
|||
|
|
@ -104,10 +104,11 @@ void DebugActor::OnUpdate(Duration dt)
|
|||
}
|
||||
#endif
|
||||
|
||||
ss << "Render: " << Renderer::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl;
|
||||
const auto& status = Renderer::Instance().GetContext().GetStatus();
|
||||
|
||||
ss << "Primitives / sec: " << std::fixed << Renderer::Instance().GetStatus().primitives * frame_time_.size()
|
||||
<< std::endl;
|
||||
ss << "Render: " << status.duration.Milliseconds() << "ms" << std::endl;
|
||||
|
||||
ss << "Primitives / sec: " << std::fixed << status.primitives * frame_time_.size() << std::endl;
|
||||
|
||||
ss << "Memory: ";
|
||||
{
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void Application::Run(bool debug)
|
|||
if (debug)
|
||||
{
|
||||
Director::Instance().ShowDebugInfo(true);
|
||||
Renderer::Instance().SetCollectingStatus(true);
|
||||
Renderer::Instance().GetContext().SetCollectingStatus(true);
|
||||
}
|
||||
|
||||
// Everything is ready
|
||||
|
|
@ -185,6 +185,9 @@ void Application::Update()
|
|||
|
||||
void Application::Render()
|
||||
{
|
||||
Renderer& renderer = Renderer::Instance();
|
||||
renderer.Clear();
|
||||
|
||||
// Before render
|
||||
for (auto c : render_comps_)
|
||||
{
|
||||
|
|
@ -192,17 +195,20 @@ void Application::Render()
|
|||
}
|
||||
|
||||
// Rendering
|
||||
Renderer& renderer = Renderer::Instance();
|
||||
renderer.BeginDraw();
|
||||
for (auto c : render_comps_)
|
||||
{
|
||||
c->OnRender(renderer);
|
||||
c->OnRender(renderer.GetContext());
|
||||
}
|
||||
renderer.EndDraw();
|
||||
|
||||
// After render
|
||||
for (auto rit = render_comps_.rbegin(); rit != render_comps_.rend(); ++rit)
|
||||
{
|
||||
(*rit)->AfterRender();
|
||||
}
|
||||
|
||||
renderer.Present();
|
||||
}
|
||||
|
||||
void Application::DispatchEvent(Event* evt)
|
||||
|
|
|
|||
|
|
@ -234,7 +234,8 @@ HRESULT D2DDeviceResources::CreateDeviceResources(_In_ ComPtr<IDXGIDevice> dxgi_
|
|||
|
||||
// Create the Direct2D device object and a corresponding context.
|
||||
ComPtr<ID2D1Device> device;
|
||||
HRESULT hr = factory_->CreateDevice(dxgi_device.get(), &device);
|
||||
|
||||
HRESULT hr = factory_->CreateDevice(dxgi_device.get(), &device);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -261,7 +262,8 @@ HRESULT D2DDeviceResources::CreateWindowSizeDependentResources()
|
|||
// Create a Direct2D target bitmap associated with the
|
||||
// swap chain back buffer and set it as the current target.
|
||||
ComPtr<IDXGISurface> dxgi_back_buffer;
|
||||
HRESULT hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
HRESULT hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -342,7 +344,8 @@ HRESULT D2DDeviceResources::CreateBitmapFromConverter(_Out_ ComPtr<ID2D1Bitmap>&
|
|||
return E_UNEXPECTED;
|
||||
|
||||
ComPtr<ID2D1Bitmap> output;
|
||||
HRESULT hr = device_context_->CreateBitmapFromWicBitmap(converter.get(), properties, &output);
|
||||
|
||||
HRESULT hr = device_context_->CreateBitmapFromWicBitmap(converter.get(), properties, &output);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -358,7 +361,8 @@ HRESULT D2DDeviceResources::CreateBitmapDecoderFromFile(_Out_ ComPtr<IWICBitmapD
|
|||
return E_UNEXPECTED;
|
||||
|
||||
ComPtr<IWICBitmapDecoder> decoder_output;
|
||||
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(file_path.c_str(), nullptr, GENERIC_READ,
|
||||
|
||||
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(file_path.c_str(), nullptr, GENERIC_READ,
|
||||
WICDecodeMetadataCacheOnLoad, &decoder_output);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ HRESULT RenderContext::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPt
|
|||
if (!factory || !ctx)
|
||||
return E_INVALIDARG;
|
||||
|
||||
render_ctx_ = ctx;
|
||||
render_target_ = ctx;
|
||||
text_renderer_.reset();
|
||||
current_brush_.reset();
|
||||
|
||||
HRESULT hr = ITextRenderer::Create(&text_renderer_, render_ctx_.get());
|
||||
HRESULT hr = ITextRenderer::Create(&text_renderer_, render_target_.get());
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -56,19 +56,25 @@ HRESULT RenderContext::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPt
|
|||
Resize(reinterpret_cast<const Size&>(GetRenderTarget()->GetSize()));
|
||||
}
|
||||
|
||||
// DrawingStateBlock
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = factory->CreateDrawingStateBlock(&drawing_state_);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void RenderContext::DiscardDeviceResources()
|
||||
{
|
||||
text_renderer_.reset();
|
||||
render_ctx_.reset();
|
||||
render_target_.reset();
|
||||
current_brush_.reset();
|
||||
}
|
||||
|
||||
bool RenderContext::IsValid() const
|
||||
{
|
||||
return render_ctx_ != nullptr;
|
||||
return render_target_ != nullptr;
|
||||
}
|
||||
|
||||
void RenderContext::BeginDraw()
|
||||
|
|
@ -79,15 +85,15 @@ void RenderContext::BeginDraw()
|
|||
status_.primitives = 0;
|
||||
}
|
||||
|
||||
if (render_ctx_)
|
||||
if (render_target_)
|
||||
{
|
||||
render_ctx_->BeginDraw();
|
||||
render_target_->BeginDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::EndDraw()
|
||||
{
|
||||
win32::ThrowIfFailed(render_ctx_->EndDraw());
|
||||
win32::ThrowIfFailed(render_target_->EndDraw());
|
||||
|
||||
if (collecting_status_)
|
||||
{
|
||||
|
|
@ -97,12 +103,12 @@ void RenderContext::EndDraw()
|
|||
|
||||
void RenderContext::DrawGeometry(Geometry const& geometry, float stroke_width, const StrokeStyle& stroke)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
if (geometry.IsValid())
|
||||
{
|
||||
render_ctx_->DrawGeometry(geometry.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width,
|
||||
render_target_->DrawGeometry(geometry.GetGeometry().get(), current_brush_->GetBrush().get(), stroke_width,
|
||||
stroke.GetStrokeStyle().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -111,12 +117,12 @@ void RenderContext::DrawGeometry(Geometry const& geometry, float stroke_width, c
|
|||
|
||||
void RenderContext::FillGeometry(Geometry const& geometry)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
if (geometry.IsValid())
|
||||
{
|
||||
render_ctx_->FillGeometry(geometry.GetGeometry().get(), current_brush_->GetBrush().get());
|
||||
render_target_->FillGeometry(geometry.GetGeometry().get(), current_brush_->GetBrush().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
}
|
||||
|
|
@ -124,10 +130,10 @@ void RenderContext::FillGeometry(Geometry const& geometry)
|
|||
|
||||
void RenderContext::DrawLine(Point const& point1, Point const& point2, float stroke_width, const StrokeStyle& stroke)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), current_brush_->GetBrush().get(),
|
||||
render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), current_brush_->GetBrush().get(),
|
||||
stroke_width, stroke.GetStrokeStyle().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -135,10 +141,10 @@ void RenderContext::DrawLine(Point const& point1, Point const& point2, float str
|
|||
|
||||
void RenderContext::DrawRectangle(Rect const& rect, float stroke_width, const StrokeStyle& stroke)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width,
|
||||
render_target_->DrawRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get(), stroke_width,
|
||||
stroke.GetStrokeStyle().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -146,10 +152,10 @@ void RenderContext::DrawRectangle(Rect const& rect, float stroke_width, const St
|
|||
|
||||
void RenderContext::FillRectangle(Rect const& rect)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->FillRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get());
|
||||
render_target_->FillRectangle(DX::ConvertToRectF(rect), current_brush_->GetBrush().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
}
|
||||
|
|
@ -157,10 +163,10 @@ void RenderContext::FillRectangle(Rect const& rect)
|
|||
void RenderContext::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, float stroke_width,
|
||||
const StrokeStyle& stroke)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
|
||||
render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
|
||||
current_brush_->GetBrush().get(), stroke_width, stroke.GetStrokeStyle().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -168,10 +174,10 @@ void RenderContext::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, f
|
|||
|
||||
void RenderContext::FillRoundedRectangle(Rect const& rect, Vec2 const& radius)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
|
||||
render_target_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y),
|
||||
current_brush_->GetBrush().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -179,10 +185,10 @@ void RenderContext::FillRoundedRectangle(Rect const& rect, Vec2 const& radius)
|
|||
|
||||
void RenderContext::DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, const StrokeStyle& stroke)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
|
||||
render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
|
||||
current_brush_->GetBrush().get(), stroke_width, stroke.GetStrokeStyle().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -190,10 +196,10 @@ void RenderContext::DrawEllipse(Point const& center, Vec2 const& radius, float s
|
|||
|
||||
void RenderContext::FillEllipse(Point const& center, Vec2 const& radius)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
|
||||
|
||||
render_ctx_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
|
||||
render_target_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y),
|
||||
current_brush_->GetBrush().get());
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -206,7 +212,7 @@ void RenderContext::DrawTexture(Texture const& texture, Rect const& src_rect, Re
|
|||
|
||||
void RenderContext::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
if (texture.IsValid())
|
||||
{
|
||||
|
|
@ -214,7 +220,7 @@ void RenderContext::DrawTexture(Texture const& texture, const Rect* src_rect, co
|
|||
? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
|
||||
: D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
|
||||
|
||||
render_ctx_->DrawBitmap(texture.GetBitmap().get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
|
||||
render_target_->DrawBitmap(texture.GetBitmap().get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
|
||||
brush_opacity_, mode, src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr);
|
||||
|
||||
IncreasePrimitivesCount();
|
||||
|
|
@ -260,10 +266,10 @@ void RenderContext::DrawTextLayout(TextLayout const& layout, Point const& offset
|
|||
|
||||
void RenderContext::CreateTexture(Texture& texture, math::Vec2T<uint32_t> size, D2D1_PIXEL_FORMAT format)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
ComPtr<ID2D1Bitmap> saved_bitmap;
|
||||
HRESULT hr = render_ctx_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(format), &saved_bitmap);
|
||||
HRESULT hr = render_target_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(format), &saved_bitmap);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -277,24 +283,24 @@ void RenderContext::CreateTexture(Texture& texture, math::Vec2T<uint32_t> size,
|
|||
|
||||
void RenderContext::PushClipRect(Rect const& clip_rect)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
render_ctx_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect),
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
render_target_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect),
|
||||
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
}
|
||||
|
||||
void RenderContext::PopClipRect()
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
render_ctx_->PopAxisAlignedClip();
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
render_target_->PopAxisAlignedClip();
|
||||
}
|
||||
|
||||
void RenderContext::PushLayer(LayerArea& layer)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
if (!layer.IsValid())
|
||||
{
|
||||
ComPtr<ID2D1Layer> output;
|
||||
HRESULT hr = render_ctx_->CreateLayer(&output);
|
||||
HRESULT hr = render_target_->CreateLayer(&output);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -308,7 +314,7 @@ void RenderContext::PushLayer(LayerArea& layer)
|
|||
|
||||
if (layer.IsValid())
|
||||
{
|
||||
render_ctx_->PushLayer(
|
||||
render_target_->PushLayer(
|
||||
D2D1::LayerParameters(DX::ConvertToRectF(layer.GetAreaRect()), layer.GetMaskGeometry().GetGeometry().get(),
|
||||
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED,
|
||||
DX::ConvertToMatrix3x2F(layer.GetMaskTransform()), layer.GetOpacity(), nullptr,
|
||||
|
|
@ -319,34 +325,34 @@ void RenderContext::PushLayer(LayerArea& layer)
|
|||
|
||||
void RenderContext::PopLayer()
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
render_ctx_->PopLayer();
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
render_target_->PopLayer();
|
||||
}
|
||||
|
||||
void RenderContext::Clear()
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
render_ctx_->Clear();
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
render_target_->Clear();
|
||||
}
|
||||
|
||||
void RenderContext::Clear(Color const& clear_color)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
render_ctx_->Clear(DX::ConvertToColorF(clear_color));
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
render_target_->Clear(DX::ConvertToColorF(clear_color));
|
||||
}
|
||||
|
||||
void RenderContext::SetTransform(const Matrix3x2& matrix)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
if (fast_global_transform_)
|
||||
{
|
||||
render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
|
||||
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
|
||||
}
|
||||
else
|
||||
{
|
||||
Matrix3x2 result = matrix * global_transform_;
|
||||
render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&result));
|
||||
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -365,15 +371,15 @@ void RenderContext::SetGlobalTransform(const Matrix3x2* matrix)
|
|||
|
||||
void RenderContext::SetAntialiasMode(bool enabled)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
render_ctx_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
render_target_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED);
|
||||
antialias_ = enabled;
|
||||
}
|
||||
|
||||
void RenderContext::SetTextAntialiasMode(TextAntialiasMode mode)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
|
||||
switch (mode)
|
||||
|
|
@ -395,12 +401,12 @@ void RenderContext::SetTextAntialiasMode(TextAntialiasMode mode)
|
|||
}
|
||||
|
||||
text_antialias_ = mode;
|
||||
render_ctx_->SetTextAntialiasMode(antialias_mode);
|
||||
render_target_->SetTextAntialiasMode(antialias_mode);
|
||||
}
|
||||
|
||||
bool RenderContext::CheckVisibility(Rect const& bounds, Matrix3x2 const& transform)
|
||||
{
|
||||
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
|
||||
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
|
||||
|
||||
if (fast_global_transform_)
|
||||
{
|
||||
|
|
@ -427,6 +433,26 @@ void RenderContext::IncreasePrimitivesCount(uint32_t increase) const
|
|||
}
|
||||
}
|
||||
|
||||
void RenderContext::SaveDrawingState()
|
||||
{
|
||||
KGE_ASSERT(IsValid());
|
||||
|
||||
if (drawing_state_)
|
||||
{
|
||||
render_target_->SaveDrawingState(drawing_state_.get());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderContext::RestoreDrawingState()
|
||||
{
|
||||
KGE_ASSERT(IsValid());
|
||||
|
||||
if (drawing_state_)
|
||||
{
|
||||
render_target_->RestoreDrawingState(drawing_state_.get());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// TextureRenderContext
|
||||
//
|
||||
|
|
|
|||
|
|
@ -238,19 +238,28 @@ private:
|
|||
/// @brief 增加渲染图元数量
|
||||
void IncreasePrimitivesCount(uint32_t increase = 1) const;
|
||||
|
||||
private:
|
||||
bool antialias_;
|
||||
bool fast_global_transform_;
|
||||
float brush_opacity_;
|
||||
TextAntialiasMode text_antialias_;
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1RenderTarget> render_ctx_;
|
||||
BrushPtr current_brush_;
|
||||
Rect visible_size_;
|
||||
Matrix3x2 global_transform_;
|
||||
/// \~chinese
|
||||
/// @brief 保存绘制状态
|
||||
void SaveDrawingState();
|
||||
|
||||
mutable bool collecting_status_;
|
||||
mutable Status status_;
|
||||
/// \~chinese
|
||||
/// @brief 恢复绘制状态
|
||||
void RestoreDrawingState();
|
||||
|
||||
private:
|
||||
bool antialias_;
|
||||
bool fast_global_transform_;
|
||||
mutable bool collecting_status_;
|
||||
float brush_opacity_;
|
||||
TextAntialiasMode text_antialias_;
|
||||
BrushPtr current_brush_;
|
||||
Rect visible_size_;
|
||||
Matrix3x2 global_transform_;
|
||||
mutable Status status_;
|
||||
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1RenderTarget> render_target_;
|
||||
ComPtr<ID2D1DrawingStateBlock> drawing_state_;
|
||||
};
|
||||
|
||||
/// \~chinese
|
||||
|
|
@ -296,8 +305,8 @@ inline RenderContext::Status const& RenderContext::GetStatus() const
|
|||
|
||||
inline ComPtr<ID2D1RenderTarget> RenderContext::GetRenderTarget() const
|
||||
{
|
||||
KGE_ASSERT(render_ctx_);
|
||||
return render_ctx_;
|
||||
KGE_ASSERT(render_target_);
|
||||
return render_target_;
|
||||
}
|
||||
|
||||
inline ComPtr<ITextRenderer> RenderContext::GetTextRenderer() const
|
||||
|
|
|
|||
|
|
@ -45,9 +45,8 @@ void Renderer::SetupComponent()
|
|||
target_window_ = Window::Instance().GetHandle();
|
||||
output_size_ = Window::Instance().GetSize();
|
||||
|
||||
d2d_res_ = nullptr;
|
||||
d3d_res_ = nullptr;
|
||||
drawing_state_block_ = nullptr;
|
||||
d2d_res_ = nullptr;
|
||||
d3d_res_ = nullptr;
|
||||
|
||||
HRESULT hr = target_window_ ? S_OK : E_FAIL;
|
||||
|
||||
|
|
@ -61,16 +60,10 @@ void Renderer::SetupComponent()
|
|||
{
|
||||
hr = ID2DDeviceResources::Create(&d2d_res_, d3d_res_->GetDXGIDevice(), d3d_res_->GetDXGISwapChain());
|
||||
|
||||
// DrawingStateBlock
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d2d_res_->GetFactory()->CreateDrawingStateBlock(&drawing_state_block_);
|
||||
}
|
||||
|
||||
// Other device resources
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
|
||||
hr = render_ctx_.CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
|
||||
}
|
||||
|
||||
// FontFileLoader and FontCollectionLoader
|
||||
|
|
@ -116,7 +109,7 @@ void Renderer::DestroyComponent()
|
|||
{
|
||||
KGE_SYS_LOG(L"Destroying device resources");
|
||||
|
||||
DiscardDeviceResources();
|
||||
render_ctx_.DiscardDeviceResources();
|
||||
|
||||
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get());
|
||||
res_font_file_loader_.reset();
|
||||
|
|
@ -124,34 +117,39 @@ void Renderer::DestroyComponent()
|
|||
d2d_res_->GetDWriteFactory()->UnregisterFontCollectionLoader(res_font_collection_loader_.get());
|
||||
res_font_collection_loader_.reset();
|
||||
|
||||
drawing_state_block_.reset();
|
||||
d2d_res_.reset();
|
||||
d3d_res_.reset();
|
||||
|
||||
::CoUninitialize();
|
||||
}
|
||||
|
||||
void Renderer::BeforeRender()
|
||||
void Renderer::BeginDraw()
|
||||
{
|
||||
KGE_ASSERT(d3d_res_ && IsValid());
|
||||
KGE_ASSERT(render_ctx_.IsValid());
|
||||
|
||||
render_ctx_.SaveDrawingState();
|
||||
render_ctx_.BeginDraw();
|
||||
}
|
||||
|
||||
void Renderer::EndDraw()
|
||||
{
|
||||
KGE_ASSERT(render_ctx_.IsValid());
|
||||
|
||||
render_ctx_.EndDraw();
|
||||
render_ctx_.RestoreDrawingState();
|
||||
}
|
||||
|
||||
void Renderer::Clear()
|
||||
{
|
||||
KGE_ASSERT(d3d_res_);
|
||||
|
||||
HRESULT hr = d3d_res_->ClearRenderTarget(clear_color_);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
GetRenderTarget()->SaveDrawingState(drawing_state_block_.get());
|
||||
BeginDraw();
|
||||
}
|
||||
|
||||
win32::ThrowIfFailed(hr);
|
||||
}
|
||||
|
||||
void Renderer::AfterRender()
|
||||
void Renderer::Present()
|
||||
{
|
||||
KGE_ASSERT(d3d_res_ && IsValid());
|
||||
|
||||
EndDraw();
|
||||
GetRenderTarget()->RestoreDrawingState(drawing_state_block_.get());
|
||||
KGE_ASSERT(d3d_res_);
|
||||
|
||||
HRESULT hr = d3d_res_->Present(vsync_);
|
||||
|
||||
|
|
@ -175,7 +173,7 @@ void Renderer::HandleEvent(Event* evt)
|
|||
|
||||
HRESULT Renderer::HandleDeviceLost()
|
||||
{
|
||||
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_);
|
||||
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_.IsValid());
|
||||
|
||||
HRESULT hr = d3d_res_->HandleDeviceLost();
|
||||
|
||||
|
|
@ -186,7 +184,7 @@ HRESULT Renderer::HandleDeviceLost()
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
|
||||
hr = render_ctx_.CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
|
@ -939,7 +937,8 @@ void Renderer::ResizeTarget(uint32_t width, uint32_t height)
|
|||
{
|
||||
output_size_.x = static_cast<float>(width);
|
||||
output_size_.y = static_cast<float>(height);
|
||||
hr = d3d_res_->SetLogicalSize(output_size_);
|
||||
|
||||
hr = d3d_res_->SetLogicalSize(output_size_);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
@ -949,7 +948,7 @@ void Renderer::ResizeTarget(uint32_t width, uint32_t height)
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
Resize(reinterpret_cast<const Size&>(GetRenderTarget()->GetSize()));
|
||||
render_ctx_.Resize(output_size_);
|
||||
}
|
||||
|
||||
win32::ThrowIfFailed(hr);
|
||||
|
|
|
|||
|
|
@ -58,9 +58,7 @@ typedef ID3D11DeviceResources ID3DDeviceResources;
|
|||
*/
|
||||
class KGE_API Renderer
|
||||
: public Singleton<Renderer>
|
||||
, public RenderComponent
|
||||
, public EventComponent
|
||||
, public RenderContext
|
||||
{
|
||||
friend Singleton<Renderer>;
|
||||
|
||||
|
|
@ -201,6 +199,26 @@ public:
|
|||
size_t dash_size, float dash_offset);
|
||||
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 开始渲染
|
||||
void BeginDraw();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 结束渲染
|
||||
void EndDraw();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 清除绘制内容
|
||||
void Clear();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将绘制内容呈现至窗口
|
||||
void Present();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取渲染上下文
|
||||
RenderContext& GetContext();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief »ñȡĿ±ê´°¿Ú
|
||||
WindowHandle GetTargetWindow() const;
|
||||
|
|
@ -222,10 +240,6 @@ public:
|
|||
|
||||
void DestroyComponent() override;
|
||||
|
||||
void BeforeRender() override;
|
||||
|
||||
void AfterRender() override;
|
||||
|
||||
void HandleEvent(Event* evt) override;
|
||||
|
||||
private:
|
||||
|
|
@ -238,14 +252,14 @@ private:
|
|||
void ResizeTarget(uint32_t width, uint32_t height);
|
||||
|
||||
private:
|
||||
bool vsync_;
|
||||
WindowHandle target_window_;
|
||||
Color clear_color_;
|
||||
Size output_size_;
|
||||
bool vsync_;
|
||||
WindowHandle target_window_;
|
||||
Color clear_color_;
|
||||
Size output_size_;
|
||||
RenderContext render_ctx_;
|
||||
|
||||
ComPtr<ID2DDeviceResources> d2d_res_;
|
||||
ComPtr<ID3DDeviceResources> d3d_res_;
|
||||
ComPtr<ID2D1DrawingStateBlock> drawing_state_block_;
|
||||
ComPtr<IFontCollectionLoader> font_collection_loader_;
|
||||
ComPtr<IResourceFontFileLoader> res_font_file_loader_;
|
||||
ComPtr<IResourceFontCollectionLoader> res_font_collection_loader_;
|
||||
|
|
@ -268,6 +282,11 @@ inline Color const& Renderer::GetClearColor() const
|
|||
return clear_color_;
|
||||
}
|
||||
|
||||
inline RenderContext& Renderer::GetContext()
|
||||
{
|
||||
return render_ctx_;
|
||||
}
|
||||
|
||||
inline ID2DDeviceResources* Renderer::GetD2DDeviceResources()
|
||||
{
|
||||
KGE_ASSERT(d2d_res_);
|
||||
|
|
|
|||
Loading…
Reference in New Issue