3#include <Covellite/Gui/Renderer.hpp>
4#include <alicorn/std/vector.hpp>
5#include <alicorn/boost/filesystem.hpp>
6#include <alicorn/patterns/factory.hpp>
7#include <alicorn/image.hpp>
8#include <Covellite/App/Vfs.hpp>
9#include <Covellite/Api/Component.inl>
10#include <Covellite/Api/Renders.hpp>
11#include <Covellite/Api/Vertex.hpp>
19Renderer::Renderer(
const RendersPtr_t & _pRenders) :
20 m_pRenders(_pRenders),
23 m_pRenders->Obtain(Component_t::Make(
25 { uT(
"id"), uT(
"Covellite.Gui.Camera.Gui") },
26 { uT(
"type"), uT(
"Camera") },
27 { uT(
"kind"), uT(
"Orthographic") },
29 m_pRenders->Obtain(Component_t::Make(
31 { uT(
"id"), uT(
"Covellite.Gui.State.Blend") },
32 { uT(
"type"), uT(
"State") },
33 { uT(
"kind"), uT(
"Blend") },
35 m_pRenders->Obtain(Component_t::Make(
37 { uT(
"id"), uT(
"Covellite.Gui.State.Sampler") },
38 { uT(
"type"), uT(
"State") },
39 { uT(
"kind"), uT(
"Sampler") },
41 m_pRenders->Obtain(Component_t::Make(
43 { uT(
"id"), uT(
"Covellite.Gui.Shader.Vertex") },
44 { uT(
"type"), uT(
"Shader") },
45 { uT(
"entry"), uT(
"vsFlat") },
48 m_pScissorRect(Component_t::Make(
50 { uT(
"type"), uT(
"Data") },
51 { uT(
"kind"), uT(
"Rect") },
63void Renderer::RenderGeometry(
64 CovelliteGui::Vertex * _pVertex,
int _VertexCount,
65 int * _pIndex,
int _IndexCount,
66 CovelliteGui::TextureHandle _hTexture,
67 const CovelliteGui::Vector2f & _Position)
69 const auto hGeometry = CompileGeometry(
70 _pVertex, _VertexCount,
73 RenderCompiledGeometry(hGeometry, _Position);
74 ReleaseCompiledGeometry(hGeometry);
77CovelliteGui::CompiledGeometryHandle Renderer::CompileGeometry(
78 CovelliteGui::Vertex * _pVertex,
int _VertexCount,
79 int * _pIndex,
int _IndexCount,
80 CovelliteGui::TextureHandle _hTexture)
82 static size_t ObjectId = 0;
84 const auto strObjectId = String_t{ uT(
"%ID%") }
85 .Replace(uT(
"%ID%"), (
size_t)++ObjectId);
87 Renders_t & Object = m_Objects[ObjectId].Renders;
88 m_Objects[ObjectId].pPosition = Component_t::Make(
90 { uT(
"type"), uT(
"Data") },
91 { uT(
"kind"), uT(
"Position") },
96 using namespace ::alicorn::extension::std;
100 Object.push_back(m_pRenders->Obtain(Component_t::Make(
102 { uT(
"id"), uT(
"Covellite.Gui.Shader.Pixel.Colored") },
103 { uT(
"type"), uT(
"Shader") },
104 { uT(
"entry"), uT(
"psColored") },
109 const auto strTextureId = uT(
"Covellite.Gui.Texture.%ID%")
110 .Replace(uT(
"%ID%"), (
size_t)_hTexture);
114 m_pRenders->Obtain(Component_t::Make(
116 { uT(
"id"), uT(
"Covellite.Gui.Shader.Pixel.Textured") },
117 { uT(
"type"), uT(
"Shader") },
118 { uT(
"entry"), uT(
"psTextured") },
120 m_pRenders->Obtain(Component_t::Make(
122 { uT(
"id"), strTextureId },
123 { uT(
"type"), uT(
"Texture") },
129 [](CovelliteGui::Vertex * _pVertex, const ::std::size_t _VertexCount)
131 ::std::vector<::covellite::api::Vertex> Result{ _VertexCount };
133 for (::std::size_t i = 0; i < _VertexCount; i++)
135 auto & Vertex = Result[i];
137 Vertex.px = _pVertex[i].position.x;
138 Vertex.py = _pVertex[i].position.y;
142 Vertex.tu = _pVertex[i].tex_coord.x;
143 Vertex.tv = _pVertex[i].tex_coord.y;
145 Vertex.ex = _pVertex[i].colour.red / 255.0f;
146 Vertex.ey = _pVertex[i].colour.green / 255.0f;
147 Vertex.ez = _pVertex[i].colour.blue / 255.0f;
148 Vertex.ew = _pVertex[i].colour.alpha / 255.0f;
156 m_pRenders->Obtain(Component_t::Make(
158 { uT(
"id"), uT(
"Covellite.Gui.Buffer.Vertex.") + strObjectId },
159 { uT(
"type"), uT(
"Buffer") },
160 { uT(
"content"), Convert(_pVertex,
static_cast<::std::size_t
>(_VertexCount)) },
161 { uT(
"dimension"), 2 },
163 m_pRenders->Obtain(Component_t::Make(
165 { uT(
"id"), uT(
"Covellite.Gui.Transform.") + strObjectId },
166 { uT(
"type"), uT(
"Transform") },
167 { uT(
"service"), Object_t{ m_Objects[ObjectId].pPosition } },
169 m_pRenders->Obtain(Component_t::Make(
171 { uT(
"id"), uT(
"Covellite.Gui.Present.") + strObjectId },
172 { uT(
"type"), uT(
"Present") },
173 { uT(
"content"), ::std::vector<int>{ _pIndex, _pIndex + _IndexCount } },
177 return (CovelliteGui::CompiledGeometryHandle)ObjectId;
180void Renderer::RenderCompiledGeometry(
181 CovelliteGui::CompiledGeometryHandle _hGeometry,
182 const CovelliteGui::Vector2f & _Position)
184 const auto itObject = m_Objects.find((
size_t)_hGeometry);
185 if (itObject == m_Objects.end())
return;
187 auto & Position = *itObject->second.pPosition;
189 Position[uT(
"x")] = _Position.x;
190 Position[uT(
"y")] = _Position.y;
192 using namespace ::alicorn::extension::std;
194 m_RenderQueue += itObject->second.Renders;
197void Renderer::ReleaseCompiledGeometry(
198 CovelliteGui::CompiledGeometryHandle _hGeometry)
200 const auto strObjectId = String_t{ uT(
"%ID%") }
201 .Replace(uT(
"%ID%"), (
size_t)_hGeometry);
203 m_pRenders->Remove(Component_t::Make(
205 { uT(
"id"), uT(
"Covellite.Gui.Buffer.Vertex.") + strObjectId }
207 m_pRenders->Remove(Component_t::Make(
209 { uT(
"id"), uT(
"Covellite.Gui.Present.") + strObjectId }
212 m_Objects.erase((
size_t)_hGeometry);
215void Renderer::EnableScissorRegion(
bool _IsEnable)
217 if (_IsEnable)
return;
219 using namespace ::alicorn::extension::std;
221 m_RenderQueue.push_back(m_pRenders->Obtain(Component_t::Make(
223 { uT(
"id"), uT(
"Covellite.Gui.State.Scissor.Disabled") },
224 { uT(
"type"), uT(
"State") },
225 { uT(
"kind"), uT(
"Scissor") },
226 { uT(
"enabled"), uT(
"false") }
230void Renderer::SetScissorRegion(
int _X,
int _Y,
int _Width,
int _Height)
232 m_RenderQueue.push_back([&, _X, _Y, _Width, _Height]()
234 auto & ScissorRect = *m_pScissorRect;
236 ScissorRect[uT(
"left")] = _X;
237 ScissorRect[uT(
"right")] = _X + _Width;
238 ScissorRect[uT(
"top")] = _Y;
239 ScissorRect[uT(
"bottom")] = _Y + _Height;
242 using namespace ::alicorn::extension::std;
244 m_RenderQueue.push_back(m_pRenders->Obtain(Component_t::Make(
246 { uT(
"id"), uT(
"Covellite.Gui.State.Scissor.Enabled") },
247 { uT(
"type"), uT(
"State") },
248 { uT(
"kind"), uT(
"Scissor") },
249 { uT(
"enabled"), uT(
"true") },
250 { uT(
"service"), Object_t{ m_pScissorRect } }
254bool Renderer::LoadTexture(
255 CovelliteGui::TextureHandle & _hTexture,
256 CovelliteGui::Vector2i & _TextureDimensions,
257 const CovelliteGui::String & _PathToFile)
266 using namespace ::alicorn::source;
270 const image::Universal_t<image::pixel::RGBA> Image
272 app::Vfs_t::GetInstance().GetData(CovelliteGuiStringToUtf8(_PathToFile))
275 _TextureDimensions.x =
static_cast<int>(Image.GetData().Width);
276 _TextureDimensions.y =
static_cast<int>(Image.GetData().Height);
279 TODO(
"Лишнее копирование данных текстуры.");
281 return GenerateTexture(_hTexture,
282 Image.GetData().Buffer.data(), _TextureDimensions);
284 catch (const ::std::exception &)
294bool Renderer::GenerateTexture(
295 CovelliteGui::TextureHandle & _hTexture,
296 const CovelliteGui::byte * _pSource,
297 const CovelliteGui::Vector2i & _SourceDimensions)
299 static CovelliteGui::TextureHandle TextureId = 0;
301 const auto strTextureId = String_t{ uT(
"Covellite.Gui.Texture.%ID%") }
302 .Replace(uT(
"%ID%"), (
size_t)++TextureId);
304 const auto Count = 4 * _SourceDimensions.x * _SourceDimensions.y;
306 m_pRenders->Obtain(Component_t::Make(
308 { uT(
"id"), strTextureId },
309 { uT(
"type"), uT(
"Texture") },
310 { uT(
"content"), ::std::vector<uint8_t>{ _pSource, _pSource + Count } },
311 { uT(
"width"), _SourceDimensions.x },
312 { uT(
"height"), _SourceDimensions.y },
315 _hTexture = TextureId;
320void Renderer::ReleaseTexture(CovelliteGui::TextureHandle _hTexture)
322 const auto strTextureId = String_t{ uT(
"Covellite.Gui.Texture.%ID%") }
323 .Replace(uT(
"%ID%"), (
size_t)_hTexture);
325 m_pRenders->Remove(Component_t::Make(
327 { uT(
"id"), strTextureId },
328 { uT(
"type"), uT(
"Texture") },
332void Renderer::RenderScene(
void)
334 for (
const auto & Render : m_DefaultRenders) Render();
335 for (
const auto & Render : m_RenderQueue) Render();
337 m_RenderQueue.clear();