Remove TextureRenderContext & add function to create a RenderContext from a texture

This commit is contained in:
Nomango 2020-02-20 18:22:52 +08:00
parent b9f1d47143
commit f71c5b9ff8
38 changed files with 263 additions and 589 deletions

View File

@ -83,7 +83,6 @@
<ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextureRenderContextImpl.h" />
<ClInclude Include="..\..\src\kiwano\render\Font.h" /> <ClInclude Include="..\..\src\kiwano\render\Font.h" />
<ClInclude Include="..\..\src\kiwano\render\NativeObject.h" /> <ClInclude Include="..\..\src\kiwano\render\NativeObject.h" />
<ClInclude Include="..\..\src\kiwano\render\Shape.h" /> <ClInclude Include="..\..\src\kiwano\render\Shape.h" />
@ -97,7 +96,6 @@
<ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp" /> <ClInclude Include="..\..\src\kiwano\render\TextStyle.hpp" />
<ClInclude Include="..\..\src\kiwano\render\Texture.h" /> <ClInclude Include="..\..\src\kiwano\render\Texture.h" />
<ClInclude Include="..\..\src\kiwano\render\TextureCache.h" /> <ClInclude Include="..\..\src\kiwano\render\TextureCache.h" />
<ClInclude Include="..\..\src\kiwano\render\TextureRenderContext.h" />
<ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" /> <ClInclude Include="..\..\src\kiwano\utils\LocalStorage.h" />
<ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" /> <ClInclude Include="..\..\src\kiwano\utils\ResourceCache.h" />
<ClInclude Include="..\..\src\kiwano\utils\UserData.h" /> <ClInclude Include="..\..\src\kiwano\utils\UserData.h" />
@ -159,7 +157,6 @@
<ClCompile Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.cpp" />
<ClCompile Include="..\..\src\kiwano\render\DirectX\RendererImpl.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\RendererImpl.cpp" />
<ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp" /> <ClCompile Include="..\..\src\kiwano\render\DirectX\TextRenderer.cpp" />
<ClCompile Include="..\..\src\kiwano\render\DirectX\TextureRenderContextImpl.cpp" />
<ClCompile Include="..\..\src\kiwano\render\Font.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Font.cpp" />
<ClCompile Include="..\..\src\kiwano\render\Shape.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Shape.cpp" />
<ClCompile Include="..\..\src\kiwano\render\ShapeMaker.cpp" /> <ClCompile Include="..\..\src\kiwano\render\ShapeMaker.cpp" />
@ -171,7 +168,6 @@
<ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp" /> <ClCompile Include="..\..\src\kiwano\render\TextLayout.cpp" />
<ClCompile Include="..\..\src\kiwano\render\Texture.cpp" /> <ClCompile Include="..\..\src\kiwano\render\Texture.cpp" />
<ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp" /> <ClCompile Include="..\..\src\kiwano\render\TextureCache.cpp" />
<ClCompile Include="..\..\src\kiwano\render\TextureRenderContext.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\LocalStorage.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\ResourceCache.cpp" />
<ClCompile Include="..\..\src\kiwano\utils\UserData.cpp" /> <ClCompile Include="..\..\src\kiwano\utils\UserData.cpp" />

View File

@ -270,15 +270,9 @@
<ClInclude Include="..\..\src\kiwano\math\Scalar.h"> <ClInclude Include="..\..\src\kiwano\math\Scalar.h">
<Filter>math</Filter> <Filter>math</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\render\TextureRenderContext.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h"> <ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextureRenderContextImpl.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<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>
@ -509,15 +503,9 @@
<ClCompile Include="..\..\src\kiwano\render\Shape.cpp"> <ClCompile Include="..\..\src\kiwano\render\Shape.cpp">
<Filter>render</Filter> <Filter>render</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\render\TextureRenderContext.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.cpp"> <ClCompile Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.cpp">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\TextureRenderContextImpl.cpp">
<Filter>render\DirectX</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\render\DirectX\RendererImpl.cpp"> <ClCompile Include="..\..\src\kiwano\render\DirectX\RendererImpl.cpp">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClCompile> </ClCompile>

View File

