Magic_Game/src/kiwano/renderer/RenderContext.cpp

530 lines
13 KiB
C++
Raw Normal View History

2019-08-16 00:50:54 +08:00
// Copyright (c) 2016-2019 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.
2020-01-10 15:22:12 +08:00
#include <kiwano/renderer/RenderContext.h>
2019-12-28 22:04:08 +08:00
#include <kiwano/core/Logger.h>
2019-08-16 00:50:54 +08:00
namespace kiwano
{
//
2020-01-10 15:22:12 +08:00
// RenderContext
2019-08-16 00:50:54 +08:00
//
2020-01-10 15:22:12 +08:00
RenderContext::RenderContext()
2019-12-27 23:42:51 +08:00
: collecting_status_(false)
2019-08-21 12:47:19 +08:00
, fast_global_transform_(true)
, brush_opacity_(1.0f)
2019-08-21 16:33:41 +08:00
, antialias_(true)
, text_antialias_(TextAntialiasMode::GrayScale)
2019-08-16 00:50:54 +08:00
{
status_.primitives = 0;
}
2020-01-10 15:22:12 +08:00
HRESULT RenderContext::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> ctx)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
if (!factory || !ctx)
2019-12-28 22:04:08 +08:00
return E_INVALIDARG;
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_ = ctx;
2019-12-28 22:04:08 +08:00
text_renderer_.reset();
current_brush_.reset();
HRESULT hr = ITextRenderer::Create(
&text_renderer_,
2020-01-10 15:22:12 +08:00
render_ctx_.get()
2019-12-28 22:04:08 +08:00
);
2019-08-16 00:50:54 +08:00
if (SUCCEEDED(hr))
{
2019-12-28 22:04:08 +08:00
SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_);
Resize(reinterpret_cast<const Size&>(GetRenderTarget()->GetSize()));
2019-08-16 00:50:54 +08:00
}
return hr;
}
2020-01-10 15:22:12 +08:00
void RenderContext::DiscardDeviceResources()
2019-08-20 19:32:36 +08:00
{
text_renderer_.reset();
2020-01-10 15:22:12 +08:00
render_ctx_.reset();
2019-08-20 19:32:36 +08:00
current_brush_.reset();
}
2020-01-10 15:22:12 +08:00
bool RenderContext::IsValid() const
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
return render_ctx_ != nullptr;
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::BeginDraw()
2019-08-16 00:50:54 +08:00
{
if (collecting_status_)
{
status_.start = Time::Now();
status_.primitives = 0;
}
2020-01-10 15:22:12 +08:00
if (render_ctx_)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
render_ctx_->BeginDraw();
2019-08-16 00:50:54 +08:00
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::EndDraw()
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
win32::ThrowIfFailed( render_ctx_->EndDraw() );
2019-08-16 00:50:54 +08:00
if (collecting_status_)
{
status_.duration = Time::Now() - status_.start;
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawGeometry(Geometry const& geometry, float stroke_width, const StrokeStyle& stroke)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
if (geometry.IsValid())
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
render_ctx_->DrawGeometry(
2019-08-16 00:50:54 +08:00
geometry.GetGeometry().get(),
2019-12-27 23:42:51 +08:00
current_brush_->GetBrush().get(),
2019-08-16 00:50:54 +08:00
stroke_width,
2020-01-10 11:43:07 +08:00
stroke.GetStrokeStyle().get()
2019-08-16 00:50:54 +08:00
);
IncreasePrimitivesCount();
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::FillGeometry(Geometry const& geometry)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
if (geometry.IsValid())
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
render_ctx_->FillGeometry(
2019-08-16 00:50:54 +08:00
geometry.GetGeometry().get(),
2019-12-27 23:42:51 +08:00
current_brush_->GetBrush().get()
2019-08-16 00:50:54 +08:00
);
2019-10-14 10:43:11 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawLine(Point const& point1, Point const& point2, float stroke_width, const StrokeStyle& stroke)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->DrawLine(
2019-12-28 22:04:08 +08:00
DX::ConvertToPoint2F(point1),
DX::ConvertToPoint2F(point2),
current_brush_->GetBrush().get(),
stroke_width,
2020-01-10 11:43:07 +08:00
stroke.GetStrokeStyle().get()
2019-12-28 22:04:08 +08:00
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawRectangle(Rect const& rect, float stroke_width, const StrokeStyle& stroke)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->DrawRectangle(
2019-12-28 22:04:08 +08:00
DX::ConvertToRectF(rect),
current_brush_->GetBrush().get(),
stroke_width,
2020-01-10 11:43:07 +08:00
stroke.GetStrokeStyle().get()
2019-12-28 22:04:08 +08:00
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::FillRectangle(Rect const& rect)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-10-14 10:43:11 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->FillRectangle(
2019-12-28 22:04:08 +08:00
DX::ConvertToRectF(rect),
current_brush_->GetBrush().get()
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, float stroke_width, const StrokeStyle& stroke)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->DrawRoundedRectangle(
2019-12-28 22:04:08 +08:00
D2D1::RoundedRect(
DX::ConvertToRectF(rect),
radius.x,
radius.y
),
current_brush_->GetBrush().get(),
stroke_width,
2020-01-10 11:43:07 +08:00
stroke.GetStrokeStyle().get()
2019-12-28 22:04:08 +08:00
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::FillRoundedRectangle(Rect const& rect, Vec2 const& radius)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->FillRoundedRectangle(
2019-12-28 22:04:08 +08:00
D2D1::RoundedRect(
DX::ConvertToRectF(rect),
radius.x,
radius.y
),
current_brush_->GetBrush().get()
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, const StrokeStyle& stroke)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->DrawEllipse(
2019-12-28 22:04:08 +08:00
D2D1::Ellipse(
DX::ConvertToPoint2F(center),
radius.x,
radius.y
),
current_brush_->GetBrush().get(),
stroke_width,
2020-01-10 11:43:07 +08:00
stroke.GetStrokeStyle().get()
2019-12-28 22:04:08 +08:00
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::FillEllipse(Point const& center, Vec2 const& radius)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->FillEllipse(
2019-12-28 22:04:08 +08:00
D2D1::Ellipse(
DX::ConvertToPoint2F(center),
radius.x,
radius.y
),
current_brush_->GetBrush().get()
);
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
IncreasePrimitivesCount();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect)
2019-08-16 00:50:54 +08:00
{
DrawTexture(texture, &src_rect, &dest_rect);
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
if (texture.IsValid())
2019-08-16 00:50:54 +08:00
{
2019-12-26 19:25:43 +08:00
auto mode = (texture.GetBitmapInterpolationMode() == InterpolationMode::Linear)
2019-08-21 16:33:41 +08:00
? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
: D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
2020-01-10 15:22:12 +08:00
render_ctx_->DrawBitmap(
2019-12-26 19:25:43 +08:00
texture.GetBitmap().get(),
2019-08-16 00:50:54 +08:00
dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr,
brush_opacity_,
2019-08-21 16:33:41 +08:00
mode,
2019-08-16 00:50:54 +08:00
src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr
);
IncreasePrimitivesCount();
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::DrawTextLayout(TextLayout const& layout, Point const& offset)
2019-08-16 00:50:54 +08:00
{
2019-12-28 22:04:08 +08:00
KGE_ASSERT(text_renderer_ && "Text renderer has not been initialized!");
2019-08-16 00:50:54 +08:00
if (layout.IsValid())
{
ComPtr<ID2D1Brush> fill_brush;
ComPtr<ID2D1Brush> outline_brush;
const TextStyle& style = layout.GetStyle();
2019-08-27 15:29:32 +08:00
if (style.fill_brush)
{
fill_brush = style.fill_brush->GetBrush();
fill_brush->SetOpacity(brush_opacity_);
}
2019-08-16 00:50:54 +08:00
if (style.outline_brush)
{
outline_brush = style.outline_brush->GetBrush();
outline_brush->SetOpacity(brush_opacity_);
}
HRESULT hr = text_renderer_->DrawTextLayout(
layout.GetTextLayout().get(),
offset.x,
offset.y,
fill_brush.get(),
outline_brush.get(),
style.outline_width,
2020-01-10 11:43:07 +08:00
style.outline_stroke.GetStrokeStyle().get()
);
if (SUCCEEDED(hr))
{
IncreasePrimitivesCount(text_renderer_->GetLastPrimitivesCount());
}
else
{
KGE_ERROR(L"Failed to draw text layout with HRESULT of %08X", hr);
}
2019-12-28 22:04:08 +08:00
}
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::CreateTexture(Texture& texture, math::Vec2T<uint32_t> size, D2D1_PIXEL_FORMAT format)
2019-12-27 10:51:34 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-27 10:51:34 +08:00
2019-12-28 22:04:08 +08:00
ComPtr<ID2D1Bitmap> saved_bitmap;
2020-01-10 15:22:12 +08:00
HRESULT hr = render_ctx_->CreateBitmap(
2019-12-28 22:04:08 +08:00
D2D1::SizeU(size.x, size.y),
D2D1::BitmapProperties(format),
&saved_bitmap
);
2019-12-27 10:51:34 +08:00
if (SUCCEEDED(hr))
{
2019-12-28 22:04:08 +08:00
texture.SetBitmap(saved_bitmap);
2019-08-16 00:50:54 +08:00
}
2019-12-28 22:04:08 +08:00
else
2019-08-16 00:50:54 +08:00
{
2019-12-30 14:24:29 +08:00
win32::ThrowIfFailed(hr);
2019-08-16 00:50:54 +08:00
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::PushClipRect(Rect const& clip_rect)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_ctx_->PushAxisAlignedClip(
2019-12-28 22:04:08 +08:00
DX::ConvertToRectF(clip_rect),
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
);
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::PopClipRect()
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_ctx_->PopAxisAlignedClip();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::PushLayer(LayerArea& layer)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-08-20 19:32:36 +08:00
if (!layer.IsValid())
{
2019-12-28 22:04:08 +08:00
ComPtr<ID2D1Layer> output;
2020-01-10 15:22:12 +08:00
HRESULT hr = render_ctx_->CreateLayer(&output);
2019-12-28 22:04:08 +08:00
if (SUCCEEDED(hr))
{
layer.SetLayer(output);
}
else
{
2019-12-30 14:24:29 +08:00
win32::ThrowIfFailed(hr);
2019-12-28 22:04:08 +08:00
}
2019-08-20 19:32:36 +08:00
}
2019-12-28 22:04:08 +08:00
if (layer.IsValid())
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
render_ctx_->PushLayer(
2019-08-16 00:50:54 +08:00
D2D1::LayerParameters(
2019-08-16 10:12:34 +08:00
DX::ConvertToRectF(layer.GetAreaRect()),
layer.GetMaskGeometry().GetGeometry().get(),
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED,
2019-08-20 19:32:36 +08:00
DX::ConvertToMatrix3x2F(layer.GetMaskTransform()),
2019-08-16 10:12:34 +08:00
layer.GetOpacity(),
2019-08-16 00:50:54 +08:00
nullptr,
D2D1_LAYER_OPTIONS_NONE
),
2019-08-16 10:12:34 +08:00
layer.GetLayer().get()
2019-08-16 00:50:54 +08:00
);
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::PopLayer()
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_ctx_->PopLayer();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::Clear()
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_ctx_->Clear();
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::Clear(Color const& clear_color)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_ctx_->Clear(DX::ConvertToColorF(clear_color));
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::SetTransform(const Matrix3x2& matrix)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
if (fast_global_transform_)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
2019-08-16 00:50:54 +08:00
}
2019-12-28 22:04:08 +08:00
else
2019-08-16 00:50:54 +08:00
{
2019-12-28 22:04:08 +08:00
Matrix3x2 result = matrix * global_transform_;
2020-01-10 15:22:12 +08:00
render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&result));
2019-08-16 00:50:54 +08:00
}
}
2020-01-10 15:22:12 +08:00
void RenderContext::SetGlobalTransform(const Matrix3x2* matrix)
2019-08-21 12:47:19 +08:00
{
if (matrix)
{
global_transform_ = *matrix;
fast_global_transform_ = false;
}
else
{
fast_global_transform_ = true;
}
2019-08-20 23:51:12 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::SetAntialiasMode(bool enabled)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-08-16 00:50:54 +08:00
2020-01-10 15:22:12 +08:00
render_ctx_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED);
2019-12-28 22:04:08 +08:00
antialias_ = enabled;
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::SetTextAntialiasMode(TextAntialiasMode mode)
2019-08-16 00:50:54 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-08-16 00:50:54 +08:00
2019-12-28 22:04:08 +08:00
D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
switch (mode)
2019-08-16 00:50:54 +08:00
{
2019-12-28 22:04:08 +08:00
case TextAntialiasMode::Default:
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
break;
case TextAntialiasMode::ClearType:
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
break;
case TextAntialiasMode::GrayScale:
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
break;
case TextAntialiasMode::None:
antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
break;
default:
break;
2019-08-16 00:50:54 +08:00
}
2019-12-28 22:04:08 +08:00
text_antialias_ = mode;
2020-01-10 15:22:12 +08:00
render_ctx_->SetTextAntialiasMode(antialias_mode);
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
bool RenderContext::CheckVisibility(Rect const& bounds, Matrix3x2 const& transform)
2019-08-20 19:32:36 +08:00
{
2020-01-10 15:22:12 +08:00
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
2019-12-28 22:04:08 +08:00
2019-08-21 12:47:19 +08:00
if (fast_global_transform_)
{
2019-12-28 22:04:08 +08:00
return visible_size_.Intersects(transform.Transform(bounds));
2019-08-21 12:47:19 +08:00
}
2019-12-28 22:04:08 +08:00
return visible_size_.Intersects(Matrix3x2(transform * global_transform_).Transform(bounds));
}
2020-01-10 15:22:12 +08:00
void RenderContext::Resize(Size const& size)
2019-12-28 22:04:08 +08:00
{
visible_size_ = Rect(Point(), size);
2019-08-20 19:32:36 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::SetCollectingStatus(bool enable)
2019-08-16 00:50:54 +08:00
{
2019-12-30 10:00:24 +08:00
collecting_status_ = enable;
2019-08-16 00:50:54 +08:00
}
2020-01-10 15:22:12 +08:00
void RenderContext::IncreasePrimitivesCount(uint32_t increase) const
2019-08-16 00:50:54 +08:00
{
if (collecting_status_)
{
status_.primitives += increase;
2019-08-16 00:50:54 +08:00
}
}
//
2020-01-10 15:22:12 +08:00
// TextureRenderContext
2019-08-16 00:50:54 +08:00
//
2020-01-10 15:22:12 +08:00
TextureRenderContext::TextureRenderContext()
2019-08-16 00:50:54 +08:00
{
}
2020-01-10 15:22:12 +08:00
bool TextureRenderContext::GetOutput(Texture& texture)
2019-08-16 00:50:54 +08:00
{
HRESULT hr = E_FAIL;
2019-12-27 10:51:34 +08:00
if (bitmap_rt_)
2019-08-16 00:50:54 +08:00
{
2019-12-27 10:51:34 +08:00
ComPtr<ID2D1Bitmap> bitmap;
2019-12-27 23:42:51 +08:00
hr = bitmap_rt_->GetBitmap(&bitmap);
2019-08-16 00:50:54 +08:00
2019-08-20 19:32:36 +08:00
if (SUCCEEDED(hr))
{
2019-12-27 23:42:51 +08:00
texture.SetBitmap(bitmap);
2019-08-20 19:32:36 +08:00
}
2019-08-16 00:50:54 +08:00
}
2019-12-27 23:42:51 +08:00
return SUCCEEDED(hr);
2019-08-16 00:50:54 +08:00
}
}