1#include "ImguiRenderer.h"
3#include "../../Context.h"
4#include "../../ViewContext.h"
6#include "Input/KeyboardMapping.h"
7#include "Renderer/IRenderer.h"
8#include "Resources/ResourceStore.h"
10#include "Rendering/IGraphicsDevice.h"
11#include "Rendering/IContext.h"
12#include "Rendering/IBuffers.h"
13#include "Rendering/ITextures.h"
14#include "Rendering/IEffects.h"
15#include "Rendering/IRenderTargets.h"
16#include "Rendering/ICapabilities.h"
17#include "Rendering/CommandGroupAnnotation.h"
18#include "Services/DPIService.h"
20#include "Foundation/Logging/Logger.h"
21#include "Foundation/Platform/Keyboard.h"
22#include "Foundation/Platform/Mouse.h"
26#include "imgui_internal.h"
28#include <glm/mat4x4.hpp>
29#include <glm/ext/matrix_projection.hpp>
36 std::set<ImGuiContext*> guiContexts;
40 glm::mat4 projectionMatrix;
47 void dummyRenderCallback(
const ImDrawList* ,
const ImDrawCmd* )
49 LOG_WARNING(logger,
"Calling dummyRenderCallback");
52 ImGuiKey CogsKeyToImGuiKey(Cogs::Key key) {
54 case Cogs::Key::A:
return ImGuiKey_A;
55 case Cogs::Key::B:
return ImGuiKey_B;
56 case Cogs::Key::C:
return ImGuiKey_C;
57 case Cogs::Key::D:
return ImGuiKey_D;
58 case Cogs::Key::E:
return ImGuiKey_E;
59 case Cogs::Key::F:
return ImGuiKey_F;
60 case Cogs::Key::G:
return ImGuiKey_G;
61 case Cogs::Key::H:
return ImGuiKey_H;
62 case Cogs::Key::I:
return ImGuiKey_I;
63 case Cogs::Key::J:
return ImGuiKey_J;
64 case Cogs::Key::K:
return ImGuiKey_K;
65 case Cogs::Key::L:
return ImGuiKey_L;
66 case Cogs::Key::M:
return ImGuiKey_M;
67 case Cogs::Key::N:
return ImGuiKey_N;
68 case Cogs::Key::O:
return ImGuiKey_O;
69 case Cogs::Key::P:
return ImGuiKey_P;
70 case Cogs::Key::Q:
return ImGuiKey_Q;
71 case Cogs::Key::R:
return ImGuiKey_R;
72 case Cogs::Key::S:
return ImGuiKey_S;
73 case Cogs::Key::T:
return ImGuiKey_T;
74 case Cogs::Key::U:
return ImGuiKey_U;
75 case Cogs::Key::V:
return ImGuiKey_V;
76 case Cogs::Key::W:
return ImGuiKey_W;
77 case Cogs::Key::X:
return ImGuiKey_X;
78 case Cogs::Key::Y:
return ImGuiKey_Y;
79 case Cogs::Key::Z:
return ImGuiKey_Z;
80 case Cogs::Key::Zero:
return ImGuiKey_0;
81 case Cogs::Key::One:
return ImGuiKey_1;
82 case Cogs::Key::Two:
return ImGuiKey_2;
83 case Cogs::Key::Three:
return ImGuiKey_3;
84 case Cogs::Key::Four:
return ImGuiKey_4;
85 case Cogs::Key::Five:
return ImGuiKey_5;
86 case Cogs::Key::Six:
return ImGuiKey_6;
87 case Cogs::Key::Seven:
return ImGuiKey_7;
88 case Cogs::Key::Eight:
return ImGuiKey_8;
89 case Cogs::Key::Nine:
return ImGuiKey_9;
90 case Cogs::Key::Left:
return ImGuiKey_LeftArrow;
91 case Cogs::Key::Right:
return ImGuiKey_RightArrow;
92 case Cogs::Key::Up:
return ImGuiKey_UpArrow;
93 case Cogs::Key::Down:
return ImGuiKey_DownArrow;
94 case Cogs::Key::Shift:
95 case Cogs::Key::LeftShift:
96 case Cogs::Key::RightShift:
return ImGuiMod_Shift;
97 case Cogs::Key::Control:
98 case Cogs::Key::LeftControl:
99 case Cogs::Key::RightControl:
return ImGuiMod_Ctrl;
101 case Cogs::Key::LeftAlt:
102 case Cogs::Key::RightAlt:
return ImGuiMod_Alt;
103 case Cogs::Key::CapsLock:
return ImGuiKey_CapsLock;
104 case Cogs::Key::Tab:
return ImGuiKey_Tab;
105 case Cogs::Key::Escape:
return ImGuiKey_Escape;
106 case Cogs::Key::Enter:
return ImGuiKey_Enter;
107 case Cogs::Key::Space:
return ImGuiKey_Space;
108 case Cogs::Key::Insert:
return ImGuiKey_Insert;
109 case Cogs::Key::Delete:
return ImGuiKey_Delete;
110 case Cogs::Key::Backspace:
return ImGuiKey_Backspace;
111 case Cogs::Key::Home:
return ImGuiKey_Home;
112 case Cogs::Key::End:
return ImGuiKey_End;
113 case Cogs::Key::PageUp:
return ImGuiKey_PageUp;
114 case Cogs::Key::PageDown:
return ImGuiKey_PageDown;
115 case Cogs::Key::F1:
return ImGuiKey_F1;
116 case Cogs::Key::F2:
return ImGuiKey_F2;
117 case Cogs::Key::F3:
return ImGuiKey_F3;
118 case Cogs::Key::F4:
return ImGuiKey_F4;
119 case Cogs::Key::F5:
return ImGuiKey_F5;
120 case Cogs::Key::F6:
return ImGuiKey_F6;
121 case Cogs::Key::F7:
return ImGuiKey_F7;
122 case Cogs::Key::F8:
return ImGuiKey_F8;
123 case Cogs::Key::F9:
return ImGuiKey_F9;
124 case Cogs::Key::F10:
return ImGuiKey_F10;
125 case Cogs::Key::F11:
return ImGuiKey_F11;
126 case Cogs::Key::F12:
return ImGuiKey_F12;
127 default:
return ImGuiKey_None;
133GetClipboardTextFn Cogs::Core::ImguiRenderer::getClipboardTextFn =
nullptr;
134SetClipboardTextFn Cogs::Core::ImguiRenderer::setClipboardTextFn =
nullptr;
140 auto & defaultFont = fontRegistry.fonts[0];
141 fontRegistry.defaultFont = &defaultFont;
143 float scaleFactor = context->getDefaultView()->
dpiService->getScaleFactor();
145 this->context = context;
146 this->device = context->device;
148 imguiContext = createGuiContext();
149 ImGui::SetCurrentContext(imguiContext);
152 ImGuiIO& io = ImGui::GetIO();
153 fontGlyphBuilder = ImFontGlyphRangesBuilder();
155 fontGlyphBuilder.AddRanges(io.Fonts->GetGlyphRangesDefault());
156 fontGlyphBuilder.BuildRanges(&loadedRanges);
159 defaultFont.load(context,
"Fonts/SourceSansPro-Regular.ttf", 20 * scaleFactor, loadedRanges.Data);
161 defaultFont.load(context,
"C:/Windows/Fonts/segoeui.ttf", 16 * scaleFactor, loadedRanges.Data);
162#elif defined(__linux__)
163 defaultFont.load(context,
"/usr/share/fonts/truetype/freefont/FreeSans.ttf", 16 * scaleFactor, loadedRanges.Data);
164#elif defined(__APPLE__)
165 defaultFont.load(context,
"/System/Library/Fonts/SFNS.ttf", 16 * scaleFactor, loadedRanges.Data);
170 timer = Timer::startNew();
177void Cogs::Core::ImguiRenderer::cleanup()
180 ImGui::SetCurrentContext(imguiContext);
182 ImGui::GetIO().Fonts =
nullptr;
184 fontRegistry.fonts.clear();
185 fontRegistry.defaultFont =
nullptr;
187 deleteGuiContext(imguiContext);
188 imguiContext =
nullptr;
190 fontGlyphBuilder.Clear();
194ImGuiContext* Cogs::Core::ImguiRenderer::createGuiContext() {
195 ImGuiContext* guiContext = ImGui::CreateContext(&fontRegistry.defaultFont->fontAtlas);
197 guiContexts.insert(guiContext);
198 ImGui::SetCurrentContext(guiContext);
200 ImGuiPlatformIO platformIO = ImGui::GetPlatformIO();
207 if (getClipboardTextFn) {
208 platformIO.Platform_GetClipboardTextFn =
reinterpret_cast<const char*(*)(ImGuiContext*)
>(getClipboardTextFn);
210 if (setClipboardTextFn) {
211 platformIO.Platform_SetClipboardTextFn =
reinterpret_cast<void(*)(ImGuiContext*,
const char*)
>(setClipboardTextFn);
214 ImGui::GetStyle().ScaleAllSizes(context->getDefaultView()->dpiService->getScaleFactor());
219void Cogs::Core::ImguiRenderer::deleteGuiContext(ImGuiContext* guiContext) {
220 auto i = guiContexts.find(guiContext);
222 if (i != guiContexts.end()) {
223 guiContexts.erase(i);
226 ImGui::SetCurrentContext(guiContext);
227 ImGui::DestroyContext(guiContext);
237 for (ImGuiContext* context : guiContexts) {
238 active |= context->IO.WantCaptureMouse;
250 for (ImGuiContext* context : guiContexts) {
251 active |= context->IO.WantCaptureKeyboard;
256void Cogs::Core::ImguiRenderer::setClipboardCallbacks(GetClipboardTextFn getter, SetClipboardTextFn setter) {
257 getClipboardTextFn = getter;
258 setClipboardTextFn = setter;
260 ImGuiContext* currentContext = ImGui::GetCurrentContext();
262 for (ImGuiContext* context : guiContexts) {
263 ImGui::SetCurrentContext(context);
265 ImGuiPlatformIO& platformIO = ImGui::GetPlatformIO();
272 platformIO.Platform_GetClipboardTextFn =
reinterpret_cast<const char*(*)(ImGuiContext*)
>(getClipboardTextFn);
273 platformIO.Platform_SetClipboardTextFn =
reinterpret_cast<void(*)(ImGuiContext*,
const char*)
>(setClipboardTextFn);
275 ImGui::SetCurrentContext(currentContext);
278void Cogs::Core::ImguiRenderer::updateConstantBuffer(IContext * deviceContext, uint32_t mode)
281 const float L = 0.0f;
282 const float R = ImGui::GetIO().DisplaySize.x;
283 const float B = ImGui::GetIO().DisplaySize.y;
284 const float T = 0.0f;
286 auto M = glm::ortho(L, R, B, T);
290 switch (mode & GUI_MODE_TEX_TYPE_MASK)
292 case GUI_MODE_TEX_TYPE_2D:
295 case GUI_MODE_TEX_TYPE_ARRAY:
297 offset = mode & GUI_MODE_TEX_OFFSET_MASK;
299 case GUI_MODE_TEX_TYPE_CUBE:
301 offset = mode & GUI_MODE_TEX_OFFSET_MASK;
303 case GUI_MODE_TEX_TYPE_2DMS:
312 switch (mode & GUI_MODE_TEX_CHANNELS_MASK) {
313 case GUI_MODE_TEX_CHANNELS_RGB:
316 case GUI_MODE_TEX_CHANNELS_ALPHA:
319 case GUI_MODE_TEX_CHANNELS_RED:
322 case GUI_MODE_TEX_CHANNELS_111R:
331 if (context->renderer->getSettings().defaultRenderTargetExpectsSRGB) {
340 constants->projectionMatrix = M;
341 constants->showAlpha = showAlpha;
342 constants->texMode = texMode;
343 constants->offset = offset;
344 constants->output_sRGB = output_sRGB;
347 deviceContext->setConstantBuffer(
"ImguiBuffer", constantBuffer);
354void Cogs::Core::ImguiRenderer::frame(ImGuiContext* guiContext, ViewContext& view,
bool updateio)
356 ImGui::SetCurrentContext(guiContext);
358 ImGuiIO& io = ImGui::GetIO();
362 const std::vector<Cogs::Gesture>& gestures = view.refGestures().getGestures();
363 const Keyboard& keyboard = view.refKeyboard();
364 Cogs::PointerType pointerType = view.refGestures().getPointerType();
366 std::memset(io.MouseDown, 0,
sizeof(io.MouseDown));
368 if (pointerType == Cogs::PointerType::Touch) {
369 view.refGestures().hoverEnable =
true;
372 touchPointerPosition.x = gesture.press.coord.x;
373 touchPointerPosition.y = gesture.press.coord.y;
374 touchPointerHeld =
true;
377 touchPointerPosition.x = gesture.tap.coord.x;
378 touchPointerPosition.y = gesture.tap.coord.y;
379 touchPointerHeld =
false;
382 touchPointerPosition.x = gesture.drag.currCoord.x;
383 touchPointerPosition.y = gesture.drag.currCoord.y;
384 touchPointerHeld =
true;
387 touchPointerPosition.x = gesture.hover.coord.x;
388 touchPointerPosition.y = gesture.hover.coord.y;
393 io.MouseDown[0] = mouseState.buttonDown[MouseButton::Left] || touchPointerHeld;
394 io.MouseDown[1] = mouseState.buttonDown[MouseButton::Right];
395 io.MouseDown[2] = mouseState.buttonDown[MouseButton::Middle];
397 if (pointerType == Cogs::PointerType::Touch) {
398 io.MousePos.x =
static_cast<float>(touchPointerPosition.x);
399 io.MousePos.y =
static_cast<float>(touchPointerPosition.y);
402 io.MousePos.x =
static_cast<float>(mouseState.position.x);
403 io.MousePos.y =
static_cast<float>(mouseState.position.y);
406 io.MouseWheel = mouseState.wheel != 0 ? (mouseState.wheel > 0 ? 1.0f : -1.0f) : 0;
408 for (
const Keyboard::Event& e: keyboard.getEvents()) {
409 if ((e.type == Keyboard::Event::Type::Press) || (e.type == Keyboard::Event::Type::Release)) {
410 Key key = std::get<Key>(e.data);
411 io.AddKeyEvent(CogsKeyToImGuiKey(key), e.type == Keyboard::Event::Type::Press);
414 io.AddInputCharactersUTF8(keyboard.getState().chars.c_str());
416 io.DisplaySize = view.getSize();
419 io.DeltaTime = std::max(
static_cast<float>(timer.elapsedSeconds()), 0.000001f);
422 if (updateLoadedRanges) {
423 ImVector<ImWchar> requiredRanges;
425 fontGlyphBuilder.BuildRanges(&requiredRanges);
427 if (!std::equal(loadedRanges.begin(), loadedRanges.end(), requiredRanges.begin(), requiredRanges.end())) {
428 for (
auto& [_, font] : fontRegistry.fonts) {
429 font.reloadWithNewGlyphs(context, requiredRanges.Data);
431 loadedRanges = requiredRanges;
433 updateLoadedRanges =
false;
439void Cogs::Core::ImguiRenderer::render()
441 auto deviceContext = device->getImmediateContext();
443 CommandGroupAnnotation commandGroup(deviceContext,
"Imgui::Render");
447 auto drawData = ImGui::GetDrawData();
449 auto buffers = device->getBuffers();
452 if (!
HandleIsValid(vertexBuffer) || vertexBufferSize < drawData->TotalVtxCount) {
454 vertexBufferSize = drawData->TotalVtxCount + 5000;
456 vertexBuffer = buffers->loadVertexBuffer(
nullptr, vertexBufferSize, format);
459 if (!
HandleIsValid(indexBuffer) || indexBufferSize < drawData->TotalIdxCount) {
461 indexBufferSize = drawData->TotalIdxCount + 10000;
463 indexBuffer = buffers->loadIndexBuffer(
nullptr, indexBufferSize,
sizeof(ImDrawIdx));
471 size_t vtx_offset = 0;
472 for (
int n = 0; n < drawData->CmdListsCount; n++) {
473 const ImDrawList* commandList = drawData->CmdLists[n];
474 deviceContext->updateSubBuffer(vertexBuffer, vtx_offset,
sizeof(ImDrawVert) * commandList->VtxBuffer.size(), &commandList->VtxBuffer[0]);
475 vtx_offset +=
sizeof(ImDrawVert) * commandList->VtxBuffer.size();
478 size_t idx_offset = 0;
479 for (
int n = 0; n < drawData->CmdListsCount; n++) {
480 const ImDrawList* commandList = drawData->CmdLists[n];
481 deviceContext->updateSubBuffer(indexBuffer, idx_offset,
sizeof(ImDrawIdx) * commandList->IdxBuffer.size(), &commandList->IdxBuffer[0]);
482 idx_offset +=
sizeof(ImDrawIdx) * commandList->IdxBuffer.size();
490 if (vtx_dst && idx_dst) {
491 for (
int n = 0; n < drawData->CmdListsCount; n++) {
492 const auto commandList = drawData->CmdLists[n];
494 memcpy(vtx_dst, &commandList->VtxBuffer[0], commandList->VtxBuffer.size() *
sizeof(ImDrawVert));
495 memcpy(idx_dst, &commandList->IdxBuffer[0], commandList->IdxBuffer.size() *
sizeof(ImDrawIdx));
497 vtx_dst += commandList->VtxBuffer.size();
498 idx_dst += commandList->IdxBuffer.size();
501 deviceContext->unmap(vertexBuffer);
502 deviceContext->unmap(indexBuffer);
505 deviceContext->setViewport(0, 0, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y);
506 deviceContext->clearDepth(context->renderer->getClearDepth());
508 deviceContext->setEffect(effect);
509 const uint32_t strides[] = {
sizeof(ImDrawVert) };
510 deviceContext->setVertexBuffers(&vertexBuffer, 1, strides,
nullptr);
511 deviceContext->setIndexBuffer(indexBuffer,
sizeof(ImDrawIdx));
512 if (
HandleIsValid(inputLayout)) deviceContext->setInputLayout(inputLayout);
513 updateConstantBuffer(deviceContext, GUI_MODE_DEFAULT);
515 deviceContext->setBlendState(blendState);
516 deviceContext->setRasterizerState(rasterizerState);
517 deviceContext->setDepthStencilState(depthState);
519 switch (mode & GUI_MODE_TEX_TYPE_MASK)
521 case GUI_MODE_TEX_TYPE_2D:
523 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
525 case GUI_MODE_TEX_TYPE_ARRAY:
527 deviceContext->setSamplerState(
"texarraySampler", 3, sampler);
529 case GUI_MODE_TEX_TYPE_CUBE:
531 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
533 case GUI_MODE_TEX_TYPE_2DMS:
535 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
546 for (
int n = 0; n < drawData->CmdListsCount; n++) {
547 const ImDrawList* commandList = drawData->CmdLists[n];
549 for (
int commandIndex = 0; commandIndex < commandList->CmdBuffer.size(); commandIndex++) {
550 const ImDrawCmd* pcmd = &commandList->CmdBuffer[commandIndex];
553 updateConstantBuffer(deviceContext, (uint32_t)(uint64_t)pcmd->UserCallbackData);
556 if (pcmd->UserCallback) {
557 pcmd->UserCallback(commandList, pcmd);
559 switch (device->getType()) {
562 deviceContext->setScissor(
int(pcmd->ClipRect.x),
563 int(ImGui::GetIO().DisplaySize.y) -
int(pcmd->ClipRect.w),
564 int(pcmd->ClipRect.z) -
int(pcmd->ClipRect.x),
565 int(pcmd->ClipRect.w) -
int(pcmd->ClipRect.y));
570 deviceContext->setScissor(
int(pcmd->ClipRect.x),
571 int(pcmd->ClipRect.y),
572 int(pcmd->ClipRect.z),
573 int(pcmd->ClipRect.w));
579 deviceContext->setBlendState(blendState);
581 assert(pcmd->ElemCount > 0);
582 switch (mode & GUI_MODE_TEX_TYPE_MASK)
584 case GUI_MODE_TEX_TYPE_2D:
585 deviceContext->setTexture(
"texture0", 0, textureHandle);
586 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
588 case GUI_MODE_TEX_TYPE_ARRAY:
589 deviceContext->setTexture(
"texarray", 3, textureHandle);
590 deviceContext->setSamplerState(
"texture0Sampler", 3, sampler);
592 case GUI_MODE_TEX_TYPE_CUBE:
593 deviceContext->setTexture(
"texcube", 2, textureHandle);
594 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
596 case GUI_MODE_TEX_TYPE_2DMS:
597 deviceContext->setTexture(
"texturems", 1, textureHandle);
598 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
608 baseIndex += pcmd->ElemCount;
611 baseVertex += commandList->VtxBuffer.size();
614 auto & io = ImGui::GetIO();
616 io.ClearInputCharacters();
619void Cogs::Core::ImguiRenderer::addTextToGlyphBuilder(
const char* text)
622 fontGlyphBuilder.AddText(text);
623 updateLoadedRanges =
true;
627void Cogs::Core::ImguiRenderer::addRangeToGlyphBuilder(
const ImWchar* ranges)
629 fontGlyphBuilder.AddRanges(ranges);
630 updateLoadedRanges =
true;
633void Cogs::Core::ImguiRenderer::style()
636 float satMult = 0.0f;
637 static int hue = 146;
638 static float col_main_sat = satMult * 180.f / 255.f;
639 static float col_main_val = 161.f / 255.f;
640 static float col_area_sat = satMult * 124.f / 255.f;
641 static float col_area_val = 100.f / 255.f;
642 static float col_back_sat = satMult * 59.f / 255.f;
643 static float col_back_val = 40.f / 255.f;
645 ImGuiStyle & style = ImGui::GetStyle();
647 ImVec4 col_text = ImColor::HSV(hue / 255.f, 20.f / 255.f, 255.f / 255.f);
648 ImVec4 col_main = ImColor::HSV(hue / 255.f, col_main_sat, col_main_val);
649 ImVec4 col_back = ImColor::HSV(hue / 255.f, col_back_sat, col_back_val);
650 ImVec4 col_dark = ImColor::HSV(hue / 255.f, col_back_sat, 55 / 255.f);
651 ImVec4 col_area = ImColor::HSV(hue / 255.f, col_area_sat, col_area_val);
653 style.Colors[ImGuiCol_Text] = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
654 style.Colors[ImGuiCol_TextDisabled] = ImVec4(col_text.x, col_text.y, col_text.z, 0.58f);
655 style.Colors[ImGuiCol_WindowBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
656 style.Colors[ImGuiCol_Border] = ImVec4(col_text.x, col_text.y, col_text.z, 0.30f);
657 style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
658 style.Colors[ImGuiCol_FrameBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
659 style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.68f);
660 style.Colors[ImGuiCol_FrameBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
661 style.Colors[ImGuiCol_TitleBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.45f);
662 style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(col_main.x, col_main.y, col_main.z, 0.35f);
663 style.Colors[ImGuiCol_TitleBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
664 style.Colors[ImGuiCol_MenuBarBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
665 style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
666 style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.31f);
667 style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
668 style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
669 style.Colors[ImGuiCol_CheckMark] = ImVec4(col_main.x, col_main.y, col_main.z, 0.80f);
670 style.Colors[ImGuiCol_SliderGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.24f);
671 style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
672 style.Colors[ImGuiCol_Button] = ImVec4(col_main.x, col_main.y, col_main.z, 0.44f);
673 style.Colors[ImGuiCol_ButtonHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.86f);
674 style.Colors[ImGuiCol_ButtonActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
675 style.Colors[ImGuiCol_Header] = ImVec4(col_main.x, col_main.y, col_main.z, 0.76f);
676 style.Colors[ImGuiCol_HeaderHovered] = ImVec4(col_dark.x, col_dark.y, col_dark.z, 0.86f);
677 style.Colors[ImGuiCol_HeaderActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
678 style.Colors[ImGuiCol_ResizeGrip] = ImVec4(col_main.x, col_main.y, col_main.z, 0.20f);
679 style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
680 style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
681 style.Colors[ImGuiCol_PlotLines] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
682 style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
683 style.Colors[ImGuiCol_PlotHistogram] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
684 style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
685 style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.43f);
686 style.Colors[ImGuiCol_PopupBg] = ImVec4(col_back.x, col_back.y, col_back.z, 0.99f);
687 style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
689 style.WindowRounding = 2.0f;
690 style.WindowBorderSize = 0.0f;
693void Cogs::Core::ImguiRenderer::createSampler()
695 SamplerState fs = {};
699 sampler = device->getTextures()->loadSamplerState(fs);
702bool Cogs::Core::ImguiRenderer::createResources()
704 VertexElement elements[] = {
709 format = device->getBuffers()->createVertexFormat(elements, glm::countof(elements));
712 desc.name =
"ImguiEffect";
715 switch (device->getType()) {
718 desc.vertexShader =
"Engine/ImguiVS.wgsl";
719 desc.pixelShader =
"Engine/ImguiPS.wgsl";
720 desc.vsEntryPoint =
"vs_main";
721 desc.psEntryPoint =
"fs_main";
730 desc.vertexShader =
"Engine/ImguiVS.es30.glsl";
731 desc.pixelShader =
"Engine/ImguiPS.es30.glsl";
736 desc.vertexShader =
"Engine/ImguiVS.hlsl";
737 desc.pixelShader =
"Engine/ImguiPS.hlsl";
740 effect = device->getEffects()->loadEffect(desc);
741 inputLayout = device->getBuffers()->loadInputLayout(&format, 1, effect);
744 device->getBuffers()->annotate(constantBuffer,
"ImGui");
748 bs.sourceBlend = BlendState::Blend::SourceAlpha;
749 bs.destinationBlend = BlendState::Blend::InverseSourceAlpha;
750 bs.operation = BlendState::BlendOperation::Add;
752 blendState = device->getRenderTargets()->loadBlendState(bs);
754 RasterizerState rs = {};
756 rs.frontCounterClockwise =
false;
757 rs.wireFrame =
false;
760 rasterizerState = device->getRenderTargets()->loadRasterizerState(rs);
762 DepthStencilState ds = {};
763 ds.depthEnabled =
false;
766 depthState = device->getRenderTargets()->loadDepthStencilState(ds);
773void Cogs::Core::GuiFont::load(
const Context * context,
const std::string& name,
float size,
const ImWchar* glyphRanges)
776 auto fontBytes = context->resourceStore->getResourceContents(name);
777 if (fontBytes.empty()) {
778 static const std::string fallbackFont =
"Fonts/Inconsolata-Regular.ttf";
780 LOG_WARNING(logger,
"Failed to read font %.*s, trying %s", StringViewFormat(name), fallbackFont.c_str());
781 fontBytes = context->resourceStore->getResourceContents(fallbackFont);
785 unsigned char* pixels;
789 config.FontDataOwnedByAtlas =
false;
793 for (
int i = 0; i < cNoOfFontSizes; ++i, size += initialSize) {
794 font[i] = fontAtlas.AddFontFromMemoryTTF(fontBytes.data(),
static_cast<int>(fontBytes.size()), size, &config, glyphRanges);
796 fontAtlas.GetTexDataAsRGBA32(&pixels, &width, &height);
797 fontAtlas.TexID = context->device->getTextures()->loadTexture(pixels, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB, 0).handle;
800void Cogs::Core::GuiFont::reloadWithNewGlyphs(
const Context* context,
const ImWchar* glyphRanges) {
801 load(context, path, initialSize, glyphRanges);
804ImFont* Cogs::Core::GuiFont::find(
float size,
float& scale)
const {
806 float fontSize = initialSize;
808 for (; idx < (cNoOfFontSizes - 1); ++idx, fontSize += initialSize) {
809 if (size <= (fontSize + (fontSize * 0.3f))) {
813 scale = size / fontSize;
A Context instance contains all the services, systems and runtime components needed to use Cogs.
static bool isUsingMouse()
Tests whether any ImGui control is being interacted with, or if the mouse is over an ImGui window or ...
static bool isUsingKeyboard()
Tests whether any ImGui control is currently accepting text input.
std::unique_ptr< class DPIService > dpiService
DPI service instance.
Log implementation class.
bool HandleIsValid(const ResourceHandle_t< T > &handle)
Check if the given resource is valid, that is not equal to NoHandle or InvalidHandle.
ImDrawCallback setGuiMode
Callback for Render updates - not really called.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
@ OpenGLES30
Graphics device using the OpenGLES 3.0 API.
@ OpenGL20
Graphics device using OpenGL, supporting at least OpenGL 2.0.
@ WebGPU
Graphics device using the WebGPU API Backend.
@ VertexData
Per vertex data.
std::pair< std::string, std::string > PreprocessorDefinition
Preprocessor definition.
@ Position
Position semantic.
@ TextureCoordinate
Texture coordinate semantic.
@ Write
The buffer can be mapped and written to by the CPU after creation.
@ ConstantBuffer
The buffer can be bound as input to effects as a constant buffer.
@ Always
Always evaluates to true.
Contains an effect description used to load a single effect.
EEffectFlags
Effect source flags.
@ WGSL
Effect source is WGSL.
@ GLSL
Effect source is GLSL.
@ Press
A long press, a press that was too long to be a tap, events on press start and end.
@ Tap
A short press, see tapMaxDuration, single-fire event.
@ Drag
Pointer movement with a button pressed or touch, see mouseMoveThreshold and touchMoveThreshold,...
@ Hover
Mouse pointer hovers over window without any buttons pressed, single-fire event.
static const Handle_t NoHandle
Represents a handle to nothing.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
@ TriangleList
List of triangles.
@ None
Do not perform any face culling.
@ Clamp
Texture coordinates are clamped to the [0, 1] range.
@ MinMagMipLinear
Linear sampling for both minification and magnification.
@ Dynamic
Buffer will be loaded and modified with some frequency.