Covellite++  Version: 2.3.0 Revision: ??? Platform: x64 Build: 23:13 04.01.2025
Кроссплатформенный фреймворк для разработки приложений на С++
Загрузка...
Поиск...
Не найдено
OpenGLCommon.cpp
1
2#include "stdafx.h"
3#include "OpenGLCommon.hpp"
4#include <glm/glm.force.hpp>
5#include <alicorn/std/string/encoding.hpp>
6#include "Component.hpp"
7#include "Shaders/Shaders.hpp"
8#include "GraphicApi.Constants.hpp"
9
10namespace covellite
11{
12
13namespace api
14{
15
16namespace renderer
17{
18
19OpenGLCommon::OpenGLCommon(const Data_t & _Data, const String_t & _PreVersion) :
20 m_Top{ _Data.ClientRect.Top },
21 m_Width{ _Data.ClientRect.Width },
22 m_Height{ _Data.ClientRect.Height },
23 m_PreVersion{ _PreVersion }
24{
25}
26
27OpenGLCommon::String_t OpenGLCommon::GetUsingApi(void) const /*override*/
28{
29 using namespace ::alicorn::extension::std;
30
31 const ::std::string Version =
32 reinterpret_cast<const char *>(glGetString(GL_VERSION));
33
34 return m_PreVersion + string_cast<String, Encoding::Ascii128>(Version);
35}
36
37void OpenGLCommon::ResizeWindow(const Rect & _ClientRect) noexcept /*final*/
38{
39 m_Top = _ClientRect.Top;
40 m_Width = _ClientRect.Width;
41 m_Height = _ClientRect.Height;
42
43 m_IsResizeWindow = true;
44}
45
46auto OpenGLCommon::CreateState(const ComponentPtr_t & _pComponent) -> Render_t /*override*/
47{
48 const auto CreateBlendState = [](void) noexcept
49 {
50 return [](void) noexcept
51 {
52 glEnable(GL_BLEND);
53 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
54 };
55 };
56
57 const auto CreateSamplerState = [&](void)
58 {
59 return [=](void)
60 {
61 m_TexParameters.MinFilter = GL_LINEAR;
62 m_TexParameters.MagFilter = GL_LINEAR;
63 m_TexParameters.WrapS = GL_REPEAT;
64 m_TexParameters.WrapT = GL_REPEAT;
65 };
66 };
67
68 const auto CreateScissorState = [&](void)
69 {
70 const auto pScissorRect = CapturingServiceComponent::Get(_pComponent,
71 { { uT("Rect"), api::Component::Make({}) } })[0];
72
73 Render_t ScissorEnabled = [=](void)
74 {
75 const Component::Scissor Rect{ *pScissorRect };
76
77 glEnable(GL_SCISSOR_TEST);
78
79 GLint ViewPort[4] = { 0 };
80 glGetIntegerv(GL_VIEWPORT, ViewPort);
81
82 // (x, y) - левый нижний угол!
83 glScissor(Rect.Left, ViewPort[3] - Rect.Bottom,
84 Rect.Right - Rect.Left, Rect.Bottom - Rect.Top);
85 };
86
87 Render_t ScissorDisabled = [](void) noexcept
88 {
89 glDisable(GL_SCISSOR_TEST);
90 };
91
92 const Component::Scissor Scissor{ *_pComponent };
93 return (Scissor.IsEnabled) ? ScissorEnabled : ScissorDisabled;
94 };
95
96 const auto CreateDepthState = [&](void)
97 {
98 return GetDepthRender(
99 (*_pComponent)[uT("enabled")].Default(false),
100 (*_pComponent)[uT("clear")].Default(false),
101 (*_pComponent)[uT("overwrite")].Default(true));
102 };
103
104 const auto CreateClearState = [&](void)
105 {
106 // ?????????????????????????????????????????????????????????????????????? //
107 // Использование здесь ::glm::vec4 приводит к падению программы в Release
108 // версии при копировании созданного рендера в
109 // Component::Renders::m_AllExistingRenders.
110 class Color { public: float r, g, b, a; };
111
112 const auto BackgroundColor = ARGBtoFloat4<Color>(
113 (*_pComponent)[uT("color")].Default(0xFF000000));
114 // ?????????????????????????????????????????????????????????????????????? //
115
116 return [=](void) noexcept
117 {
118 glClearColor(
119 BackgroundColor.r,
120 BackgroundColor.g,
121 BackgroundColor.b,
122 BackgroundColor.a);
123 glClear(GL_COLOR_BUFFER_BIT);
124 };
125 };
126
127 ::std::map<String_t, ::std::function<Render_t(void)>> Creators =
128 {
129 { uT("Blend"), CreateBlendState },
130 { uT("Sampler"), CreateSamplerState },
131 { uT("Scissor"), CreateScissorState },
132 { uT("Depth"), CreateDepthState },
133 { uT("Clear"), CreateClearState },
134 };
135
136 return Creators[_pComponent->Kind]();
137}
138
139auto OpenGLCommon::GetDepthRender(
140 const bool _IsEnabled,
141 const bool _IsClear,
142 const bool _IsOverwrite) -> Render_t
143{
144 const Render_t DepthDisable = [](void) noexcept
145 {
146 glDisable(GL_DEPTH_TEST);
147 };
148
149 const auto IsOverwrite =
150 static_cast<GLboolean>(_IsOverwrite ? GL_TRUE : GL_FALSE);
151
152 const Render_t DepthEnable = [=](void) noexcept
153 {
154 glEnable(GL_DEPTH_TEST);
155 glDepthMask(IsOverwrite);
156 glDepthFunc(GL_GREATER);
157 };
158
159 const Render_t DepthClear = [=](void) noexcept
160 {
161 glEnable(GL_DEPTH_TEST);
162 glDepthMask(IsOverwrite);
163 glDepthFunc(GL_GREATER);
164 glClearDepth(0.0f);
165 glClear(GL_DEPTH_BUFFER_BIT);
166 };
167
168 return _IsEnabled ? (_IsClear ? DepthClear : DepthEnable) : DepthDisable;
169}
170
171// cppcheck-suppress unusedFunction
172auto OpenGLCommon::GetPreRenderGeometry(const ComponentPtr_t & _pComponent) -> MatrixBuilder_t
173{
174 ::std::deque<MatrixBuilder_t> PreRenders;
175
176 auto CreatePosition = [&](const ComponentPtr_t & _pPosition)
177 {
178 // OpenGL требует фомирования мартиц тансформации в обратном порядке!
179 PreRenders.push_front([_pPosition](::glm::mat4 & _Matrix)
180 {
181 const Component::Position Pos{ *_pPosition };
182 _Matrix = ::glm::translate(_Matrix, ::glm::vec3{ Pos.X, Pos.Y, Pos.Z });
183 });
184 };
185
186 auto CreateRotation = [&](const ComponentPtr_t & _pRotation)
187 {
188 // OpenGL требует фомирования мартиц тансформации в обратном порядке!
189 PreRenders.push_front([_pRotation](::glm::mat4 & _Matrix)
190 {
191 const Component::Rotation Rot{ *_pRotation };
192 _Matrix = ::glm::rotate(_Matrix, Rot.Z, ::glm::vec3{ 0.0f, 0.0f, 1.0f });
193 _Matrix = ::glm::rotate(_Matrix, Rot.Y, ::glm::vec3{ 0.0f, 1.0f, 0.0f });
194 _Matrix = ::glm::rotate(_Matrix, Rot.X, ::glm::vec3{ 1.0f, 0.0f, 0.0f });
195 });
196 };
197
198 auto CreateScale = [&](const ComponentPtr_t & _pScale)
199 {
200 // OpenGL требует фомирования мартиц тансформации в обратном порядке!
201 PreRenders.push_front([_pScale](::glm::mat4 & _Matrix)
202 {
203 const Component::Scale Scale{ *_pScale };
204 _Matrix = ::glm::scale(_Matrix, ::glm::vec3{ Scale.X, Scale.Y, Scale.Z });
205 });
206 };
207
208 CapturingServiceComponent::Process(_pComponent,
209 {
210 { uT("Position"), CreatePosition },
211 { uT("Rotation"), CreateRotation },
212 { uT("Scale"), CreateScale },
213 });
214
215 return [PreRenders](::glm::mat4 & _Matrix)
216 {
217 for (auto & Render : PreRenders) Render(_Matrix);
218 };
219}
220
221// cppcheck-suppress unusedFunction
222auto OpenGLCommon::GetPreRenderBillboardGeometry(const ComponentPtr_t & _pComponent) -> MatrixBuilder_t
223{
224 ::std::deque<MatrixBuilder_t> PreRenders;
225
226 auto CreatePosition = [&](const ComponentPtr_t & _pPosition)
227 {
228 // OpenGL требует фомирования мартиц тансформации в обратном порядке!
229 PreRenders.push_front([_pPosition](::glm::mat4 & _Matrix)
230 {
231 const Component::Position Pos{ *_pPosition };
232 _Matrix = ::glm::translate(_Matrix, ::glm::vec3{ Pos.X, Pos.Y, Pos.Z });
233 });
234 };
235
236 CapturingServiceComponent::Process(_pComponent,
237 { { uT("Position"), CreatePosition } });
238
239 PreRenders.push_front([=](::glm::mat4 & _Matrix)
240 {
241 _Matrix[0][3] = 0.0f;
242 _Matrix[1][3] = 0.0f;
243 _Matrix[2][3] = 0.0f;
244 _Matrix[3][0] = 0.0f;
245 _Matrix[3][1] = 0.0f;
246 _Matrix[3][2] = 0.0f;
247 _Matrix[3][3] = 1.0f;
248 });
249
250 return [PreRenders](::glm::mat4 & _Matrix)
251 {
252 for (auto & Render : PreRenders) Render(_Matrix);
253 };
254}
255
256} // namespace renderer
257
258} // namespace api
259
260} // namespace covellite