ImGui: Finish implementing pipeline switching for all backends

This commit is contained in:
Henrik Rydgård 2024-11-27 01:13:59 +01:00
parent 09779e0f44
commit 6763c13f88
8 changed files with 143 additions and 116 deletions

View file

@ -164,7 +164,7 @@ public:
void DrawIndexed(int indexCount, int offset) override;
void DrawUP(const void *vdata, int vertexCount) override;
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) override;
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
@ -1407,7 +1407,13 @@ void D3D11DrawContext::DrawIndexedUP(const void *vdata, int vertexCount, const v
DrawIndexed(indexCount, 0);
}
void D3D11DrawContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) {
void D3D11DrawContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) {
if (draws.is_empty() || !vertexCount || !indexCount) {
return;
}
curPipeline_ = (D3D11Pipeline *)draws[0].pipeline;
int vbyteSize = vertexCount * curPipeline_->input->stride;
int ibyteSize = indexCount * sizeof(u16);
@ -1417,12 +1423,14 @@ void D3D11DrawContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCo
UpdateBuffer(upIBuffer_, (const uint8_t *)idata, 0, ibyteSize, Draw::UPDATE_DISCARD);
BindIndexBuffer(upIBuffer_, 0);
UpdateDynamicUniformBuffer(ub, ubSize);
ApplyCurrentState();
for (int i = 0; i < draws.size(); i++) {
if (draws[i].pipeline != curPipeline_) {
curPipeline_ = (D3D11Pipeline *)draws[i].pipeline;
ApplyCurrentState();
UpdateDynamicUniformBuffer(ub, ubSize);
}
if (draws[i].bindTexture) {
@ -1432,6 +1440,8 @@ void D3D11DrawContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCo
ID3D11ShaderResourceView *view = ((D3D11Framebuffer *)draws[i].bindFramebufferAsTex)->colorSRView;
context_->PSSetShaderResources(0, 1, &view);
}
ID3D11SamplerState *sstate = ((D3D11SamplerState *)draws[i].samplerState)->ss;
context_->PSSetSamplers(0, 1, &sstate);
D3D11_RECT rc;
rc.left = draws[i].clipx;
rc.top = draws[i].clipy;

View file

@ -574,7 +574,7 @@ public:
void DrawIndexed(int vertexCount, int offset) override;
void DrawUP(const void *vdata, int vertexCount) override;
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) override;
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
@ -1203,10 +1203,16 @@ void D3D9Context::DrawIndexedUP(const void *vdata, int vertexCount, const void *
vdata, curPipeline_->inputLayout->GetStride());
}
void D3D9Context::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) {
void D3D9Context::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) {
if (draws.is_empty() || !vertexCount || !indexCount) {
return;
}
BindPipeline(draws[0].pipeline);
curPipeline_->inputLayout->Apply(device_);
curPipeline_->Apply(device_, stencilRef_, stencilWriteMask_, stencilCompareMask_);
ApplyDynamicState();
UpdateDynamicUniformBuffer(ub, ubSize);
// Suboptimal! Should dirty-track textures.
for (int i = 0; i < draws.size(); i++) {

View file

@ -444,7 +444,7 @@ public:
void DrawIndexed(int vertexCount, int offset) override;
void DrawUP(const void *vdata, int vertexCount) override;
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) override;
void Clear(int mask, uint32_t colorval, float depthVal, int stencilVal) override;
@ -1442,7 +1442,14 @@ void OpenGLContext::DrawIndexedUP(const void *vdata, int vertexCount, const void
renderManager_.DrawIndexed(curPipeline_->inputLayout->inputLayout_, vbuf, voffset, ibuf, ioffset, curPipeline_->prim, indexCount, GL_UNSIGNED_SHORT, 1);
}
void OpenGLContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) {
void OpenGLContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) {
if (draws.is_empty() || !vertexCount || !indexCount) {
return;
}
BindPipeline(draws[0].pipeline);
UpdateDynamicUniformBuffer(ub, ubSize);
_assert_(curPipeline_->inputLayout != nullptr);
int stride = curPipeline_->inputLayout->stride;
uint32_t vdataSize = stride * vertexCount;
@ -1467,6 +1474,7 @@ void OpenGLContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount
OpenGLPipeline *glPipeline = (OpenGLPipeline *)draw.pipeline;
_dbg_assert_(glPipeline->inputLayout->stride == stride);
BindPipeline(glPipeline); // this updated curPipeline_.
UpdateDynamicUniformBuffer(ub, ubSize);
}
if (draw.bindTexture) {
renderManager_.BindTexture(0, ((OpenGLTexture *)draw.bindTexture)->GetTex());

View file

@ -493,7 +493,7 @@ public:
void DrawUP(const void *vdata, int vertexCount) override;
void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) override;
// Specialized for quick IMGUI drawing.
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw>) override;
void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw>, const void *dynUniforms, size_t size) override;
void BindCurrentPipeline();
void ApplyDynamicState();
@ -1557,13 +1557,15 @@ void VKContext::DrawIndexedUP(const void *vdata, int vertexCount, const void *id
renderManager_.DrawIndexed(descSetIndex, 1, &ubo_offset, vulkanVbuf, (int)vbBindOffset, vulkanIbuf, (int)ibBindOffset, indexCount, 1);
}
void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) {
void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *ub, size_t ubSize) {
_dbg_assert_(vertexCount >= 0);
_dbg_assert_(indexCount >= 0);
if (vertexCount <= 0 || indexCount <= 0 || draws.is_empty()) {
return;
}
curPipeline_ = (VKPipeline *)draws[0].pipeline;
VkBuffer vulkanVbuf, vulkanIbuf, vulkanUBObuf;
size_t vdataSize = vertexCount * curPipeline_->stride;
uint32_t vbBindOffset;
@ -1579,6 +1581,8 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co
_assert_(idataPtr != nullptr);
memcpy(idataPtr, idata, idataSize);
curPipeline_->SetDynamicUniformData(ub, ubSize);
uint32_t ubo_offset = (uint32_t)curPipeline_->PushUBO(push_, vulkan_, &vulkanUBObuf);
BindCurrentPipeline();
@ -1589,6 +1593,7 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co
VKPipeline *vkPipe = (VKPipeline *)draw.pipeline;
renderManager_.BindPipeline(vkPipe->pipeline, vkPipe->flags, pipelineLayout_);
curPipeline_ = (VKPipeline *)draw.pipeline;
curPipeline_->SetDynamicUniformData(ub, ubSize);
}
// TODO: Dirty-check these.
if (draw.bindTexture) {
@ -1596,6 +1601,8 @@ void VKContext::DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, co
} else if (draw.bindFramebufferAsTex) {
BindFramebufferAsTexture(draw.bindFramebufferAsTex, 0, FBChannel::FB_COLOR_BIT, 0);
}
Draw::SamplerState *sstate = draw.samplerState;
BindSamplerStates(0, 1, &sstate);
int descSetIndex;
PackedDescriptor *descriptors = renderManager_.PushDescriptorSet(4, &descSetIndex);
BindDescriptors(vulkanUBObuf, descriptors);