@ -42,7 +42,7 @@ KGE_DECLARE_SMART_PTR(Sound);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Sound : public virtual ObjectBase class KGE_API Sound : public ObjectBase
{ {
friend class AudioModule; friend class AudioModule;

View File

@ -37,7 +37,7 @@ KGE_DECLARE_SMART_PTR(SoundPlayer);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API SoundPlayer : public virtual ObjectBase class KGE_API SoundPlayer : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -51,7 +51,7 @@ enum class HttpType
* \~chinese * \~chinese
* @brief HTTP请求 * @brief HTTP请求
*/ */
class KGE_API HttpRequest : public virtual ObjectBase class KGE_API HttpRequest : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -36,7 +36,7 @@ KGE_DECLARE_SMART_PTR(HttpResponse);
* \~chinese * \~chinese
* @brief HTTP响应 * @brief HTTP响应
*/ */
class KGE_API HttpResponse : public virtual ObjectBase class KGE_API HttpResponse : public ObjectBase
{ {
public: public:
HttpResponse(HttpRequestPtr request); HttpResponse(HttpRequestPtr request);

View File

@ -36,7 +36,7 @@ KGE_DECLARE_SMART_PTR(Fixture);
/// \~chinese /// \~chinese
/// @brief 物理夹具 /// @brief 物理夹具
class Fixture : public virtual ObjectBase class KGE_API Fixture : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -45,7 +45,7 @@ KGE_DECLARE_SMART_PTR(WheelJoint);
/// \~chinese /// \~chinese
/// @brief 关节 /// @brief 关节
class KGE_API Joint : public virtual ObjectBase class KGE_API Joint : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -57,7 +57,7 @@ typedef IntrusiveList<ActorPtr> ActorList;
* *
*/ */
class KGE_API Actor class KGE_API Actor
: public virtual ObjectBase : public ObjectBase
, public TimerManager , public TimerManager
, public ActionManager , public ActionManager
, public EventDispatcher , public EventDispatcher

View File

@ -20,7 +20,6 @@
#include <kiwano/2d/Canvas.h> #include <kiwano/2d/Canvas.h>
#include <kiwano/core/Logger.h> #include <kiwano/core/Logger.h>
#include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
@ -32,11 +31,9 @@ CanvasPtr Canvas::Create(const Size& size)
{ {
try try
{ {
ptr->ctx_ = TextureRenderContext::Create();
ptr->stroke_brush_ = Brush::Create(Color::White); ptr->stroke_brush_ = Brush::Create(Color::White);
ptr->fill_brush_ = Brush::Create(Color::White); ptr->fill_brush_ = Brush::Create(Color::White);
ptr->ResizeAndClear(size);
ptr->SetSize(ptr->ctx_->GetSize());
} }
catch (std::exception) catch (std::exception)
{ {
@ -47,28 +44,24 @@ CanvasPtr Canvas::Create(const Size& size)
} }
Canvas::Canvas() Canvas::Canvas()
: cache_expired_(false)
{ {
} }
void Canvas::BeginDraw() void Canvas::BeginDraw()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->BeginDraw(); render_ctx_->BeginDraw();
} }
void Canvas::EndDraw() void Canvas::EndDraw()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->EndDraw(); render_ctx_->EndDraw();
cache_expired_ = true;
} }
void Canvas::OnRender(RenderContext& ctx) void Canvas::OnRender(RenderContext& ctx)
{ {
UpdateCache(); if (texture_cached_)
if (texture_cached_ && texture_cached_->IsValid())
{ {
PrepareToRender(ctx); PrepareToRender(ctx);
ctx.DrawTexture(*texture_cached_, nullptr, &GetBounds()); ctx.DrawTexture(*texture_cached_, nullptr, &GetBounds());
@ -77,156 +70,153 @@ void Canvas::OnRender(RenderContext& ctx)
void Canvas::SetBrush(BrushPtr brush) void Canvas::SetBrush(BrushPtr brush)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(brush); render_ctx_->SetCurrentBrush(brush);
} }
void Canvas::SetBrushTransform(const Transform& transform) void Canvas::SetBrushTransform(const Transform& transform)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetTransform(transform.ToMatrix()); render_ctx_->SetTransform(transform.ToMatrix());
} }
void Canvas::SetBrushTransform(const Matrix3x2& transform) void Canvas::SetBrushTransform(const Matrix3x2& transform)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetTransform(transform); render_ctx_->SetTransform(transform);
} }
void Canvas::PushLayer(LayerPtr layer) void Canvas::PushLayer(LayerPtr layer)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
if (layer) if (layer)
{ {
ctx_->PushLayer(*layer); render_ctx_->PushLayer(*layer);
} }
} }
void Canvas::PopLayer() void Canvas::PopLayer()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->PopLayer(); render_ctx_->PopLayer();
} }
void Canvas::PushClipRect(const Rect& clip_rect) void Canvas::PushClipRect(const Rect& clip_rect)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->PushClipRect(clip_rect); render_ctx_->PushClipRect(clip_rect);
} }
void Canvas::PopClipRect() void Canvas::PopClipRect()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->PopClipRect(); render_ctx_->PopClipRect();
} }
void Canvas::DrawShape(ShapePtr shape) void Canvas::DrawShape(ShapePtr shape)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
if (shape) if (shape)
{ {
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawShape(*shape); render_ctx_->DrawShape(*shape);
cache_expired_ = true;
} }
} }
void Canvas::DrawLine(const Point& begin, const Point& end) void Canvas::DrawLine(const Point& begin, const Point& end)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawLine(begin, end); render_ctx_->DrawLine(begin, end);
cache_expired_ = true;
} }
void Canvas::DrawCircle(const Point& center, float radius) void Canvas::DrawCircle(const Point& center, float radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawEllipse(center, Vec2(radius, radius)); render_ctx_->DrawEllipse(center, Vec2(radius, radius));
cache_expired_ = true;
} }
void Canvas::DrawEllipse(const Point& center, const Vec2& radius) void Canvas::DrawEllipse(const Point& center, const Vec2& radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawEllipse(center, radius); render_ctx_->DrawEllipse(center, radius);
cache_expired_ = true;
} }
void Canvas::DrawRect(const Rect& rect) void Canvas::DrawRect(const Rect& rect)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawRectangle(rect); render_ctx_->DrawRectangle(rect);
cache_expired_ = true;
} }
void Canvas::DrawRoundedRect(const Rect& rect, const Vec2& radius) void Canvas::DrawRoundedRect(const Rect& rect, const Vec2& radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawRoundedRectangle(rect, radius); render_ctx_->DrawRoundedRectangle(rect, radius);
cache_expired_ = true;
} }
void Canvas::FillShape(ShapePtr shape) void Canvas::FillShape(ShapePtr shape)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
if (shape) if (shape)
{ {
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillShape(*shape); render_ctx_->FillShape(*shape);
cache_expired_ = true;
} }
} }
void Canvas::FillCircle(const Point& center, float radius) void Canvas::FillCircle(const Point& center, float radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillEllipse(center, Vec2(radius, radius)); render_ctx_->FillEllipse(center, Vec2(radius, radius));
cache_expired_ = true;
} }
void Canvas::FillEllipse(const Point& center, const Vec2& radius) void Canvas::FillEllipse(const Point& center, const Vec2& radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillEllipse(center, radius); render_ctx_->FillEllipse(center, radius);
cache_expired_ = true;
} }
void Canvas::FillRect(const Rect& rect) void Canvas::FillRect(const Rect& rect)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillRectangle(rect); render_ctx_->FillRectangle(rect);
cache_expired_ = true;
} }
void Canvas::FillRoundedRect(const Rect& rect, const Vec2& radius) void Canvas::FillRoundedRect(const Rect& rect, const Vec2& radius)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillRoundedRectangle(rect, radius); render_ctx_->FillRoundedRectangle(rect, radius);
cache_expired_ = true;
} }
void Canvas::DrawTexture(TexturePtr texture, const Rect* src_rect, const Rect* dest_rect) void Canvas::DrawFrame(FramePtr frame, const Point& pos)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
if (texture) if (frame && frame->IsValid())
{ {
ctx_->DrawTexture(*texture, src_rect, dest_rect); render_ctx_->DrawTexture(*frame->GetTexture(), &frame->GetCropRect(), &Rect(pos, frame->GetSize()));
cache_expired_ = true; }
}
void Canvas::DrawFrame(FramePtr frame, const Point& pos, const Size& size)
{
KGE_ASSERT(render_ctx_);
if (frame && frame->IsValid())
{
render_ctx_->DrawTexture(*frame->GetTexture(), &frame->GetCropRect(), &Rect(pos, size));
} }
} }
@ -240,11 +230,10 @@ void Canvas::DrawTextLayout(const String& text, const TextStyle& style, const Po
void Canvas::DrawTextLayout(TextLayoutPtr layout, const Point& point) void Canvas::DrawTextLayout(TextLayoutPtr layout, const Point& point)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
if (layout) if (layout)
{ {
ctx_->DrawTextLayout(*layout, point); render_ctx_->DrawTextLayout(*layout, point);
cache_expired_ = true;
} }
} }
@ -280,60 +269,42 @@ void Canvas::AddArc(const Point& point, const Size& radius, float rotation, bool
void Canvas::StrokePath() void Canvas::StrokePath()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(stroke_brush_); render_ctx_->SetCurrentBrush(stroke_brush_);
ctx_->SetCurrentStrokeStyle(stroke_style_); render_ctx_->SetCurrentStrokeStyle(stroke_style_);
ctx_->DrawShape(*shape_maker_.GetShape()); render_ctx_->DrawShape(*shape_maker_.GetShape());
cache_expired_ = true;
} }
void Canvas::FillPath() void Canvas::FillPath()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->SetCurrentBrush(fill_brush_); render_ctx_->SetCurrentBrush(fill_brush_);
ctx_->FillShape(*shape_maker_.GetShape()); render_ctx_->FillShape(*shape_maker_.GetShape());
cache_expired_ = true;
} }
void Canvas::Clear() void Canvas::Clear()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->Clear(); render_ctx_->Clear();
cache_expired_ = true;
} }
void Canvas::Clear(const Color& clear_color) void Canvas::Clear(const Color& clear_color)
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(render_ctx_);
ctx_->Clear(clear_color); render_ctx_->Clear(clear_color);
cache_expired_ = true;
} }
void Canvas::ResizeAndClear(Size size) void Canvas::ResizeAndClear(Size size)
{ {
ctx_ = TextureRenderContext::Create(size); texture_cached_ = new Texture;
render_ctx_ = RenderContext::Create(*texture_cached_, size);
SetSize(render_ctx_->GetSize());
} }
TexturePtr Canvas::ExportToTexture() const TexturePtr Canvas::ExportToTexture() const
{ {
UpdateCache();
return texture_cached_; return texture_cached_;
} }
void Canvas::UpdateCache() const
{
if (cache_expired_ && ctx_)
{
if (!texture_cached_)
{
texture_cached_ = new Texture;
}
if (ctx_->GetOutput(*texture_cached_))
{
cache_expired_ = false;
}
}
}
} // namespace kiwano } // namespace kiwano

