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>
37 std::set<ImGuiContext*> guiContexts;
41 glm::mat4 projectionMatrix;
48 void dummyRenderCallback(
const ImDrawList* ,
const ImDrawCmd* )
50 LOG_WARNING(logger,
"Calling dummyRenderCallback");
53 ImGuiKey CogsKeyToImGuiKey(Cogs::Key key) {
55 case Cogs::Key::A:
return ImGuiKey_A;
56 case Cogs::Key::B:
return ImGuiKey_B;
57 case Cogs::Key::C:
return ImGuiKey_C;
58 case Cogs::Key::D:
return ImGuiKey_D;
59 case Cogs::Key::E:
return ImGuiKey_E;
60 case Cogs::Key::F:
return ImGuiKey_F;
61 case Cogs::Key::G:
return ImGuiKey_G;
62 case Cogs::Key::H:
return ImGuiKey_H;
63 case Cogs::Key::I:
return ImGuiKey_I;
64 case Cogs::Key::J:
return ImGuiKey_J;
65 case Cogs::Key::K:
return ImGuiKey_K;
66 case Cogs::Key::L:
return ImGuiKey_L;
67 case Cogs::Key::M:
return ImGuiKey_M;
68 case Cogs::Key::N:
return ImGuiKey_N;
69 case Cogs::Key::O:
return ImGuiKey_O;
70 case Cogs::Key::P:
return ImGuiKey_P;
71 case Cogs::Key::Q:
return ImGuiKey_Q;
72 case Cogs::Key::R:
return ImGuiKey_R;
73 case Cogs::Key::S:
return ImGuiKey_S;
74 case Cogs::Key::T:
return ImGuiKey_T;
75 case Cogs::Key::U:
return ImGuiKey_U;
76 case Cogs::Key::V:
return ImGuiKey_V;
77 case Cogs::Key::W:
return ImGuiKey_W;
78 case Cogs::Key::X:
return ImGuiKey_X;
79 case Cogs::Key::Y:
return ImGuiKey_Y;
80 case Cogs::Key::Z:
return ImGuiKey_Z;
81 case Cogs::Key::Zero:
return ImGuiKey_0;
82 case Cogs::Key::One:
return ImGuiKey_1;
83 case Cogs::Key::Two:
return ImGuiKey_2;
84 case Cogs::Key::Three:
return ImGuiKey_3;
85 case Cogs::Key::Four:
return ImGuiKey_4;
86 case Cogs::Key::Five:
return ImGuiKey_5;
87 case Cogs::Key::Six:
return ImGuiKey_6;
88 case Cogs::Key::Seven:
return ImGuiKey_7;
89 case Cogs::Key::Eight:
return ImGuiKey_8;
90 case Cogs::Key::Nine:
return ImGuiKey_9;
91 case Cogs::Key::Left:
return ImGuiKey_LeftArrow;
92 case Cogs::Key::Right:
return ImGuiKey_RightArrow;
93 case Cogs::Key::Up:
return ImGuiKey_UpArrow;
94 case Cogs::Key::Down:
return ImGuiKey_DownArrow;
95 case Cogs::Key::Shift:
96 case Cogs::Key::LeftShift:
97 case Cogs::Key::RightShift:
return ImGuiMod_Shift;
98 case Cogs::Key::Control:
99 case Cogs::Key::LeftControl:
100 case Cogs::Key::RightControl:
return ImGuiMod_Ctrl;
102 case Cogs::Key::LeftAlt:
103 case Cogs::Key::RightAlt:
return ImGuiMod_Alt;
104 case Cogs::Key::CapsLock:
return ImGuiKey_CapsLock;
105 case Cogs::Key::Tab:
return ImGuiKey_Tab;
106 case Cogs::Key::Escape:
return ImGuiKey_Escape;
107 case Cogs::Key::Enter:
return ImGuiKey_Enter;
108 case Cogs::Key::Space:
return ImGuiKey_Space;
109 case Cogs::Key::Insert:
return ImGuiKey_Insert;
110 case Cogs::Key::Delete:
return ImGuiKey_Delete;
111 case Cogs::Key::Backspace:
return ImGuiKey_Backspace;
112 case Cogs::Key::Home:
return ImGuiKey_Home;
113 case Cogs::Key::End:
return ImGuiKey_End;
114 case Cogs::Key::PageUp:
return ImGuiKey_PageUp;
115 case Cogs::Key::PageDown:
return ImGuiKey_PageDown;
116 case Cogs::Key::F1:
return ImGuiKey_F1;
117 case Cogs::Key::F2:
return ImGuiKey_F2;
118 case Cogs::Key::F3:
return ImGuiKey_F3;
119 case Cogs::Key::F4:
return ImGuiKey_F4;
120 case Cogs::Key::F5:
return ImGuiKey_F5;
121 case Cogs::Key::F6:
return ImGuiKey_F6;
122 case Cogs::Key::F7:
return ImGuiKey_F7;
123 case Cogs::Key::F8:
return ImGuiKey_F8;
124 case Cogs::Key::F9:
return ImGuiKey_F9;
125 case Cogs::Key::F10:
return ImGuiKey_F10;
126 case Cogs::Key::F11:
return ImGuiKey_F11;
127 case Cogs::Key::F12:
return ImGuiKey_F12;
128 default:
return ImGuiKey_None;
134GetClipboardTextFn Cogs::Core::ImguiRenderer::getClipboardTextFn =
nullptr;
135SetClipboardTextFn Cogs::Core::ImguiRenderer::setClipboardTextFn =
nullptr;
141 auto & defaultFont = fontRegistry.fonts[0];
142 fontRegistry.defaultFont = &defaultFont;
144 float scaleFactor = context->getDefaultView()->
dpiService->getScaleFactor();
146 this->context = context;
147 this->device = context->device;
149 imguiContext = createGuiContext();
150 ImGui::SetCurrentContext(imguiContext);
153 ImGuiIO& io = ImGui::GetIO();
154 fontGlyphBuilder = ImFontGlyphRangesBuilder();
156 fontGlyphBuilder.AddRanges(io.Fonts->GetGlyphRangesDefault());
157 fontGlyphBuilder.BuildRanges(&loadedRanges);
160 defaultFont.load(context,
"Fonts/SourceSansPro-Regular.ttf", 20 * scaleFactor, loadedRanges.Data);
162 defaultFont.load(context,
"C:/Windows/Fonts/segoeui.ttf", 16 * scaleFactor, loadedRanges.Data);
163#elif defined(__linux__)
164 defaultFont.load(context,
"/usr/share/fonts/truetype/freefont/FreeSans.ttf", 16 * scaleFactor, loadedRanges.Data);
165#elif defined(__APPLE__)
166 defaultFont.load(context,
"/System/Library/Fonts/SFNS.ttf", 16 * scaleFactor, loadedRanges.Data);
171 timer = Timer::startNew();
178void Cogs::Core::ImguiRenderer::cleanup()
181 ImGui::SetCurrentContext(imguiContext);
183 ImGui::GetIO().Fonts =
nullptr;
185 fontRegistry.fonts.clear();
186 fontRegistry.defaultFont =
nullptr;
188 deleteGuiContext(imguiContext);
189 imguiContext =
nullptr;
191 fontGlyphBuilder.Clear();
195ImGuiContext* Cogs::Core::ImguiRenderer::createGuiContext() {
196 ImGuiContext* guiContext = ImGui::CreateContext(&fontRegistry.defaultFont->fontAtlas);
198 guiContexts.insert(guiContext);
199 ImGui::SetCurrentContext(guiContext);
201 ImGuiPlatformIO platformIO = ImGui::GetPlatformIO();
208 if (getClipboardTextFn) {
209 platformIO.Platform_GetClipboardTextFn =
reinterpret_cast<const char*(*)(ImGuiContext*)
>(getClipboardTextFn);
211 if (setClipboardTextFn) {
212 platformIO.Platform_SetClipboardTextFn =
reinterpret_cast<void(*)(ImGuiContext*,
const char*)
>(setClipboardTextFn);
215 ImGui::GetStyle().ScaleAllSizes(context->getDefaultView()->dpiService->getScaleFactor());
220void Cogs::Core::ImguiRenderer::deleteGuiContext(ImGuiContext* guiContext) {
221 auto i = guiContexts.find(guiContext);
223 if (i != guiContexts.end()) {
224 guiContexts.erase(i);
227 ImGui::SetCurrentContext(guiContext);
228 ImGui::DestroyContext(guiContext);
238 for (ImGuiContext* context : guiContexts) {
239 active |= context->IO.WantCaptureMouse;
251 for (ImGuiContext* context : guiContexts) {
252 active |= context->IO.WantCaptureKeyboard;
257void Cogs::Core::ImguiRenderer::setClipboardCallbacks(GetClipboardTextFn getter, SetClipboardTextFn setter) {
258 getClipboardTextFn = getter;
259 setClipboardTextFn = setter;
261 ImGuiContext* currentContext = ImGui::GetCurrentContext();
263 for (ImGuiContext* context : guiContexts) {
264 ImGui::SetCurrentContext(context);
266 ImGuiPlatformIO& platformIO = ImGui::GetPlatformIO();
273 platformIO.Platform_GetClipboardTextFn =
reinterpret_cast<const char*(*)(ImGuiContext*)
>(getClipboardTextFn);
274 platformIO.Platform_SetClipboardTextFn =
reinterpret_cast<void(*)(ImGuiContext*,
const char*)
>(setClipboardTextFn);
276 ImGui::SetCurrentContext(currentContext);
279void Cogs::Core::ImguiRenderer::updateConstantBuffer(IContext * deviceContext, uint32_t mode)
282 const float L = 0.0f;
283 const float R = ImGui::GetIO().DisplaySize.x;
284 const float B = ImGui::GetIO().DisplaySize.y;
285 const float T = 0.0f;
287 auto M = glm::ortho(L, R, B, T);
291 switch (mode & GUI_MODE_TEX_TYPE_MASK)
293 case GUI_MODE_TEX_TYPE_2D:
296 case GUI_MODE_TEX_TYPE_ARRAY:
298 offset = mode & GUI_MODE_TEX_OFFSET_MASK;
300 case GUI_MODE_TEX_TYPE_CUBE:
302 offset = mode & GUI_MODE_TEX_OFFSET_MASK;
304 case GUI_MODE_TEX_TYPE_2DMS:
313 switch (mode & GUI_MODE_TEX_CHANNELS_MASK) {
314 case GUI_MODE_TEX_CHANNELS_RGB:
317 case GUI_MODE_TEX_CHANNELS_ALPHA:
320 case GUI_MODE_TEX_CHANNELS_RED:
323 case GUI_MODE_TEX_CHANNELS_111R:
326 case GUI_MODE_TEX_CHANNELS_111INVR:
335 if (context->renderer->getSettings().defaultRenderTargetExpectsSRGB) {
344 constants->projectionMatrix = M;
345 constants->showAlpha = showAlpha;
346 constants->texMode = texMode;
347 constants->offset = offset;
348 constants->output_sRGB = output_sRGB;
351 deviceContext->setConstantBuffer(
"ImguiBuffer", constantBuffer);
358void Cogs::Core::ImguiRenderer::frame(ImGuiContext* guiContext, ViewContext& view,
bool updateio)
360 ImGui::SetCurrentContext(guiContext);
362 ImGuiIO& io = ImGui::GetIO();
363 const Keyboard& keyboard = view.refKeyboard();
367 const std::vector<Cogs::Gesture>& gestures = view.refGestures().getGestures();
368 Cogs::PointerType pointerType = view.refGestures().getPointerType();
370 std::memset(io.MouseDown, 0,
sizeof(io.MouseDown));
372 if (pointerType == Cogs::PointerType::Touch) {
373 view.refGestures().hoverEnable =
true;
376 touchPointerPosition.x = gesture.press.coord.x;
377 touchPointerPosition.y = gesture.press.coord.y;
378 touchPointerHeld =
true;
381 touchPointerPosition.x = gesture.tap.coord.x;
382 touchPointerPosition.y = gesture.tap.coord.y;
383 touchPointerHeld =
false;
386 touchPointerPosition.x = gesture.drag.currCoord.x;
387 touchPointerPosition.y = gesture.drag.currCoord.y;
388 touchPointerHeld =
true;
391 touchPointerPosition.x = gesture.hover.coord.x;
392 touchPointerPosition.y = gesture.hover.coord.y;
397 io.MouseDown[0] = mouseState.buttonDown[MouseButton::Left] || touchPointerHeld;
398 io.MouseDown[1] = mouseState.buttonDown[MouseButton::Right];
399 io.MouseDown[2] = mouseState.buttonDown[MouseButton::Middle];
401 if (pointerType == Cogs::PointerType::Touch) {
402 io.MousePos.x = touchPointerPosition.x;
403 io.MousePos.y = touchPointerPosition.y;
406 io.MousePos.x = mouseState.position.x;
407 io.MousePos.y = mouseState.position.y;
410 io.MouseWheel = mouseState.wheel != 0 ? (mouseState.wheel > 0 ? 1.0f : -1.0f) : 0;
412 for (
const Keyboard::Event& e: keyboard.getEvents()) {
413 if ((e.type == Keyboard::Event::Type::Press) || (e.type == Keyboard::Event::Type::Release)) {
414 io.AddKeyEvent(CogsKeyToImGuiKey(std::get<Key>(e.data)), e.type == Keyboard::Event::Type::Press);
417 io.AddInputCharactersUTF8(keyboard.getState().chars.c_str());
420 for (
const Keyboard::Event& e: keyboard.getEvents()) {
421 if (e.type == Keyboard::Event::Type::Release) {
422 io.AddKeyEvent(CogsKeyToImGuiKey(std::get<Key>(e.data)),
false);
426 io.DisplaySize = view.getSize();
429 io.DeltaTime = std::max(
static_cast<float>(timer.elapsedSeconds()), 0.000001f);
432 if (updateLoadedRanges) {
433 ImVector<ImWchar> requiredRanges;
435 fontGlyphBuilder.BuildRanges(&requiredRanges);
437 if (!std::equal(loadedRanges.begin(), loadedRanges.end(), requiredRanges.begin(), requiredRanges.end())) {
438 for (
auto& [_, font] : fontRegistry.fonts) {
439 font.reloadWithNewGlyphs(context, requiredRanges.Data);
441 loadedRanges = requiredRanges;
443 updateLoadedRanges =
false;
449void Cogs::Core::ImguiRenderer::render()
455 inputLayout = device->getBuffers()->loadInputLayout(&format, 1, effect);
459 LOG_ERROR(logger,
"ImguiRenderer: Invalid imgui effect handle.");
462 effectStatus = status;
464 auto deviceContext = device->getImmediateContext();
466 CommandGroupAnnotation commandGroup(deviceContext,
"Imgui::Render");
476 auto drawData = ImGui::GetDrawData();
478 auto buffers = device->getBuffers();
481 if (!
HandleIsValid(vertexBuffer) || vertexBufferSize < drawData->TotalVtxCount) {
483 vertexBufferSize = drawData->TotalVtxCount + 5000;
485 vertexBuffer = buffers->loadVertexBuffer(
nullptr, vertexBufferSize, format);
488 if (!
HandleIsValid(indexBuffer) || indexBufferSize < drawData->TotalIdxCount) {
490 indexBufferSize = drawData->TotalIdxCount + 10000;
492 indexBuffer = buffers->loadIndexBuffer(
nullptr, indexBufferSize,
sizeof(ImDrawIdx));
500 size_t vtx_offset = 0;
501 for (
int n = 0; n < drawData->CmdListsCount; n++) {
502 const ImDrawList* commandList = drawData->CmdLists[n];
503 deviceContext->updateSubBuffer(vertexBuffer, vtx_offset,
sizeof(ImDrawVert) * commandList->VtxBuffer.size(), &commandList->VtxBuffer[0]);
504 vtx_offset +=
sizeof(ImDrawVert) * commandList->VtxBuffer.size();
507 size_t idx_offset = 0;
508 for (
int n = 0; n < drawData->CmdListsCount; n++) {
509 const ImDrawList* commandList = drawData->CmdLists[n];
510 deviceContext->updateSubBuffer(indexBuffer, idx_offset,
sizeof(ImDrawIdx) * commandList->IdxBuffer.size(), &commandList->IdxBuffer[0]);
511 idx_offset +=
sizeof(ImDrawIdx) * commandList->IdxBuffer.size();
519 if (vtx_dst && idx_dst) {
520 for (
int n = 0; n < drawData->CmdListsCount; n++) {
521 const auto commandList = drawData->CmdLists[n];
523 memcpy(vtx_dst, &commandList->VtxBuffer[0], commandList->VtxBuffer.size() *
sizeof(ImDrawVert));
524 memcpy(idx_dst, &commandList->IdxBuffer[0], commandList->IdxBuffer.size() *
sizeof(ImDrawIdx));
526 vtx_dst += commandList->VtxBuffer.size();
527 idx_dst += commandList->IdxBuffer.size();
530 deviceContext->unmap(vertexBuffer);
531 deviceContext->unmap(indexBuffer);
534 deviceContext->setViewport(0, 0, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y);
535 deviceContext->clearDepth(context->renderer->getClearDepth());
537 deviceContext->setEffect(effect);
538 const uint32_t strides[] = {
sizeof(ImDrawVert) };
539 deviceContext->setVertexBuffers(&vertexBuffer, 1, strides,
nullptr);
540 deviceContext->setIndexBuffer(indexBuffer,
sizeof(ImDrawIdx));
541 if (
HandleIsValid(inputLayout)) deviceContext->setInputLayout(inputLayout);
542 updateConstantBuffer(deviceContext, GUI_MODE_DEFAULT);
544 deviceContext->setBlendState(blendState);
545 deviceContext->setRasterizerState(rasterizerState);
546 deviceContext->setDepthStencilState(depthState);
548 deviceContext->setTexture(
"texture0", 0, dummyTex2D);
549 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
551 deviceContext->setTexture(
"texturems", 1, dummyTex2DMS);
552 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
554 deviceContext->setTexture(
"texcube", 2, dummyTexCube);
555 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
557 deviceContext->setTexture(
"texarray", 3, dummyTex2DArray);
558 deviceContext->setSamplerState(
"texarraySampler", 3, sampler);
564 for (
int n = 0; n < drawData->CmdListsCount; n++) {
565 const ImDrawList* commandList = drawData->CmdLists[n];
567 for (
int commandIndex = 0; commandIndex < commandList->CmdBuffer.size(); commandIndex++) {
568 const ImDrawCmd* pcmd = &commandList->CmdBuffer[commandIndex];
571 updateConstantBuffer(deviceContext, (uint32_t)(uint64_t)pcmd->UserCallbackData);
574 if (pcmd->UserCallback) {
575 pcmd->UserCallback(commandList, pcmd);
577 switch (device->getType()) {
580 deviceContext->setScissor(
int(pcmd->ClipRect.x),
581 int(ImGui::GetIO().DisplaySize.y) -
int(pcmd->ClipRect.w),
582 int(pcmd->ClipRect.z) -
int(pcmd->ClipRect.x),
583 int(pcmd->ClipRect.w) -
int(pcmd->ClipRect.y));
588 deviceContext->setScissor(
int(pcmd->ClipRect.x),
589 int(pcmd->ClipRect.y),
590 int(pcmd->ClipRect.z),
591 int(pcmd->ClipRect.w));
597 deviceContext->setBlendState(blendState);
599 assert(pcmd->ElemCount > 0);
600 switch (mode & GUI_MODE_TEX_TYPE_MASK)
602 case GUI_MODE_TEX_TYPE_2D:
603 deviceContext->setTexture(
"texture0", 0, textureHandle);
604 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
606 case GUI_MODE_TEX_TYPE_ARRAY:
607 deviceContext->setTexture(
"texarray", 3, textureHandle);
608 deviceContext->setSamplerState(
"texture0Sampler", 3, sampler);
610 case GUI_MODE_TEX_TYPE_CUBE:
611 deviceContext->setTexture(
"texcube", 2, textureHandle);
612 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
614 case GUI_MODE_TEX_TYPE_2DMS:
615 deviceContext->setTexture(
"texturems", 1, textureHandle);
616 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
626 baseIndex += pcmd->ElemCount;
629 baseVertex += commandList->VtxBuffer.size();
632 auto & io = ImGui::GetIO();
634 io.ClearInputCharacters();
637void Cogs::Core::ImguiRenderer::addTextToGlyphBuilder(
const char* text)
640 fontGlyphBuilder.AddText(text);
641 updateLoadedRanges =
true;
645void Cogs::Core::ImguiRenderer::addRangeToGlyphBuilder(
const ImWchar* ranges)
647 fontGlyphBuilder.AddRanges(ranges);
648 updateLoadedRanges =
true;
651void Cogs::Core::ImguiRenderer::style()
654 float satMult = 0.0f;
655 static int hue = 146;
656 static float col_main_sat = satMult * 180.f / 255.f;
657 static float col_main_val = 161.f / 255.f;
658 static float col_area_sat = satMult * 124.f / 255.f;
659 static float col_area_val = 100.f / 255.f;
660 static float col_back_sat = satMult * 59.f / 255.f;
661 static float col_back_val = 40.f / 255.f;
663 ImGuiStyle & style = ImGui::GetStyle();
665 ImVec4 col_text = ImColor::HSV(hue / 255.f, 20.f / 255.f, 255.f / 255.f);
666 ImVec4 col_main = ImColor::HSV(hue / 255.f, col_main_sat, col_main_val);
667 ImVec4 col_back = ImColor::HSV(hue / 255.f, col_back_sat, col_back_val);
668 ImVec4 col_dark = ImColor::HSV(hue / 255.f, col_back_sat, 55 / 255.f);
669 ImVec4 col_area = ImColor::HSV(hue / 255.f, col_area_sat, col_area_val);
671 style.Colors[ImGuiCol_Text] = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
672 style.Colors[ImGuiCol_TextDisabled] = ImVec4(col_text.x, col_text.y, col_text.z, 0.58f);
673 style.Colors[ImGuiCol_WindowBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
674 style.Colors[ImGuiCol_Border] = ImVec4(col_text.x, col_text.y, col_text.z, 0.30f);
675 style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
676 style.Colors[ImGuiCol_FrameBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
677 style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.68f);
678 style.Colors[ImGuiCol_FrameBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
679 style.Colors[ImGuiCol_TitleBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.45f);
680 style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(col_main.x, col_main.y, col_main.z, 0.35f);
681 style.Colors[ImGuiCol_TitleBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
682 style.Colors[ImGuiCol_MenuBarBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
683 style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
684 style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.31f);
685 style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
686 style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
687 style.Colors[ImGuiCol_CheckMark] = ImVec4(col_main.x, col_main.y, col_main.z, 0.80f);
688 style.Colors[ImGuiCol_SliderGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.24f);
689 style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
690 style.Colors[ImGuiCol_Button] = ImVec4(col_main.x, col_main.y, col_main.z, 0.44f);
691 style.Colors[ImGuiCol_ButtonHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.86f);
692 style.Colors[ImGuiCol_ButtonActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
693 style.Colors[ImGuiCol_Header] = ImVec4(col_main.x, col_main.y, col_main.z, 0.76f);
694 style.Colors[ImGuiCol_HeaderHovered] = ImVec4(col_dark.x, col_dark.y, col_dark.z, 0.86f);
695 style.Colors[ImGuiCol_HeaderActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
696 style.Colors[ImGuiCol_ResizeGrip] = ImVec4(col_main.x, col_main.y, col_main.z, 0.20f);
697 style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
698 style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
699 style.Colors[ImGuiCol_PlotLines] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
700 style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
701 style.Colors[ImGuiCol_PlotHistogram] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
702 style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
703 style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.43f);
704 style.Colors[ImGuiCol_PopupBg] = ImVec4(col_back.x, col_back.y, col_back.z, 0.99f);
705 style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
707 style.WindowRounding = 2.0f;
708 style.WindowBorderSize = 0.0f;
711void Cogs::Core::ImguiRenderer::createSampler()
713 SamplerState fs = {};
717 sampler = device->getTextures()->loadSamplerState(fs);
720bool Cogs::Core::ImguiRenderer::createResources()
722 VertexElement elements[] = {
727 format = device->getBuffers()->createVertexFormat(elements, std::size(elements));
730 desc.name =
"ImguiEffect";
733 switch (device->getType()) {
736 desc.vertexShader =
"Engine/ImguiVS.wgsl";
737 desc.pixelShader =
"Engine/ImguiPS.wgsl";
738 desc.vsEntryPoint =
"vs_main";
739 desc.psEntryPoint =
"fs_main";
748 desc.vertexShader =
"Engine/ImguiVS.es30.glsl";
749 desc.pixelShader =
"Engine/ImguiPS.es30.glsl";
754 desc.vertexShader =
"Engine/ImguiVS.hlsl";
755 desc.pixelShader =
"Engine/ImguiPS.hlsl";
758 effect = device->getEffects()->loadEffect(desc);
761 device->getBuffers()->annotate(constantBuffer,
"ImGui");
765 bs.sourceBlend = BlendState::Blend::SourceAlpha;
766 bs.destinationBlend = BlendState::Blend::InverseSourceAlpha;
767 bs.operation = BlendState::BlendOperation::Add;
769 blendState = device->getRenderTargets()->loadBlendState(bs);
771 RasterizerState rs = {};
773 rs.frontCounterClockwise =
false;
774 rs.wireFrame =
false;
777 rasterizerState = device->getRenderTargets()->loadRasterizerState(rs);
779 DepthStencilState ds = {};
780 ds.depthEnabled =
false;
783 depthState = device->getRenderTargets()->loadDepthStencilState(ds);
790 const unsigned char data[2 * 2 * 4] = {
791 0xffu, 0xffu, 0xffu, 0xffu,
792 0x88u, 0x88u, 0x88u, 0x88u,
793 0x88u, 0x88u, 0x88u, 0x88u,
794 0xffu, 0xffu, 0xffu, 0xffu,
796 const unsigned char* dataPtrs[6] = { data, data, data, data, data, data };
798 dummyTex2D = textures->
loadTexture(data, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB);
800 dummyTex2DArray = textures->
loadTextureArray(dataPtrs, 1, 1, &width, &height, TextureFormat::R8G8B8A8_UNORM_SRGB);
801 dummyTexCube = textures->
loadCubeMap(dataPtrs, 1, 1, &width, &height, TextureFormat::R8G8B8A8_UNORM_SRGB);
808void Cogs::Core::GuiFont::load(
const Context * context,
const std::string& name,
float size,
const ImWchar* glyphRanges)
811 auto fontBytes = context->resourceStore->getResourceContents(name);
812 if (fontBytes.empty()) {
813 static const std::string fallbackFont =
"Fonts/Inconsolata-Regular.ttf";
815 LOG_WARNING(logger,
"Failed to read font %.*s, trying %s", StringViewFormat(name), fallbackFont.c_str());
816 fontBytes = context->resourceStore->getResourceContents(fallbackFont);
820 unsigned char* pixels;
824 config.FontDataOwnedByAtlas =
false;
828 for (
int i = 0; i < cNoOfFontSizes; ++i, size += initialSize) {
829 font[i] = fontAtlas.AddFontFromMemoryTTF(fontBytes.data(),
static_cast<int>(fontBytes.size()), size, &config, glyphRanges);
831 fontAtlas.GetTexDataAsRGBA32(&pixels, &width, &height);
832 fontAtlas.TexID = context->device->getTextures()->loadTexture(pixels, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB, 0).handle;
835void Cogs::Core::GuiFont::reloadWithNewGlyphs(
const Context* context,
const ImWchar* glyphRanges) {
836 load(context, path, initialSize, glyphRanges);
839ImFont* Cogs::Core::GuiFont::find(
float size,
float& scale)
const {
841 float fontSize = initialSize;
843 for (; idx < (cNoOfFontSizes - 1); ++idx, fontSize += initialSize) {
844 if (size <= (fontSize + (fontSize * 0.3f))) {
848 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.
COGSCORE_DLL_API 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.
ResourceStatus
Status of an asynchronously loaded resource, such as an effect or a pipeline.
@ Error
The resource failed to load.
@ Ready
The resource has loaded successfully and is ready for use.
@ VertexData
Per vertex data.
@ TriangleList
List of triangles.
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.
Provides effects and shader management functionality.
virtual ResourceStatus checkEffect(EffectHandle effectHandle)=0
Check the load status of the effect with the given effectHandle.
Provides texture management functionality.
virtual TextureHandle loadTexture(const unsigned char *bytes, unsigned int width, unsigned int height, TextureFormat format, unsigned int flags=0)=0
Load a texture using the given data to populate the texture contents.
virtual TextureHandle loadTextureArray(const unsigned char **bytes, const size_t arraySize, const size_t numLevels, const unsigned int *widths, const unsigned int *heights, TextureFormat format, unsigned int flags=0)=0
Load an array texture with mipmaps using the given data to populate the texture contents.
virtual TextureHandle loadCubeMap(const unsigned char **bytes, const size_t arraySize, const size_t numLevels, const unsigned int *widths, const unsigned int *heights, TextureFormat format, unsigned int flags=0)=0
Load a cube map texture with mipmaps using the given data to populate the texture contents.
@ WriteDiscard
Write access. When unmapping the graphics system will discard the old contents of the resource.
@ 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.
@ RenderTarget
The texture can be used as a render target and drawn into.
@ Dynamic
Buffer will be loaded and modified with some frequency.