Implement ImGui additive rendering. (#152)

This commit is contained in:
Skyth (Asilkan) 2025-01-23 16:25:31 +03:00 committed by GitHub
parent b4de79720c
commit 372c04fedd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 37 additions and 3 deletions

View file

@ -22,6 +22,7 @@ enum class ImGuiCallback : int32_t
SetOutline = -6, SetOutline = -6,
SetProceduralOrigin = -7, SetProceduralOrigin = -7,
// -8 is ImDrawCallback_ResetRenderState, don't use! // -8 is ImDrawCallback_ResetRenderState, don't use!
SetAdditive = -9
}; };
union ImGuiCallbackData union ImGuiCallbackData
@ -64,6 +65,11 @@ union ImGuiCallbackData
{ {
float proceduralOrigin[2]; float proceduralOrigin[2];
} setProceduralOrigin; } setProceduralOrigin;
struct
{
bool enabled;
} setAdditive;
}; };
extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback); extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback);

View file

@ -1127,7 +1127,7 @@ namespace plume {
desc.srcBlend = RenderBlend::SRC_ALPHA; desc.srcBlend = RenderBlend::SRC_ALPHA;
desc.dstBlend = RenderBlend::INV_SRC_ALPHA; desc.dstBlend = RenderBlend::INV_SRC_ALPHA;
desc.blendOp = RenderBlendOperation::ADD; desc.blendOp = RenderBlendOperation::ADD;
desc.srcBlendAlpha = RenderBlend::ONE; desc.srcBlendAlpha = RenderBlend::SRC_ALPHA;
desc.dstBlendAlpha = RenderBlend::INV_SRC_ALPHA; desc.dstBlendAlpha = RenderBlend::INV_SRC_ALPHA;
desc.blendOpAlpha = RenderBlendOperation::ADD; desc.blendOpAlpha = RenderBlendOperation::ADD;
return desc; return desc;

View file

@ -1141,6 +1141,7 @@ static constexpr size_t SAMPLER_DESCRIPTOR_SIZE = 1024;
static std::unique_ptr<GuestTexture> g_imFontTexture; static std::unique_ptr<GuestTexture> g_imFontTexture;
static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout; static std::unique_ptr<RenderPipelineLayout> g_imPipelineLayout;
static std::unique_ptr<RenderPipeline> g_imPipeline; static std::unique_ptr<RenderPipeline> g_imPipeline;
static std::unique_ptr<RenderPipeline> g_imAdditivePipeline;
template<typename T> template<typename T>
static void ExecuteCopyCommandList(const T& function) static void ExecuteCopyCommandList(const T& function)
@ -1309,6 +1310,9 @@ static void CreateImGuiBackend()
pipelineDesc.inputSlotsCount = 1; pipelineDesc.inputSlotsCount = 1;
g_imPipeline = g_device->createGraphicsPipeline(pipelineDesc); g_imPipeline = g_device->createGraphicsPipeline(pipelineDesc);
pipelineDesc.renderTargetBlend[0].dstBlend = RenderBlend::ONE;
g_imAdditivePipeline = g_device->createGraphicsPipeline(pipelineDesc);
#ifndef ENABLE_IM_FONT_ATLAS_SNAPSHOT #ifndef ENABLE_IM_FONT_ATLAS_SNAPSHOT
ImFontAtlasSnapshot snapshot; ImFontAtlasSnapshot snapshot;
snapshot.Snap(); snapshot.Snap();
@ -2091,9 +2095,10 @@ static void ProcDrawImGui(const RenderCommand& cmd)
SetFramebuffer(g_backBuffer, nullptr, false); SetFramebuffer(g_backBuffer, nullptr, false);
auto& commandList = g_commandLists[g_frame]; auto& commandList = g_commandLists[g_frame];
auto pipeline = g_imPipeline.get();
commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get()); commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get());
commandList->setPipeline(g_imPipeline.get()); commandList->setPipeline(pipeline);
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0); commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 1); commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 1);
@ -2167,6 +2172,16 @@ static void ProcDrawImGui(const RenderCommand& cmd)
case ImGuiCallback::SetProceduralOrigin: case ImGuiCallback::SetProceduralOrigin:
setPushConstants(&pushConstants.proceduralOrigin, &callbackData->setProceduralOrigin, sizeof(callbackData->setProceduralOrigin)); setPushConstants(&pushConstants.proceduralOrigin, &callbackData->setProceduralOrigin, sizeof(callbackData->setProceduralOrigin));
break; break;
case ImGuiCallback::SetAdditive:
{
auto pipelineToSet = callbackData->setAdditive.enabled ? g_imAdditivePipeline.get() : g_imPipeline.get();
if (pipeline != pipelineToSet)
{
commandList->setPipeline(pipelineToSet);
pipeline = pipelineToSet;
}
break;
}
default: default:
assert(false && "Unknown ImGui callback type."); assert(false && "Unknown ImGui callback type.");
break; break;

View file

@ -108,6 +108,17 @@ inline void ResetProceduralOrigin()
SetProceduralOrigin({ 0.0f, 0.0f }); SetProceduralOrigin({ 0.0f, 0.0f });
} }
inline void SetAdditive(bool enabled)
{
auto callbackData = AddImGuiCallback(ImGuiCallback::SetAdditive);
callbackData->setAdditive.enabled = enabled;
}
inline void ResetAdditive()
{
SetAdditive(false);
}
inline float Scale(float size) inline float Scale(float size)
{ {
return size * g_aspectRatioScale; return size * g_aspectRatioScale;

View file

@ -613,13 +613,15 @@ static void DrawContainer(ImVec2 min, ImVec2 max, bool isTextArea)
); );
double gridOverlayAlpha = ComputeMotionInstaller(g_appearTime, g_disappearTime, CONTAINER_INNER_TIME, CONTAINER_INNER_DURATION); double gridOverlayAlpha = ComputeMotionInstaller(g_appearTime, g_disappearTime, CONTAINER_INNER_TIME, CONTAINER_INNER_DURATION);
const uint32_t gridColor = IM_COL32(0, 33, 0, (isTextArea ? 128 : 255) * gridAlpha); const uint32_t gridColor = IM_COL32(0, 33, 0, (isTextArea ? 223 : 255) * gridAlpha);
const uint32_t gridOverlayColor = IM_COL32(0, 32, 0, 128 * gridOverlayAlpha); const uint32_t gridOverlayColor = IM_COL32(0, 32, 0, 128 * gridOverlayAlpha);
float gridSize = Scale(GRID_SIZE); float gridSize = Scale(GRID_SIZE);
SetShaderModifier(IMGUI_SHADER_MODIFIER_CHECKERBOARD); SetShaderModifier(IMGUI_SHADER_MODIFIER_CHECKERBOARD);
SetAdditive(true);
drawList->AddRectFilled(min, max, gridColor); drawList->AddRectFilled(min, max, gridColor);
SetAdditive(false);
SetShaderModifier(IMGUI_SHADER_MODIFIER_NONE); SetShaderModifier(IMGUI_SHADER_MODIFIER_NONE);
if (isTextArea) if (isTextArea)