View File

@ -20,8 +20,9 @@
#pragma once #pragma once
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/2d/Frame.h>
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/TextureRenderContext.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
{ {
@ -117,11 +118,17 @@ public:
void FillRoundedRect(const Rect& rect, const Vec2& radius); void FillRoundedRect(const Rect& rect, const Vec2& radius);
/// \~chinese /// \~chinese
/// @brief 绘制纹理 /// @brief 绘制图像帧
/// @param texture 纹理 /// @param frame 图像帧
/// @param src_rect 纹理裁剪区域 /// @param pos 绘制图像的位置
/// @param dest_rect 绘制目标区域 void DrawFrame(FramePtr frame, const Point& pos);
void DrawTexture(TexturePtr texture, const Rect* src_rect = nullptr, const Rect* dest_rect = nullptr);
/// \~chinese
/// @brief 绘制图像帧
/// @param frame 图像帧
/// @param pos 绘制图像的位置
/// @param size 渲染的图像大小
void DrawFrame(FramePtr frame, const Point& pos, const Size& size);
/// \~chinese /// \~chinese
/// @brief 绘制文字布局 /// @brief 绘制文字布局
@ -268,17 +275,13 @@ public:
private: private:
Canvas(); Canvas();
void UpdateCache() const;
private: private:
StrokeStylePtr stroke_style_; StrokeStylePtr stroke_style_;
ShapeMaker shape_maker_; ShapeMaker shape_maker_;
BrushPtr fill_brush_; BrushPtr fill_brush_;
BrushPtr stroke_brush_; BrushPtr stroke_brush_;
TexturePtr texture_cached_;
mutable bool cache_expired_; RenderContextPtr render_ctx_;
mutable TexturePtr texture_cached_;
mutable TextureRenderContextPtr ctx_;
}; };
/** @} */ /** @} */

View File

