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:
325 case GUI_MODE_TEX_CHANNELS_111INVR:
334 if (context->renderer->getSettings().defaultRenderTargetExpectsSRGB) {
343 constants->projectionMatrix = M;
344 constants->showAlpha = showAlpha;
345 constants->texMode = texMode;
346 constants->offset = offset;
347 constants->output_sRGB = output_sRGB;
350 deviceContext->setConstantBuffer(
"ImguiBuffer", constantBuffer);
357void Cogs::Core::ImguiRenderer::frame(ImGuiContext* guiContext, ViewContext& view,
bool updateio)
359 ImGui::SetCurrentContext(guiContext);
361 ImGuiIO& io = ImGui::GetIO();
362 const Keyboard& keyboard = view.refKeyboard();
366 const std::vector<Cogs::Gesture>& gestures = view.refGestures().getGestures();
367 Cogs::PointerType pointerType = view.refGestures().getPointerType();
369 std::memset(io.MouseDown, 0,
sizeof(io.MouseDown));
371 if (pointerType == Cogs::PointerType::Touch) {
372 view.refGestures().hoverEnable =
true;
375 touchPointerPosition.x = gesture.press.coord.x;
376 touchPointerPosition.y = gesture.press.coord.y;
377 touchPointerHeld =
true;
380 touchPointerPosition.x = gesture.tap.coord.x;
381 touchPointerPosition.y = gesture.tap.coord.y;
382 touchPointerHeld =
false;
385 touchPointerPosition.x = gesture.drag.currCoord.x;
386 touchPointerPosition.y = gesture.drag.currCoord.y;
387 touchPointerHeld =
true;
390 touchPointerPosition.x = gesture.hover.coord.x;
391 touchPointerPosition.y = gesture.hover.coord.y;
396 io.MouseDown[0] = mouseState.buttonDown[MouseButton::Left] || touchPointerHeld;
397 io.MouseDown[1] = mouseState.buttonDown[MouseButton::Right];
398 io.MouseDown[2] = mouseState.buttonDown[MouseButton::Middle];
400 if (pointerType == Cogs::PointerType::Touch) {
401 io.MousePos.x = touchPointerPosition.x;
402 io.MousePos.y = touchPointerPosition.y;
405 io.MousePos.x = mouseState.position.x;
406 io.MousePos.y = mouseState.position.y;
409 io.MouseWheel = mouseState.wheel != 0 ? (mouseState.wheel > 0 ? 1.0f : -1.0f) : 0;
411 for (
const Keyboard::Event& e: keyboard.getEvents()) {
412 if ((e.type == Keyboard::Event::Type::Press) || (e.type == Keyboard::Event::Type::Release)) {
413 io.AddKeyEvent(CogsKeyToImGuiKey(std::get<Key>(e.data)), e.type == Keyboard::Event::Type::Press);
416 io.AddInputCharactersUTF8(keyboard.getState().chars.c_str());
419 for (
const Keyboard::Event& e: keyboard.getEvents()) {
420 if (e.type == Keyboard::Event::Type::Release) {
421 io.AddKeyEvent(CogsKeyToImGuiKey(std::get<Key>(e.data)),
false);
425 io.DisplaySize = view.getSize();
428 io.DeltaTime = std::max(
static_cast<float>(timer.elapsedSeconds()), 0.000001f);
431 if (updateLoadedRanges) {
432 ImVector<ImWchar> requiredRanges;
434 fontGlyphBuilder.BuildRanges(&requiredRanges);
436 if (!std::equal(loadedRanges.begin(), loadedRanges.end(), requiredRanges.begin(), requiredRanges.end())) {
437 for (
auto& [_, font] : fontRegistry.fonts) {
438 font.reloadWithNewGlyphs(context, requiredRanges.Data);
440 loadedRanges = requiredRanges;
442 updateLoadedRanges =
false;
448void Cogs::Core::ImguiRenderer::render()
450 auto deviceContext = device->getImmediateContext();
452 CommandGroupAnnotation commandGroup(deviceContext,
"Imgui::Render");
456 auto drawData = ImGui::GetDrawData();
458 auto buffers = device->getBuffers();
461 if (!
HandleIsValid(vertexBuffer) || vertexBufferSize < drawData->TotalVtxCount) {
463 vertexBufferSize = drawData->TotalVtxCount + 5000;
465 vertexBuffer = buffers->loadVertexBuffer(
nullptr, vertexBufferSize, format);
468 if (!
HandleIsValid(indexBuffer) || indexBufferSize < drawData->TotalIdxCount) {
470 indexBufferSize = drawData->TotalIdxCount + 10000;
472 indexBuffer = buffers->loadIndexBuffer(
nullptr, indexBufferSize,
sizeof(ImDrawIdx));
480 size_t vtx_offset = 0;
481 for (
int n = 0; n < drawData->CmdListsCount; n++) {
482 const ImDrawList* commandList = drawData->CmdLists[n];
483 deviceContext->updateSubBuffer(vertexBuffer, vtx_offset,
sizeof(ImDrawVert) * commandList->VtxBuffer.size(), &commandList->VtxBuffer[0]);
484 vtx_offset +=
sizeof(ImDrawVert) * commandList->VtxBuffer.size();
487 size_t idx_offset = 0;
488 for (
int n = 0; n < drawData->CmdListsCount; n++) {
489 const ImDrawList* commandList = drawData->CmdLists[n];
490 deviceContext->updateSubBuffer(indexBuffer, idx_offset,
sizeof(ImDrawIdx) * commandList->IdxBuffer.size(), &commandList->IdxBuffer[0]);
491 idx_offset +=
sizeof(ImDrawIdx) * commandList->IdxBuffer.size();
499 if (vtx_dst && idx_dst) {
500 for (
int n = 0; n < drawData->CmdListsCount; n++) {
501 const auto commandList = drawData->CmdLists[n];
503 memcpy(vtx_dst, &commandList->VtxBuffer[0], commandList->VtxBuffer.size() *
sizeof(ImDrawVert));
504 memcpy(idx_dst, &commandList->IdxBuffer[0], commandList->IdxBuffer.size() *
sizeof(ImDrawIdx));
506 vtx_dst += commandList->VtxBuffer.size();
507 idx_dst += commandList->IdxBuffer.size();
510 deviceContext->unmap(vertexBuffer);
511 deviceContext->unmap(indexBuffer);
514 deviceContext->setViewport(0, 0, ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y);
515 deviceContext->clearDepth(context->renderer->getClearDepth());
517 deviceContext->setEffect(effect);
518 const uint32_t strides[] = {
sizeof(ImDrawVert) };
519 deviceContext->setVertexBuffers(&vertexBuffer, 1, strides,
nullptr);
520 deviceContext->setIndexBuffer(indexBuffer,
sizeof(ImDrawIdx));
521 if (
HandleIsValid(inputLayout)) deviceContext->setInputLayout(inputLayout);
522 updateConstantBuffer(deviceContext, GUI_MODE_DEFAULT);
524 deviceContext->setBlendState(blendState);
525 deviceContext->setRasterizerState(rasterizerState);
526 deviceContext->setDepthStencilState(depthState);
528 deviceContext->setTexture(
"texture0", 0, dummyTex2D);
529 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
531 deviceContext->setTexture(
"texturems", 1, dummyTex2DMS);
532 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
534 deviceContext->setTexture(
"texcube", 2, dummyTexCube);
535 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
537 deviceContext->setTexture(
"texarray", 3, dummyTex2DArray);
538 deviceContext->setSamplerState(
"texarraySampler", 3, sampler);
544 for (
int n = 0; n < drawData->CmdListsCount; n++) {
545 const ImDrawList* commandList = drawData->CmdLists[n];
547 for (
int commandIndex = 0; commandIndex < commandList->CmdBuffer.size(); commandIndex++) {
548 const ImDrawCmd* pcmd = &commandList->CmdBuffer[commandIndex];
551 updateConstantBuffer(deviceContext, (uint32_t)(uint64_t)pcmd->UserCallbackData);
554 if (pcmd->UserCallback) {
555 pcmd->UserCallback(commandList, pcmd);
557 switch (device->getType()) {
560 deviceContext->setScissor(
int(pcmd->ClipRect.x),
561 int(ImGui::GetIO().DisplaySize.y) -
int(pcmd->ClipRect.w),
562 int(pcmd->ClipRect.z) -
int(pcmd->ClipRect.x),
563 int(pcmd->ClipRect.w) -
int(pcmd->ClipRect.y));
568 deviceContext->setScissor(
int(pcmd->ClipRect.x),
569 int(pcmd->ClipRect.y),
570 int(pcmd->ClipRect.z),
571 int(pcmd->ClipRect.w));
577 deviceContext->setBlendState(blendState);
579 assert(pcmd->ElemCount > 0);
580 switch (mode & GUI_MODE_TEX_TYPE_MASK)
582 case GUI_MODE_TEX_TYPE_2D:
583 deviceContext->setTexture(
"texture0", 0, textureHandle);
584 deviceContext->setSamplerState(
"texture0Sampler", 0, sampler);
586 case GUI_MODE_TEX_TYPE_ARRAY:
587 deviceContext->setTexture(
"texarray", 3, textureHandle);
588 deviceContext->setSamplerState(
"texture0Sampler", 3, sampler);
590 case GUI_MODE_TEX_TYPE_CUBE:
591 deviceContext->setTexture(
"texcube", 2, textureHandle);
592 deviceContext->setSamplerState(
"texture0Sampler", 2, sampler);
594 case GUI_MODE_TEX_TYPE_2DMS:
595 deviceContext->setTexture(
"texturems", 1, textureHandle);
596 deviceContext->setSamplerState(
"texture0Sampler", 1, sampler);
606 baseIndex += pcmd->ElemCount;
609 baseVertex += commandList->VtxBuffer.size();
612 auto & io = ImGui::GetIO();
614 io.ClearInputCharacters();
617void Cogs::Core::ImguiRenderer::addTextToGlyphBuilder(
const char* text)
620 fontGlyphBuilder.AddText(text);
621 updateLoadedRanges =
true;
625void Cogs::Core::ImguiRenderer::addRangeToGlyphBuilder(
const ImWchar* ranges)
627 fontGlyphBuilder.AddRanges(ranges);
628 updateLoadedRanges =
true;
631void Cogs::Core::ImguiRenderer::style()
634 float satMult = 0.0f;
635 static int hue = 146;
636 static float col_main_sat = satMult * 180.f / 255.f;
637 static float col_main_val = 161.f / 255.f;
638 static float col_area_sat = satMult * 124.f / 255.f;
639 static float col_area_val = 100.f / 255.f;
640 static float col_back_sat = satMult * 59.f / 255.f;
641 static float col_back_val = 40.f / 255.f;
643 ImGuiStyle & style = ImGui::GetStyle();
645 ImVec4 col_text = ImColor::HSV(hue / 255.f, 20.f / 255.f, 255.f / 255.f);
646 ImVec4 col_main = ImColor::HSV(hue / 255.f, col_main_sat, col_main_val);
647 ImVec4 col_back = ImColor::HSV(hue / 255.f, col_back_sat, col_back_val);
648 ImVec4 col_dark = ImColor::HSV(hue / 255.f, col_back_sat, 55 / 255.f);
649 ImVec4 col_area = ImColor::HSV(hue / 255.f, col_area_sat, col_area_val);
651 style.Colors[ImGuiCol_Text] = ImVec4(col_text.x, col_text.y, col_text.z, 1.00f);
652 style.Colors[ImGuiCol_TextDisabled] = ImVec4(col_text.x, col_text.y, col_text.z, 0.58f);
653 style.Colors[ImGuiCol_WindowBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
654 style.Colors[ImGuiCol_Border] = ImVec4(col_text.x, col_text.y, col_text.z, 0.30f);
655 style.Colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
656 style.Colors[ImGuiCol_FrameBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
657 style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.68f);
658 style.Colors[ImGuiCol_FrameBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
659 style.Colors[ImGuiCol_TitleBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.45f);
660 style.Colors[ImGuiCol_TitleBgCollapsed] = ImVec4(col_main.x, col_main.y, col_main.z, 0.35f);
661 style.Colors[ImGuiCol_TitleBgActive] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
662 style.Colors[ImGuiCol_MenuBarBg] = ImVec4(col_back.x, col_back.y, col_back.z, 1.00f);
663 style.Colors[ImGuiCol_ScrollbarBg] = ImVec4(col_area.x, col_area.y, col_area.z, 1.00f);
664 style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.31f);
665 style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
666 style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
667 style.Colors[ImGuiCol_CheckMark] = ImVec4(col_main.x, col_main.y, col_main.z, 0.80f);
668 style.Colors[ImGuiCol_SliderGrab] = ImVec4(col_main.x, col_main.y, col_main.z, 0.24f);
669 style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
670 style.Colors[ImGuiCol_Button] = ImVec4(col_main.x, col_main.y, col_main.z, 0.44f);
671 style.Colors[ImGuiCol_ButtonHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.86f);
672 style.Colors[ImGuiCol_ButtonActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
673 style.Colors[ImGuiCol_Header] = ImVec4(col_main.x, col_main.y, col_main.z, 0.76f);
674 style.Colors[ImGuiCol_HeaderHovered] = ImVec4(col_dark.x, col_dark.y, col_dark.z, 0.86f);
675 style.Colors[ImGuiCol_HeaderActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
676 style.Colors[ImGuiCol_ResizeGrip] = ImVec4(col_main.x, col_main.y, col_main.z, 0.20f);
677 style.Colors[ImGuiCol_ResizeGripHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 0.78f);
678 style.Colors[ImGuiCol_ResizeGripActive] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
679 style.Colors[ImGuiCol_PlotLines] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
680 style.Colors[ImGuiCol_PlotLinesHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
681 style.Colors[ImGuiCol_PlotHistogram] = ImVec4(col_text.x, col_text.y, col_text.z, 0.63f);
682 style.Colors[ImGuiCol_PlotHistogramHovered] = ImVec4(col_main.x, col_main.y, col_main.z, 1.00f);
683 style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(col_main.x, col_main.y, col_main.z, 0.43f);
684 style.Colors[ImGuiCol_PopupBg] = ImVec4(col_back.x, col_back.y, col_back.z, 0.99f);
685 style.Colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f);
687 style.WindowRounding = 2.0f;
688 style.WindowBorderSize = 0.0f;
691void Cogs::Core::ImguiRenderer::createSampler()
693 SamplerState fs = {};
697 sampler = device->getTextures()->loadSamplerState(fs);
700bool Cogs::Core::ImguiRenderer::createResources()
702 VertexElement elements[] = {
707 format = device->getBuffers()->createVertexFormat(elements, glm::countof(elements));
710 desc.name =
"ImguiEffect";
713 switch (device->getType()) {
716 desc.vertexShader =
"Engine/ImguiVS.wgsl";
717 desc.pixelShader =
"Engine/ImguiPS.wgsl";
718 desc.vsEntryPoint =
"vs_main";
719 desc.psEntryPoint =
"fs_main";
728 desc.vertexShader =
"Engine/ImguiVS.es30.glsl";
729 desc.pixelShader =
"Engine/ImguiPS.es30.glsl";
734 desc.vertexShader =
"Engine/ImguiVS.hlsl";
735 desc.pixelShader =
"Engine/ImguiPS.hlsl";
738 effect = device->getEffects()->loadEffect(desc);
739 inputLayout = device->getBuffers()->loadInputLayout(&format, 1, effect);
742 device->getBuffers()->annotate(constantBuffer,
"ImGui");
746 bs.sourceBlend = BlendState::Blend::SourceAlpha;
747 bs.destinationBlend = BlendState::Blend::InverseSourceAlpha;
748 bs.operation = BlendState::BlendOperation::Add;
750 blendState = device->getRenderTargets()->loadBlendState(bs);
752 RasterizerState rs = {};
754 rs.frontCounterClockwise =
false;
755 rs.wireFrame =
false;
758 rasterizerState = device->getRenderTargets()->loadRasterizerState(rs);
760 DepthStencilState ds = {};
761 ds.depthEnabled =
false;
764 depthState = device->getRenderTargets()->loadDepthStencilState(ds);
771 const unsigned char data[2 * 2 * 4] = {
772 0xffu, 0xffu, 0xffu, 0xffu,
773 0x88u, 0x88u, 0x88u, 0x88u,
774 0x88u, 0x88u, 0x88u, 0x88u,
775 0xffu, 0xffu, 0xffu, 0xffu,
777 const unsigned char* dataPtrs[6] = { data, data, data, data, data, data };
779 dummyTex2D = textures->
loadTexture(data, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB);
780 dummyTex2DMS = textures->
loadTexture(
nullptr, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB, 2, 0);
781 dummyTex2DArray = textures->
loadTextureArray(dataPtrs, 1, 1, &width, &height, TextureFormat::R8G8B8A8_UNORM_SRGB);
782 dummyTexCube = textures->
loadCubeMap(dataPtrs, 1, 1, &width, &height, TextureFormat::R8G8B8A8_UNORM_SRGB);
789void Cogs::Core::GuiFont::load(
const Context * context,
const std::string& name,
float size,
const ImWchar* glyphRanges)
792 auto fontBytes = context->resourceStore->getResourceContents(name);
793 if (fontBytes.empty()) {
794 static const std::string fallbackFont =
"Fonts/Inconsolata-Regular.ttf";
796 LOG_WARNING(logger,
"Failed to read font %.*s, trying %s", StringViewFormat(name), fallbackFont.c_str());
797 fontBytes = context->resourceStore->getResourceContents(fallbackFont);
801 unsigned char* pixels;
805 config.FontDataOwnedByAtlas =
false;
809 for (
int i = 0; i < cNoOfFontSizes; ++i, size += initialSize) {
810 font[i] = fontAtlas.AddFontFromMemoryTTF(fontBytes.data(),
static_cast<int>(fontBytes.size()), size, &config, glyphRanges);
812 fontAtlas.GetTexDataAsRGBA32(&pixels, &width, &height);
813 fontAtlas.TexID = context->device->getTextures()->loadTexture(pixels, width, height, TextureFormat::R8G8B8A8_UNORM_SRGB, 0).handle;
816void Cogs::Core::GuiFont::reloadWithNewGlyphs(
const Context* context,
const ImWchar* glyphRanges) {
817 load(context, path, initialSize, glyphRanges);
820ImFont* Cogs::Core::GuiFont::find(
float size,
float& scale)
const {
822 float fontSize = initialSize;
824 for (; idx < (cNoOfFontSizes - 1); ++idx, fontSize += initialSize) {
825 if (size <= (fontSize + (fontSize * 0.3f))) {
829 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.
@ 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 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.
@ Dynamic
Buffer will be loaded and modified with some frequency.