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,
SetProceduralOrigin = -7,
// -8 is ImDrawCallback_ResetRenderState, don't use!
SetAdditive = -9
};
union ImGuiCallbackData
@ -64,6 +65,11 @@ union ImGuiCallbackData
{
float proceduralOrigin[2];
} setProceduralOrigin;
struct
{
bool enabled;
} setAdditive;
};
extern ImGuiCallbackData* AddImGuiCallback(ImGuiCallback callback);

View file

@ -1127,7 +1127,7 @@ namespace plume {
desc.srcBlend = RenderBlend::SRC_ALPHA;
desc.dstBlend = RenderBlend::INV_SRC_ALPHA;
desc.blendOp = RenderBlendOperation::ADD;
desc.srcBlendAlpha = RenderBlend::ONE;
desc.srcBlendAlpha = RenderBlend::SRC_ALPHA;
desc.dstBlendAlpha = RenderBlend::INV_SRC_ALPHA;
desc.blendOpAlpha = RenderBlendOperation::ADD;
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<RenderPipelineLayout> g_imPipelineLayout;
static std::unique_ptr<RenderPipeline> g_imPipeline;
static std::unique_ptr<RenderPipeline> g_imAdditivePipeline;
template<typename T>
static void ExecuteCopyCommandList(const T& function)
@ -1309,6 +1310,9 @@ static void CreateImGuiBackend()
pipelineDesc.inputSlotsCount = 1;
g_imPipeline = g_device->createGraphicsPipeline(pipelineDesc);
pipelineDesc.renderTargetBlend[0].dstBlend = RenderBlend::ONE;
g_imAdditivePipeline = g_device->createGraphicsPipeline(pipelineDesc);
#ifndef ENABLE_IM_FONT_ATLAS_SNAPSHOT
ImFontAtlasSnapshot snapshot;
snapshot.Snap();
@ -2091,9 +2095,10 @@ static void ProcDrawImGui(const RenderCommand& cmd)
SetFramebuffer(g_backBuffer, nullptr, false);
auto& commandList = g_commandLists[g_frame];
auto pipeline = g_imPipeline.get();
commandList->setGraphicsPipelineLayout(g_imPipelineLayout.get());
commandList->setPipeline(g_imPipeline.get());
commandList->setPipeline(pipeline);
commandList->setGraphicsDescriptorSet(g_textureDescriptorSet.get(), 0);
commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 1);
@ -2167,6 +2172,16 @@ static void ProcDrawImGui(const RenderCommand& cmd)
case ImGuiCallback::SetProceduralOrigin:
setPushConstants(&pushConstants.proceduralOrigin, &callbackData->setProceduralOrigin, sizeof(callbackData->setProceduralOrigin));
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:
assert(false && "Unknown ImGui callback type.");
break;

View file

@ -108,6 +108,17 @@ inline void ResetProceduralOrigin()
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)
{
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);
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);
float gridSize = Scale(GRID_SIZE);
SetShaderModifier(IMGUI_SHADER_MODIFIER_CHECKERBOARD);
SetAdditive(true);
drawList->AddRectFilled(min, max, gridColor);
SetAdditive(false);
SetShaderModifier(IMGUI_SHADER_MODIFIER_NONE);
if (isTextArea)