View file

@ -705,6 +705,7 @@ struct ClippedDraw {
s16 cliph;
Draw::Texture *bindTexture;
Draw::Framebuffer *bindFramebufferAsTex;
Draw::SamplerState *samplerState;
Draw::Pipeline *pipeline;
};
@ -844,7 +845,7 @@ public:
virtual void DrawUP(const void *vdata, int vertexCount) = 0;
virtual void DrawIndexedUP(const void *vdata, int vertexCount, const void *idata, int indexCount) = 0;
// Intended for ImGui display lists, easier to do optimally this way.
virtual void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws) = 0;
virtual void DrawIndexedClippedBatchUP(const void *vdata, int vertexCount, const void *idata, int indexCount, Slice<ClippedDraw> draws, const void *dynUniforms, size_t size) = 0;
// Frame management (for the purposes of sync and resource management, necessary with modern APIs). Default implementations here.
virtual void BeginFrame(DebugFlags debugFlags) = 0;

View file

@ -3705,10 +3705,15 @@ void FramebufferManagerCommon::DrawImGuiDebug(int &selected) const {
}
ImGui::EndTable();
// Fix out-of-bounds issues when framebuffers are removed.
if (selected >= vfbs_.size()) {
selected = -1;
}
if (selected != -1) {
// Now, draw the image of the selected framebuffer.
Draw::Framebuffer *fb = vfbs_[selected]->fbo;
ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(fb, Draw::FB_COLOR_BIT);
ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(fb, Draw::FB_COLOR_BIT, ImGuiPipeline::TexturedOpaque);
ImGui::Image(texId, ImVec2(fb->Width(), fb->Height()));
}
}

