2#include "Rendering/IGraphicsDevice.h"
3#include "Rendering/ICapabilities.h"
6#include "InspectorGuiHelper.h"
8#include "Renderer/Renderer.h"
9#include "Renderer/InspectorGui/InspectorGuiRenderer.h"
10#include "Resources/TextureManager.h"
11#include "Renderer/RenderTexture.h"
12#include "Systems/Core/LightSystem.h"
13#include "Utilities/Math.h"
18 bool orient2D(
const float * P,
const size_t stride,
const unsigned ia,
const unsigned ib,
const unsigned ic)
20 auto a = glm::make_vec2(P + stride * ia);
21 auto b = glm::make_vec2(P + stride * ib);
22 auto c = glm::make_vec2(P + stride * ic);
23 auto ab = glm::vec3(b - a, 0);
24 auto ac = glm::vec3(c - a, 0);
25 return 0.f < glm::cross(ab, ac).z;
31 void basicConvexHull2D(
Context* , std::vector<unsigned>& loop,
const float* P,
const size_t stride,
const size_t N)
38 auto ll = glm::make_vec2(P + k0 * stride);
39 for (
unsigned i = 1; i < n; i++) {
40 auto p = glm::make_vec2(P + i * stride);
41 if (p.x < ll.x || (p.x == ll.x && p.y < ll.y)) {
48 while (loop.size() < N)
51 for (
unsigned j = 1; j < n; j++) {
52 if (e == loop.back() || orient2D(P, stride, j, loop.back(), e)) {
56 if (loop.front() == e) {
65 std::vector<ImVec2> buildConvexHull(
Context* context,
const ImVec2 o, std::vector<glm::vec3>& P,
float s,
const glm::mat4& M)
67 std::vector<unsigned> loop;
68 basicConvexHull2D(context, loop,
reinterpret_cast<float*
>(P.data()), 3, P.size());
69 std::vector<ImVec2> loop_points;
70 for (
auto & ix : loop) {
72 auto q = glm::vec2(s / 2.f)* (glm::vec2(euclidean(M * glm::vec4(p, 1))) + glm::vec2(1));
73 loop_points.push_back(ImVec2(o.x + q.x, o.y + q.y));
78 std::vector<ImVec2> buildConvexHull(
Context* context,
const ImVec2 o, std::vector<glm::vec3>& P,
float scale,
float s,
const glm::vec2& c)
80 std::vector<unsigned> loop;
81 basicConvexHull2D(context, loop,
reinterpret_cast<float*
>(P.data()), 3, P.size());
82 std::vector<ImVec2> loop_points;
83 for (
auto & ix : loop) {
85 auto q = glm::vec2(o.x, o.y) + scale * (glm::vec2(r) - c) + glm::vec2(s / 2);
86 loop_points.push_back(ImVec2(q.x, q.y));
94void Cogs::Core::shadowMapInspector(
Context * context,
bool * show)
96 if (*show ==
false)
return;
99 guiBegin(
"Shadow maps", show);
101 float expFactor = context->
variables->get(
"shadows.cascades.expFactor")->getFloat();
102 if (ImGui::InputFloat(
"shadows.cascades.expFactor", &expFactor, 0.025f, 0.1f)) {
103 context->
variables->set(
"shadows.cascades.expFactor", glm::clamp(expFactor, 0.f, 1.f));
107 float overlapFactor = context->
variables->get(
"shadows.cascades.overlapFactor")->getFloat();
108 if (ImGui::InputFloat(
"shadows.cascades.overlapFactor", &overlapFactor, 0.025f, 0.1f)) {
109 context->
variables->set(
"shadows.cascades.overlapFactor", glm::clamp(overlapFactor, 0.f, 1.f));
113 float maxShadowDistance = context->
variables->get(
"renderer.maxShadowDistance")->getFloat();
114 if (ImGui::InputFloat(
"renderer.maxShadowDistance", &maxShadowDistance, 10.f, 1000.f)) {
115 context->
variables->set(
"renderer.maxShadowDistance", glm::clamp(maxShadowDistance, 0.f, 100000.f));
119 bool flipTexture =
false;
129 for (
auto & lightComp : context->lightSystem->pool) {
130 auto * entity = lightComp.getContainer();
132 auto name = entity->getName() +
" (" + std::to_string(entity->getId()) +
")";
135 if (lightComp.enabled ==
false) {
136 name +=
" (disabled)";
139 else if (lightComp.castShadows ==
false) {
140 name +=
" (casts no shadows)";
145 IM_COL32(255, 255, 0, 255),
146 IM_COL32(0, 255, 0, 255),
147 IM_COL32(0, 0, 255, 255),
148 IM_COL32(255, 0, 255, 255)
150 ImU32 colors_light[4] = {
151 IM_COL32(255, 255, 200, 255),
152 IM_COL32(200, 255, 200, 255),
153 IM_COL32(200, 200, 255, 255),
154 IM_COL32(255, 200, 255, 255)
157 if (ImGui::CollapsingHeader(getUniqueHeader(name).c_str(), ImGuiTreeNodeFlags_DefaultOpen | (empty? ImGuiTreeNodeFlags_Leaf:0)) && !empty) {
158 auto & lightData = context->lightSystem->getData(&lightComp);
159 auto * texture = lightData.shadowTexture.resolve();
161 if (lightComp.lightType == LightType::Directional) {
162 lightData.frustaPointsCapture =
true;
163 const auto s = 256.0f;
164 auto dl = ImGui::GetWindowDrawList();
166 auto o = ImGui::GetCursorScreenPos();
167 ImGui::InvisibleButton(getUniqueHeader(name +
" canvas").c_str(), ImVec2(s, s));
169 auto viewportMin = lightData.frustaPoints[0].viewportMin;
170 auto viewportMax = lightData.frustaPoints[0].viewportMax;
171 for (
unsigned i = 0; i < lightData.numViewports; i++) {
172 auto & frustumPoints = lightData.frustaPoints[i];
173 viewportMin = glm::min(viewportMin, frustumPoints.viewportMin);
174 viewportMax = glm::max(viewportMax, frustumPoints.viewportMax);
176 auto size = glm::max(viewportMax.x - viewportMin.x,
177 viewportMax.y - viewportMin.y);
178 auto scale = s / size;
180 auto c = 0.5f*(viewportMin + viewportMax);
182 for (
int i = lightData.numViewports - 1; 0 <= i; --i) {
183 RenderTexture * renderTexture = renderer->getRenderResources().getRenderTexture(context->textureManager->generateHandle((
Texture *)texture));
185 auto & frustumPoints = lightData.frustaPoints[i];
186 auto a = glm::vec2(o.x, o.y) + scale * (frustumPoints.viewportMin - c) + glm::vec2(s / 2);
187 auto b = glm::vec2(o.x, o.y) + scale * (frustumPoints.viewportMax - c) + glm::vec2(s / 2);
189 dl->AddCallback(
setGuiMode, (
void*)(uint64_t)(GUI_MODE_TEX_CHANNELS_RED | GUI_MODE_TEX_TYPE_ARRAY | (lightData.arrayOffset + i)));
192 dl->AddImage(ImTextureID(renderTexture->textureHandle.
handle), ImVec2(a.x, a.y), ImVec2(b.x, b.y), ImVec2(0, 0), ImVec2(1, 1), colors_light[i & 3]);
195 dl->AddImage(ImTextureID(renderTexture->textureHandle.
handle), ImVec2(a.x, a.y), ImVec2(b.x, b.y), ImVec2(0, 1), ImVec2(1, 0), colors_light[i & 3]);
199 dl->AddCallback(
setGuiMode, (
void*)(GUI_MODE_DEFAULT));
202 for (
unsigned i = 0; i < lightData.numViewports; i++) {
203 auto loop_points = buildConvexHull(context, o, lightData.frustaPoints[i].points, scale, s, c);
204 dl->AddPolyline(loop_points.data(),
int(loop_points.size()), colors[i & 3],
true, 1.f);
214 for (
unsigned i = 0; i < lightData.numViewports; i++) {
215 auto & lightCameraData = lightData.lightCameraData[i];
217 RenderTexture * renderTexture = renderer->getRenderResources().getRenderTexture(context->textureManager->generateHandle((
Texture *)texture));
218 if (!renderTexture)
continue;
222 auto oo = ImGui::GetCursorScreenPos();
223 ImGui::InvisibleButton(getUniqueHeader(name +
" canvas lod" + std::to_string(i)).c_str(), ImVec2(s, s));
225 dl->AddCallback(
setGuiMode, (
void*)(uint64_t)(GUI_MODE_TEX_CHANNELS_RED | GUI_MODE_TEX_TYPE_ARRAY | (lightData.arrayOffset + i)));
227 dl->AddImage(ImTextureID(renderTexture->textureHandle.
handle), oo, ImVec2(oo.x + s, oo.y + s), ImVec2(0, 0), ImVec2(1, 1), colors_light[i & 3]);
230 dl->AddImage(ImTextureID(renderTexture->textureHandle.
handle), oo, ImVec2(oo.x + s, oo.y + s), ImVec2(0, 1), ImVec2(1, 0), colors_light[i & 3]);
233 dl->AddCallback(
setGuiMode, (
void*)(GUI_MODE_DEFAULT));
237 glm::vec4 cullBox_in[4] =
239 glm::vec4(-1, -1, 0, 1),
240 glm::vec4(1, -1, 0, 1),
241 glm::vec4(1, 1, 0, 1),
242 glm::vec4(-1, 1, 0, 1),
246 auto M = lightCameraData.rawViewProjection * glm::inverse(lightCameraData.rawViewCullMatrix);
248 for (
unsigned j = 0; j < 4; j++) {
249 const auto q = glm::vec2(s / 2.f) * (glm::vec2(euclidean(M * cullBox_in[j])) + glm::vec2(1));
250 cullBox[j] = ImVec2(oo.x + q.x, oo.y + q.y);
253 ImGui::PushClipRect(oo, ImVec2(oo.x + s, oo.y + s),
true);
254 dl->AddPolyline(cullBox, 4, colors[i & 3],
true, 1.f);
255 ImGui::PopClipRect();
258 auto loop_points = buildConvexHull(context, oo, lightData.frustaPoints[i].points, s, lightCameraData.rawProjectionMatrix);
259 dl->AddPolyline(loop_points.data(),
int(loop_points.size()), colors[i & 3],
true, 3.f);
261 for (
auto & r : lightData.frustaPoints[i].points) {
262 auto q = glm::vec2(s/2.f)* (glm::vec2(euclidean(lightCameraData.rawProjectionMatrix * glm::vec4(r, 1))) + glm::vec2(1));
263 dl->AddCircleFilled(ImVec2(oo.x + q.x, oo.y + q.y), 4.f, colors[i & 3]);
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class IRenderer * renderer
Renderer.
std::unique_ptr< class Variables > variables
Variables service instance.
virtual IGraphicsDevice * getDevice()=0
Get the graphics device used by the renderer.
virtual GraphicsDeviceType getType() const
Get the type of the graphics device.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
ImDrawCallback setGuiMode
Callback for Render updates - not really called.
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
Texture resources contain raster bitmap data to use for texturing.
handle_type handle
Internal resource handle.