@ -40,7 +40,7 @@ typedef IntrusiveList<ComponentPtr> ComponentList;
* @brief * @brief
*/ */
class KGE_API Component class KGE_API Component
: public virtual ObjectBase : public ObjectBase
, protected IntrusiveListValue<ComponentPtr> , protected IntrusiveListValue<ComponentPtr>
{ {
friend class Actor; friend class Actor;

View File

@ -30,7 +30,7 @@ KGE_DECLARE_SMART_PTR(Frame);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Frame : public virtual ObjectBase class KGE_API Frame : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -31,7 +31,7 @@ KGE_DECLARE_SMART_PTR(FrameSequence);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API FrameSequence : public virtual ObjectBase class KGE_API FrameSequence : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -87,11 +87,13 @@ bool GifSprite::Load(GifImagePtr gif)
loop_count_ = 0; loop_count_ = 0;
frame_ = GifImage::Frame(); frame_ = GifImage::Frame();
if (!frame_rt_) saved_frame_.Reset();
{ frame_to_render_.Reset();
Size frame_size = Size(float(gif_->GetWidthInPixels()), float(gif_->GetHeightInPixels())); frame_rt_.Reset();
frame_rt_ = TextureRenderContext::Create(frame_size);
} Size frame_size = Size(float(gif_->GetWidthInPixels()), float(gif_->GetHeightInPixels()));
frame_to_render_ = new Texture;
frame_rt_ = RenderContext::Create(*frame_to_render_, frame_size);
SetSize(frame_rt_->GetSize()); SetSize(frame_rt_->GetSize());
@ -149,7 +151,7 @@ void GifSprite::ComposeNextFrame()
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
KGE_ASSERT(gif_); KGE_ASSERT(gif_);
if (frame_rt_->IsValid()) if (frame_rt_)
{ {
do do
{ {
@ -191,7 +193,7 @@ void GifSprite::OverlayNextFrame()
SaveComposedFrame(); SaveComposedFrame();
} }
if (frame_rt_->IsValid()) if (frame_rt_)
{ {
frame_rt_->BeginDraw(); frame_rt_->BeginDraw();
@ -208,15 +210,7 @@ void GifSprite::OverlayNextFrame()
frame_rt_->EndDraw(); frame_rt_->EndDraw();
if (!frame_to_render_) next_index_ = (++next_index_) % gif_->GetFramesCount();
{
frame_to_render_ = new Texture;
}
if (frame_rt_->GetOutput(*frame_to_render_))
{
next_index_ = (++next_index_) % gif_->GetFramesCount();
}
} }
// Execute callback // Execute callback
@ -235,18 +229,12 @@ void GifSprite::SaveComposedFrame()
{ {
KGE_ASSERT(frame_rt_); KGE_ASSERT(frame_rt_);
TexturePtr frame_to_be_saved = new Texture; if (!saved_frame_)
if (frame_rt_->GetOutput(*frame_to_be_saved))
{ {
if (!saved_frame_) saved_frame_ = new Texture;
{ frame_rt_->CreateTexture(*saved_frame_, frame_to_render_->GetSizeInPixels());
saved_frame_ = new Texture;
frame_rt_->CreateTexture(*saved_frame_, frame_to_be_saved->GetSizeInPixels());
}
saved_frame_->CopyFrom(frame_to_be_saved);
} }
saved_frame_->CopyFrom(frame_to_render_);
} }
void GifSprite::RestoreSavedFrame() void GifSprite::RestoreSavedFrame()
@ -255,12 +243,7 @@ void GifSprite::RestoreSavedFrame()
if (saved_frame_) if (saved_frame_)
{ {
TexturePtr frame_to_copy_to = new Texture; frame_to_render_->CopyFrom(saved_frame_);
if (frame_rt_->GetOutput(*frame_to_copy_to))
{
frame_to_copy_to->CopyFrom(saved_frame_);
}
} }
} }

View File

@ -22,7 +22,7 @@
#include <kiwano/2d/Actor.h> #include <kiwano/2d/Actor.h>
#include <kiwano/core/Resource.h> #include <kiwano/core/Resource.h>
#include <kiwano/render/GifImage.h> #include <kiwano/render/GifImage.h>
#include <kiwano/render/TextureRenderContext.h> #include <kiwano/render/RenderContext.h>
namespace kiwano namespace kiwano
{ {
@ -150,18 +150,18 @@ private:
void ClearCurrentFrameArea(); void ClearCurrentFrameArea();
private: private:
bool animating_; bool animating_;
int total_loop_count_; int total_loop_count_;
int loop_count_; int loop_count_;
size_t next_index_; size_t next_index_;
Duration frame_elapsed_; Duration frame_elapsed_;
LoopDoneCallback loop_cb_; LoopDoneCallback loop_cb_;
DoneCallback done_cb_; DoneCallback done_cb_;
GifImagePtr gif_; GifImagePtr gif_;
GifImage::Frame frame_; GifImage::Frame frame_;
TexturePtr saved_frame_; TexturePtr saved_frame_;
TexturePtr frame_to_render_; TexturePtr frame_to_render_;
TextureRenderContextPtr frame_rt_; RenderContextPtr frame_rt_;
}; };
/** @} */ /** @} */

View File

@ -160,7 +160,10 @@ void Sprite::SetFrame(FramePtr frame, bool autoresize)
void Sprite::OnRender(RenderContext& ctx) void Sprite::OnRender(RenderContext& ctx)
{ {
ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds()); if (frame_ && frame_->IsValid())
{
ctx.DrawTexture(*frame_->GetTexture(), &frame_->GetCropRect(), &GetBounds());
}
} }
bool Sprite::CheckVisibility(RenderContext& ctx) const bool Sprite::CheckVisibility(RenderContext& ctx) const

View File

@ -38,7 +38,7 @@ KGE_DECLARE_SMART_PTR(RotationTransition);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Transition : public virtual ObjectBase class KGE_API Transition : public ObjectBase
{ {
friend class Director; friend class Director;

View File

@ -50,7 +50,7 @@ typedef IntrusiveList<ActionPtr> ActionList;
/// \~chinese /// \~chinese
/// @brief 动画 /// @brief 动画
class KGE_API Action class KGE_API Action
: public virtual ObjectBase : public ObjectBase
, protected IntrusiveListValue<ActionPtr> , protected IntrusiveListValue<ActionPtr>
{ {
friend class ActionManager; friend class ActionManager;

View File

@ -38,7 +38,7 @@ typedef Function<void()> AsyncTaskCallback;
/// task->Then(DoSomething); /// task->Then(DoSomething);
/// task->Start(); /// task->Start();
/// @endcode /// @endcode
class AsyncTask : public virtual ObjectBase class KGE_API AsyncTask : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese

View File

@ -43,7 +43,7 @@ typedef IntrusiveList<EventListenerPtr> ListenerList;
* @brief * @brief
*/ */
class KGE_API EventListener class KGE_API EventListener
: public virtual ObjectBase : public ObjectBase
, protected IntrusiveListValue<EventListenerPtr> , protected IntrusiveListValue<EventListenerPtr>
{ {
friend class EventDispatcher; friend class EventDispatcher;

View File

@ -28,6 +28,24 @@
namespace kiwano namespace kiwano
{ {
// wide-to-ANSI string conversion helper
namespace detail
{
inline std::unique_ptr<char[]> to_narrow(BSTR msg)
{
return std::unique_ptr<char[]>(_com_util::ConvertBSTRToString(msg));
}
inline std::unique_ptr<char[]> to_narrow(const wchar_t* msg)
{
static_assert(std::is_same<wchar_t*, BSTR>::value, "BSTR must be wchar_t*");
// const_cast is fine:
// BSTR is a wchar_t*;
// ConvertBSTRToString internally uses _wcslen and WideCharToMultiByte;
return to_narrow(const_cast<wchar_t*>(msg));
}
}
class com_error_category : public std::error_category class com_error_category : public std::error_category
{ {
public: public:
@ -38,16 +56,12 @@ public:
return "com"; return "com";
} }
// @note If _UNICODE is defined the error description gets
// converted to an ANSI string using the CP_ACP codepage.
std::string message(int hr) const override std::string message(int hr) const override
{ {
return string::ToNarrow(_com_error{ hr }.ErrorMessage()); auto narrow = detail::to_narrow(_com_error{ hr }.ErrorMessage());
return narrow.get();
} }
// Make error_condition for error code (generic if possible)
// @return system's default error condition if error value can be mapped to a Windows error, error condition with
// com category otherwise
std::error_condition default_error_condition(int hr) const noexcept override std::error_condition default_error_condition(int hr) const noexcept override
{ {
if (HRESULT_CODE(hr) || hr == 0) if (HRESULT_CODE(hr) || hr == 0)

View File

@ -37,7 +37,7 @@ typedef IntrusiveList<TimerPtr> TimerList;
/// @brief 定时器 /// @brief 定时器
/// @details 定时器用于每隔一段时间执行一次回调函数,且可以指定执行总次数 /// @details 定时器用于每隔一段时间执行一次回调函数,且可以指定执行总次数
class KGE_API Timer class KGE_API Timer
: public virtual ObjectBase : public ObjectBase
, protected IntrusiveListValue<TimerPtr> , protected IntrusiveListValue<TimerPtr>
{ {
friend class TimerManager; friend class TimerManager;

View File

@ -34,7 +34,7 @@ KGE_DECLARE_SMART_PTR(Runner);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API Runner : public virtual ObjectBase class KGE_API Runner : public ObjectBase
{ {
friend class Application; friend class Application;

View File

@ -33,12 +33,12 @@ RenderContextImpl::~RenderContextImpl()
DiscardDeviceResources(); DiscardDeviceResources();
} }
HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> ctx) HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> render_target)
{ {
if (!factory || !ctx) if (!factory || !render_target)
return E_INVALIDARG; return E_INVALIDARG;
render_target_ = ctx; render_target_ = render_target;
text_renderer_.Reset(); text_renderer_.Reset();
current_brush_.Reset(); current_brush_.Reset();
@ -49,7 +49,7 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, C
SetAntialiasMode(antialias_); SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_); SetTextAntialiasMode(text_antialias_);
Resize(reinterpret_cast<const Size&>(ctx->GetSize())); Resize(reinterpret_cast<const Size&>(render_target->GetSize()));
} }
// DrawingStateBlock // DrawingStateBlock
@ -58,6 +58,10 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, C
hr = factory->CreateDrawingStateBlock(&drawing_state_); hr = factory->CreateDrawingStateBlock(&drawing_state_);
} }
if (SUCCEEDED(hr))
{
NativePtr::Set(this, render_target);
}
return hr; return hr;
} }
@ -66,11 +70,8 @@ void RenderContextImpl::DiscardDeviceResources()
text_renderer_.Reset(); text_renderer_.Reset();
render_target_.Reset(); render_target_.Reset();
current_brush_.Reset(); current_brush_.Reset();
}
bool RenderContextImpl::IsValid() const ResetNativePointer();
{
return render_target_ != nullptr;
} }
void RenderContextImpl::BeginDraw() void RenderContextImpl::BeginDraw()

View File

@ -25,16 +25,16 @@
namespace kiwano namespace kiwano
{ {
class RendererImpl;
KGE_DECLARE_SMART_PTR(RenderContextImpl); KGE_DECLARE_SMART_PTR(RenderContextImpl);
class KGE_API RenderContextImpl : public virtual RenderContext class KGE_API RenderContextImpl : public RenderContext
{ {
friend class RendererImpl;
public: public:
bool IsValid() const override; RenderContextImpl();
virtual ~RenderContextImpl();
HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> render_target);
void BeginDraw() override; void BeginDraw() override;
@ -92,20 +92,14 @@ public:
void Resize(const Size& size) override; void Resize(const Size& size) override;
protected: private:
RenderContextImpl();
virtual ~RenderContextImpl();
HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> ctx);
void DiscardDeviceResources(); void DiscardDeviceResources();
void SaveDrawingState(); void SaveDrawingState();
void RestoreDrawingState(); void RestoreDrawingState();
protected: private:
ComPtr<ITextRenderer> text_renderer_; ComPtr<ITextRenderer> text_renderer_;
ComPtr<ID2D1RenderTarget> render_target_; ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ID2D1DrawingStateBlock> drawing_state_; ComPtr<ID2D1DrawingStateBlock> drawing_state_;

View File

@ -24,7 +24,6 @@
#include <kiwano/platform/FileSystem.h> #include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/DirectX/TextureRenderContextImpl.h>
#include <kiwano/render/DirectX/RendererImpl.h> #include <kiwano/render/DirectX/RendererImpl.h>
#include <kiwano/render/DirectX/NativePtr.h> #include <kiwano/render/DirectX/NativePtr.h>
@ -44,7 +43,6 @@ RendererImpl& RendererImpl::GetInstance()
RendererImpl::RendererImpl() RendererImpl::RendererImpl()
{ {
render_ctx_ = new RenderContextImpl;
} }
void RendererImpl::MakeContextForWindow(WindowPtr window) void RendererImpl::MakeContextForWindow(WindowPtr window)
@ -74,7 +72,13 @@ void RendererImpl::MakeContextForWindow(WindowPtr window)
// Other device resources // Other device resources
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = render_ctx_->CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext()); RenderContextImplPtr ctx = new RenderContextImpl;
hr = ctx->CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
if (SUCCEEDED(hr))
{
render_ctx_ = ctx;
}
} }
// FontFileLoader and FontCollectionLoader // FontFileLoader and FontCollectionLoader
@ -133,20 +137,6 @@ void RendererImpl::Destroy()
::CoUninitialize(); ::CoUninitialize();
} }
void RendererImpl::BeginDraw()
{
KGE_ASSERT(render_ctx_);
render_ctx_->BeginDraw();
}
void RendererImpl::EndDraw()
{
KGE_ASSERT(render_ctx_);
render_ctx_->EndDraw();
}
void RendererImpl::Clear() void RendererImpl::Clear()
{ {
KGE_ASSERT(d3d_res_); KGE_ASSERT(d3d_res_);
@ -159,34 +149,9 @@ void RendererImpl::Present()
KGE_ASSERT(d3d_res_); KGE_ASSERT(d3d_res_);
HRESULT hr = d3d_res_->Present(vsync_); HRESULT hr = d3d_res_->Present(vsync_);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
hr = HandleDeviceLost();
}
KGE_THROW_IF_FAILED(hr, "Unexpected DXGI exception"); KGE_THROW_IF_FAILED(hr, "Unexpected DXGI exception");
} }
HRESULT RendererImpl::HandleDeviceLost()
{
KGE_ASSERT(d3d_res_ && d2d_res_ && render_ctx_);
HRESULT hr = d3d_res_->HandleDeviceLost();
if (SUCCEEDED(hr))
{
hr = d2d_res_->HandleDeviceLost(d3d_res_->GetDXGIDevice(), d3d_res_->GetDXGISwapChain());
}
if (SUCCEEDED(hr))
{
hr = render_ctx_->CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
}
return hr;
}
void RendererImpl::CreateTexture(Texture& texture, const String& file_path) void RendererImpl::CreateTexture(Texture& texture, const String& file_path)
{ {
HRESULT hr = S_OK; HRESULT hr = S_OK;
@ -937,9 +902,9 @@ void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style)
KGE_THROW_IF_FAILED(hr, "Create ID2D1StrokeStyle failed"); KGE_THROW_IF_FAILED(hr, "Create ID2D1StrokeStyle failed");
} }
TextureRenderContextPtr RendererImpl::CreateTextureRenderContext(const Size* desired_size) RenderContextPtr RendererImpl::CreateTextureRenderContext(Texture& texture, const Size* desired_size)
{ {
TextureRenderContextImplPtr ptr = new TextureRenderContextImpl; RenderContextImplPtr ptr = new RenderContextImpl;
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d2d_res_) if (!d2d_res_)
@ -968,13 +933,17 @@ TextureRenderContextPtr RendererImpl::CreateTextureRenderContext(const Size* des
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ptr->bitmap_rt_ = bitmap_rt; ComPtr<ID2D1Bitmap> output;
hr = bitmap_rt->GetBitmap(&output);
if (SUCCEEDED(hr))
{
NativePtr::Set(texture, output);
}
} }
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
return ptr; return ptr;
return nullptr; return nullptr;
} }