View file

@ -21,18 +21,13 @@ struct RegisteredTexture {
Draw::FBChannel aspect;
};
};
Draw::Pipeline *pipeline;
};
enum {
IMGUI_PIPELINE_TEXTURE_BLEND,
IMGUI_PIPELINE_TEXTURE,
ImGuiPipeline pipeline;
};
struct BackendData {
Draw::SamplerState *fontSampler = nullptr;
Draw::Texture *fontImage = nullptr;
Draw::Pipeline *pipeline = nullptr;
Draw::Pipeline *pipelines[2]{};
std::vector<RegisteredTexture> tempTextures;
};
@ -45,39 +40,6 @@ static BackendData *ImGui_ImplThin3d_GetBackendData() {
return ImGui::GetCurrentContext() ? (BackendData *)ImGui::GetIO().BackendRendererUserData : nullptr;
}
static void ImGui_ImplThin3d_SetupRenderState(Draw::DrawContext *draw, ImDrawData* drawData, Draw::Pipeline *pipeline, int fb_width, int fb_height) {
BackendData *bd = ImGui_ImplThin3d_GetBackendData();
// Bind pipeline and texture
draw->BindPipeline(pipeline);
draw->BindSamplerStates(0, 1, &bd->fontSampler);
// Setup viewport
{
Draw::Viewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = (float)fb_width;
viewport.Height = (float)fb_height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
draw->SetViewport(viewport);
}
// Setup scale and translation:
// Our visible imgui space lies from drawData->DisplayPps (top left) to drawData->DisplayPos + drawData->DisplaySize (bottom right).
// DisplayPos is (0,0) for single viewport apps. We currently ignore DisplayPos.
// We probably only need to do this at the start of the frame.
{
Lin::Matrix4x4 mtx = ComputeOrthoMatrix(drawData->DisplaySize.x, drawData->DisplaySize.y, draw->GetDeviceCaps().coordConvention);
Draw::VsTexColUB ub{};
memcpy(ub.WorldViewProj, mtx.getReadPtr(), sizeof(Lin::Matrix4x4));
ub.saturation = 1.0f;
draw->UpdateDynamicUniformBuffer(&ub, sizeof(ub));
}
}
// Render function
void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *draw) {
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
@ -88,9 +50,23 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
}
BackendData* bd = ImGui_ImplThin3d_GetBackendData();
draw->BindSamplerStates(0, 1, &bd->fontSampler);
// Setup desired Vulkan state
ImGui_ImplThin3d_SetupRenderState(draw, draw_data, bd->pipeline, fb_width, fb_height);
// Setup viewport
Draw::Viewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = (float)fb_width;
viewport.Height = (float)fb_height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
draw->SetViewport(viewport);
Lin::Matrix4x4 mtx = ComputeOrthoMatrix(draw_data->DisplaySize.x, draw_data->DisplaySize.y, draw->GetDeviceCaps().coordConvention);
Draw::VsTexColUB ub{};
memcpy(ub.WorldViewProj, mtx.getReadPtr(), sizeof(Lin::Matrix4x4));
ub.saturation = 1.0f;
// Will project scissor/clipping rectangles into framebuffer space
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
@ -103,7 +79,8 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
std::vector<Draw::ClippedDraw> draws;
Draw::Texture *boundTexture;
Draw::Framebuffer *boundFBAsTexture;
Draw::Pipeline *boundPipeline = bd->pipeline;
Draw::Pipeline *boundPipeline = bd->pipelines[0];
Draw::SamplerState *boundSampler = bd->fontSampler;
// Render command lists
for (int n = 0; n < draw_data->CmdListsCount; n++) {
@ -111,59 +88,56 @@ void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *d
draws.clear();
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->UserCallback != nullptr) {
// User callback, registered via ImDrawList::AddCallback()
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) {
ImGui_ImplThin3d_SetupRenderState(draw, draw_data, bd->pipeline, fb_width, fb_height);
} else {
pcmd->UserCallback(cmd_list, pcmd);
}
// We don't use the callback mechanism.
_dbg_assert_(pcmd->UserCallback == nullptr);
// Update the texture pointers.
if (!pcmd->TextureId) {
// Default
boundTexture = bd->fontImage;
boundFBAsTexture = nullptr;
boundPipeline = bd->pipelines[0];
boundSampler = bd->fontSampler;
} else {
// Update the texture pointers.
if (!pcmd->TextureId) {
boundTexture = bd->fontImage;
boundFBAsTexture = nullptr;
boundPipeline = bd->pipeline;
size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET;
_dbg_assert_(index < bd->tempTextures.size());
if (bd->tempTextures[index].framebuffer) {
boundFBAsTexture = bd->tempTextures[index].framebuffer;
boundTexture = nullptr;
} else {
size_t index = (size_t)pcmd->TextureId - TEX_ID_OFFSET;
_dbg_assert_(index < bd->tempTextures.size());
if (bd->tempTextures[index].framebuffer) {
boundFBAsTexture = bd->tempTextures[index].framebuffer;
boundTexture = nullptr;
} else {
boundTexture = bd->tempTextures[index].texture;
boundFBAsTexture = nullptr;
}
boundPipeline = bd->tempTextures[index].pipeline ? bd->tempTextures[index].pipeline : bd->pipeline;
boundTexture = bd->tempTextures[index].texture;
boundFBAsTexture = nullptr;
}
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
// Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
Draw::ClippedDraw clippedDraw;
clippedDraw.pipeline = boundPipeline;
clippedDraw.bindTexture = boundTexture;
clippedDraw.bindFramebufferAsTex = boundFBAsTexture;
clippedDraw.clipx = clip_min.x;
clippedDraw.clipy = clip_min.y;
clippedDraw.clipw = clip_max.x - clip_min.x;
clippedDraw.cliph = clip_max.y - clip_min.y;
clippedDraw.indexCount = pcmd->ElemCount;
clippedDraw.indexOffset = pcmd->IdxOffset;
draws.push_back(clippedDraw);
boundPipeline = bd->pipelines[(int)bd->tempTextures[index].pipeline];
boundSampler = bd->fontSampler;
}
// Project scissor/clipping rectangles into framebuffer space
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
// Clamp to viewport as vkCmdSetScissor() won't accept values that are off bounds
if (clip_min.x < 0.0f) { clip_min.x = 0.0f; }
if (clip_min.y < 0.0f) { clip_min.y = 0.0f; }
if (clip_max.x > fb_width) { clip_max.x = (float)fb_width; }
if (clip_max.y > fb_height) { clip_max.y = (float)fb_height; }
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue;
Draw::ClippedDraw clippedDraw;
clippedDraw.pipeline = boundPipeline;
clippedDraw.bindTexture = boundTexture;
clippedDraw.bindFramebufferAsTex = boundFBAsTexture;
clippedDraw.samplerState = boundSampler;
clippedDraw.clipx = clip_min.x;
clippedDraw.clipy = clip_min.y;
clippedDraw.clipw = clip_max.x - clip_min.x;
clippedDraw.cliph = clip_max.y - clip_min.y;
clippedDraw.indexCount = pcmd->ElemCount;
clippedDraw.indexOffset = pcmd->IdxOffset;
draws.push_back(clippedDraw);
}
draw->DrawIndexedClippedBatchUP(cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.size(), cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.size(), draws);
draw->DrawIndexedClippedBatchUP(cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.size(), cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.size(), draws, &ub, sizeof(ub));
}
draw->SetScissorRect(0, 0, fb_width, fb_height);
@ -188,7 +162,7 @@ bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw) {
bd->fontSampler = draw->CreateSamplerState(desc);
}
if (!bd->pipeline) {
if (!bd->pipelines[0]) {
BackendData* bd = ImGui_ImplThin3d_GetBackendData();
using namespace Draw;
@ -207,6 +181,7 @@ bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw) {
BlendFactor::SRC_ALPHA, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendOp::ADD,
BlendFactor::ONE, BlendFactor::ONE_MINUS_SRC_ALPHA, BlendOp::ADD,
});
BlendState *blendOpaque = draw->CreateBlendState({ false, 0xF });
DepthStencilStateDesc dsDesc{};
DepthStencilState *depthStencil = draw->CreateDepthStencilState(dsDesc);
@ -225,7 +200,15 @@ bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw) {
&vsTexColBufDesc
};
bd->pipeline = draw->CreateGraphicsPipeline(pipelineDesc, "imgui-pipeline");
bd->pipelines[0] = draw->CreateGraphicsPipeline(pipelineDesc, "imgui-pipeline");
pipelineDesc.blend = blendOpaque;
bd->pipelines[1] = draw->CreateGraphicsPipeline(pipelineDesc, "imgui-pipeline-opaque");
inputLayout->Release();
blend->Release();
blendOpaque->Release();
depthStencil->Release();
rasterNoCull->Release();
}
if (!bd->fontImage) {
@ -261,9 +244,11 @@ void ImGui_ImplThin3d_DestroyDeviceObjects() {
bd->fontImage = nullptr;
io.Fonts->SetTexID(0);
}
if (bd->pipeline) {
bd->pipeline->Release();
bd->pipeline = nullptr;
for (int i = 0; i < ARRAY_SIZE(bd->pipelines); i++) {
if (bd->pipelines[i]) {
bd->pipelines[i]->Release();
bd->pipelines[i] = nullptr;
}
}
if (bd->fontSampler) {
bd->fontSampler->Release();
@ -324,7 +309,7 @@ void ImGui_ImplThin3d_NewFrame(Draw::DrawContext *draw, Lin::Matrix4x4 drawMatri
g_drawMatrix = drawMatrix;
}
ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, Draw::Pipeline *pipeline) {
ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, ImGuiPipeline pipeline) {
BackendData* bd = ImGui_ImplThin3d_GetBackendData();
RegisteredTexture tex{ false };
@ -335,7 +320,7 @@ ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, Draw::Pipeli
return (ImTextureID)(uint64_t)(TEX_ID_OFFSET + bd->tempTextures.size() - 1);
}
ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect, Draw::Pipeline *pipeline) {
ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect, ImGuiPipeline pipeline) {
BackendData* bd = ImGui_ImplThin3d_GetBackendData();
RegisteredTexture tex{ true };

View file

@ -34,17 +34,22 @@
#include "Common/Math/lin/matrix4x4.h"
// Called by user code. Takes ownership of the font buffer and later deletes it.
IMGUI_IMPL_API bool ImGui_ImplThin3d_Init(Draw::DrawContext *draw, const uint8_t *ttf_font, size_t size);
IMGUI_IMPL_API void ImGui_ImplThin3d_Shutdown();
IMGUI_IMPL_API void ImGui_ImplThin3d_NewFrame(Draw::DrawContext *draw, Lin::Matrix4x4 drawMatrix);
IMGUI_IMPL_API void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *draw);
IMGUI_IMPL_API bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw);
IMGUI_IMPL_API void ImGui_ImplThin3d_DestroyDeviceObjects();
IMGUI_IMPL_API bool ImGui_ImplThin3d_Init(Draw::DrawContext *draw, const uint8_t *ttf_font, size_t size);
IMGUI_IMPL_API void ImGui_ImplThin3d_Shutdown();
IMGUI_IMPL_API void ImGui_ImplThin3d_NewFrame(Draw::DrawContext *draw, Lin::Matrix4x4 drawMatrix);
IMGUI_IMPL_API void ImGui_ImplThin3d_RenderDrawData(ImDrawData* draw_data, Draw::DrawContext *draw);
IMGUI_IMPL_API bool ImGui_ImplThin3d_CreateDeviceObjects(Draw::DrawContext *draw);
IMGUI_IMPL_API void ImGui_ImplThin3d_DestroyDeviceObjects();
enum class ImGuiPipeline {
TexturedAlphaBlend = 0,
TexturedOpaque = 1,
};
// These register a texture for imgui drawing, but just for the current frame.
// Textures are unregistered again in RenderDrawData. This is just simpler.
IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, Draw::Pipeline *pipeline = nullptr);
IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect = Draw::FB_COLOR_BIT, Draw::Pipeline *pipeline = nullptr);
IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddTextureTemp(Draw::Texture *texture, ImGuiPipeline pipeline = ImGuiPipeline::TexturedAlphaBlend);
IMGUI_IMPL_API ImTextureID ImGui_ImplThin3d_AddFBAsTextureTemp(Draw::Framebuffer *framebuffer, Draw::FBChannel aspect = Draw::FB_COLOR_BIT, ImGuiPipeline pipeline = ImGuiPipeline::TexturedAlphaBlend);
void ImGui_PushFixedFont();
void ImGui_PopFont();