View File

@ -80,19 +80,13 @@ public:
void CreateStrokeStyle(StrokeStyle& stroke_style) override; void CreateStrokeStyle(StrokeStyle& stroke_style) override;
TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) override; RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) override;
public: public:
void BeginDraw() override;
void EndDraw() override;
void Clear() override; void Clear() override;
void Present() override; void Present() override;
RenderContext& GetContext() override;
/// \~chinese /// \~chinese
/// @brief 获取Direct2D设备资源 /// @brief 获取Direct2D设备资源
ID2DDeviceResources* GetD2DDeviceResources(); ID2DDeviceResources* GetD2DDeviceResources();
@ -112,10 +106,7 @@ protected:
void Destroy() override; void Destroy() override;
HRESULT HandleDeviceLost();
private: private:
RenderContextImplPtr render_ctx_;
ComPtr<ID2DDeviceResources> d2d_res_; ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID3DDeviceResources> d3d_res_; ComPtr<ID3DDeviceResources> d3d_res_;
ComPtr<IFontCollectionLoader> font_collection_loader_; ComPtr<IFontCollectionLoader> font_collection_loader_;
@ -125,11 +116,6 @@ private:
/** @} */ /** @} */
inline RenderContext& RendererImpl::GetContext()
{
return *render_ctx_;
}
inline ID2DDeviceResources* RendererImpl::GetD2DDeviceResources() inline ID2DDeviceResources* RendererImpl::GetD2DDeviceResources()
{ {
KGE_ASSERT(d2d_res_); KGE_ASSERT(d2d_res_);

View File

@ -1,50 +0,0 @@
// 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.
#include <kiwano/core/Logger.h>
#include <kiwano/render/Renderer.h>
#include <kiwano/render/DirectX/TextureRenderContextImpl.h>
#include <kiwano/render/DirectX/NativePtr.h>
namespace kiwano
{
bool TextureRenderContextImpl::GetOutput(Texture& texture)
{
HRESULT hr = E_FAIL;
if (bitmap_rt_)
{
ComPtr<ID2D1Bitmap> bitmap;
hr = bitmap_rt_->GetBitmap(&bitmap);
if (SUCCEEDED(hr))
{
NativePtr::Set(texture, bitmap);
texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height });
texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height });
}
}
return SUCCEEDED(hr);
}
} // namespace kiwano

View File

@ -1,104 +0,0 @@
// 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.
#pragma once
#include <kiwano/render/TextureRenderContext.h>
#include <kiwano/render/DirectX/RenderContextImpl.h>
namespace kiwano
{
class RendererImpl;
KGE_DECLARE_SMART_PTR(TextureRenderContextImpl);
KGE_SUPPRESS_WARNING_PUSH
KGE_SUPPRESS_WARNING(4250) // inherits via domainance
class KGE_API TextureRenderContextImpl
: public RenderContextImpl
, public TextureRenderContext
{
friend class RendererImpl;
public:
bool GetOutput(Texture& texture) override;
using RenderContextImpl::IsValid;
using RenderContextImpl::BeginDraw;
using RenderContextImpl::EndDraw;
using RenderContextImpl::DrawTexture;
using RenderContextImpl::DrawTextLayout;
using RenderContextImpl::DrawShape;
using RenderContextImpl::DrawLine;
using RenderContextImpl::DrawRectangle;
using RenderContextImpl::DrawRoundedRectangle;
using RenderContextImpl::DrawEllipse;
using RenderContextImpl::FillShape;
using RenderContextImpl::FillRectangle;
using RenderContextImpl::FillRoundedRectangle;
using RenderContextImpl::FillEllipse;
using RenderContextImpl::CreateTexture;
using RenderContextImpl::PushClipRect;
using RenderContextImpl::PopClipRect;
using RenderContextImpl::PushLayer;
using RenderContextImpl::PopLayer;
using RenderContextImpl::Clear;
using RenderContextImpl::GetSize;
using RenderContextImpl::SetCurrentBrush;
using RenderContextImpl::SetTransform;
using RenderContextImpl::SetAntialiasMode;
using RenderContextImpl::SetTextAntialiasMode;
using RenderContextImpl::CheckVisibility;
using RenderContextImpl::Resize;
private:
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt_;
};
KGE_SUPPRESS_WARNING_POP
} // namespace kiwano

View File

@ -39,7 +39,7 @@ KGE_DECLARE_SMART_PTR(NativeObject);
* \~chinese * \~chinese
* @brief * @brief
*/ */
class KGE_API NativeObject : public virtual ObjectBase class KGE_API NativeObject : public ObjectBase
{ {
public: public:
virtual bool IsValid() const; virtual bool IsValid() const;

View File

@ -19,10 +19,21 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/render/RenderContext.h> #include <kiwano/render/RenderContext.h>
#include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
RenderContextPtr RenderContext::Create(Texture& texture)
{
return Renderer::GetInstance().CreateTextureRenderContext(texture, nullptr);
}
RenderContextPtr RenderContext::Create(Texture& texture, const Size& size)
{
return Renderer::GetInstance().CreateTextureRenderContext(texture, &size);
}
RenderContext::RenderContext() RenderContext::RenderContext()
: collecting_status_(false) : collecting_status_(false)
, fast_global_transform_(true) , fast_global_transform_(true)

View File

@ -19,7 +19,6 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/core/ObjectBase.h>
#include <kiwano/core/Time.h> #include <kiwano/core/Time.h>
#include <kiwano/render/Brush.h> #include <kiwano/render/Brush.h>
#include <kiwano/render/Shape.h> #include <kiwano/render/Shape.h>
@ -29,7 +28,6 @@
namespace kiwano namespace kiwano
{ {
class Renderer;
KGE_DECLARE_SMART_PTR(RenderContext); KGE_DECLARE_SMART_PTR(RenderContext);
@ -50,16 +48,20 @@ enum class TextAntialiasMode
/// \~chinese /// \~chinese
/// @brief 渲染上下文 /// @brief 渲染上下文
/// @details /// @details 渲染上下文将完成基础图元的绘制,并将绘制结果输出到特定的平面中
/// 渲染上下文将完成基础图元的绘制,并将绘制结果输出到特定的目标中(如窗口或纹理) class KGE_API RenderContext : public NativeObject
class KGE_API RenderContext : public virtual ObjectBase
{ {
friend class Renderer;
public: public:
/// \~chinese /// \~chinese
/// @brief 是否有效 /// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中
virtual bool IsValid() const = 0; /// @param texture 保存绘制结果的纹理
static RenderContextPtr Create(Texture& texture);
/// \~chinese
/// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中
/// @param texture 保存绘制结果的纹理
/// @param size 渲染输出大小
static RenderContextPtr Create(Texture& texture, const Size& size);
/// \~chinese /// \~chinese
/// @brief 开始渲染 /// @brief 开始渲染

View File

@ -51,4 +51,18 @@ void Renderer::HandleEvent(Event* evt)
} }
} }
void Renderer::BeginDraw()
{
KGE_ASSERT(render_ctx_);
render_ctx_->BeginDraw();
}
void Renderer::EndDraw()
{
KGE_ASSERT(render_ctx_);
render_ctx_->EndDraw();
}
} // namespace kiwano } // namespace kiwano

View File

@ -24,7 +24,6 @@
#include <kiwano/render/GifImage.h> #include <kiwano/render/GifImage.h>
#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/platform/Window.h> #include <kiwano/platform/Window.h>
namespace kiwano namespace kiwano
@ -198,28 +197,29 @@ public:
virtual void CreateStrokeStyle(StrokeStyle& stroke_style) = 0; virtual void CreateStrokeStyle(StrokeStyle& stroke_style) = 0;
/// \~chinese /// \~chinese
/// @brief 创建纹理渲染上下文 /// @brief 创建纹理渲染上下文,将上下文的渲染输出到纹理中
/// @param[in,out] texture 渲染输出的纹理
/// @param[in] desired_size 期望的输出大小 /// @param[in] desired_size 期望的输出大小
/// @return 纹理渲染上下文 /// @return 纹理渲染上下文
/// @throw kiwano::SystemError 创建失败时抛出 /// @throw kiwano::SystemError 创建失败时抛出
virtual TextureRenderContextPtr CreateTextureRenderContext(const Size* desired_size = nullptr) = 0; virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0;
public: public:
/// \~chinese /// \~chinese
/// @brief 获取渲染上下文 /// @brief 获取渲染上下文
virtual RenderContext& GetContext() = 0; RenderContext& GetContext();
/// \~chinese /// \~chinese
/// @brief 获取渲染输出大小 /// @brief 获取渲染输出大小
virtual Size GetOutputSize() const; Size GetOutputSize() const;
/// \~chinese /// \~chinese
/// @brief 开始渲染 /// @brief 开始渲染
virtual void BeginDraw() = 0; virtual void BeginDraw();
/// \~chinese /// \~chinese
/// @brief 结束渲染 /// @brief 结束渲染
virtual void EndDraw() = 0; virtual void EndDraw();
/// \~chinese /// \~chinese
/// @brief 清除绘制内容 /// @brief 清除绘制内容
@ -249,13 +249,19 @@ protected:
virtual void Destroy() = 0; virtual void Destroy() = 0;
protected: protected:
bool vsync_; bool vsync_;
Color clear_color_; Color clear_color_;
Size output_size_; Size output_size_;
RenderContextPtr render_ctx_;
}; };
/** @} */ /** @} */
inline RenderContext& Renderer::GetContext()
{
return *render_ctx_;
}
inline Size Renderer::GetOutputSize() const inline Size Renderer::GetOutputSize() const
{ {
return output_size_; return output_size_;

View File

@ -1,56 +0,0 @@
// 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.
#include <kiwano/core/Logger.h>
#include <kiwano/render/TextureRenderContext.h>
#include <kiwano/render/Renderer.h>
namespace kiwano
{
TextureRenderContextPtr TextureRenderContext::Create()
{
TextureRenderContextPtr ptr;
try
{
ptr = Renderer::GetInstance().CreateTextureRenderContext(nullptr);
}
catch (std::exception&)
{
return nullptr;
}
return ptr;
}
TextureRenderContextPtr TextureRenderContext::Create(const Size& desired_size)
{
TextureRenderContextPtr ptr;
try
{
ptr = Renderer::GetInstance().CreateTextureRenderContext(&desired_size);
}
catch (std::exception&)
{
return nullptr;
}
return ptr;
}
} // namespace kiwano

View File

@ -1,57 +0,0 @@
// 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.
#pragma once
#include <kiwano/render/RenderContext.h>
namespace kiwano
{
KGE_DECLARE_SMART_PTR(TextureRenderContext);
/**
* \addtogroup Render
* @{
*/
/// \~chinese
/// @brief 纹理渲染上下文
/// @details 纹理渲染上下文将渲染输出到一个纹理对象中
class KGE_API TextureRenderContext : public virtual RenderContext
{
public:
/// \~chinese
/// @brief 创建纹理渲染上下文
static TextureRenderContextPtr Create();
/// \~chinese
/// @brief 创建纹理渲染上下文
/// @param size 期望的输出大小
static TextureRenderContextPtr Create(const Size& desired_size);
/// \~chinese
/// @brief 获取渲染输出
/// @param[out] texture 纹理输出
/// @return 操作是否成功
virtual bool GetOutput(Texture& texture) = 0;
};
/** @} */
} // namespace kiwano

View File

@ -37,7 +37,7 @@ KGE_DECLARE_SMART_PTR(LocalStorage);
/// data.SaveInt("best-score", 20); // 保存最高分 20 /// data.SaveInt("best-score", 20); // 保存最高分 20
/// int best = data.GetInt("best-score"); // 读取之前储存的最高分 /// int best = data.GetInt("best-score"); // 读取之前储存的最高分
/// @endcode /// @endcode
class KGE_API LocalStorage : public virtual ObjectBase class KGE_API LocalStorage : public ObjectBase
{ {
public: public:
/// \~chinese /// \~chinese