57 const std::shared_ptr<impeller::Context>& context) {
58 ImGuiIO& io = ImGui::GetIO();
59 IM_ASSERT(io.BackendRendererUserData ==
nullptr &&
60 "Already initialized a renderer backend!");
65 io.BackendRendererUserData =
reinterpret_cast<void*
>(bd);
66 io.BackendRendererName =
"imgui_impl_impeller";
68 ImGuiBackendFlags_RendererHasVtxOffset;
72 bd->context = context;
76 unsigned char* pixels;
78 io.Fonts->GetTexDataAsRGBA32(&pixels, &
width, &
height);
84 texture_descriptor.mip_count = 1u;
87 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
88 IM_ASSERT(bd->font_texture !=
nullptr &&
89 "Could not allocate ImGui font texture.");
90 bd->font_texture->SetLabel(
"ImGui Font Texture");
92 [[maybe_unused]]
bool uploaded = bd->font_texture->SetContents(
93 pixels, texture_descriptor.GetByteSizeOfBaseMipLevel());
95 "Could not upload ImGui font texture to device memory.");
101 impeller::ImguiRasterFragmentShader>::
102 MakeDefaultPipelineDescriptor(*context);
103 IM_ASSERT(desc.has_value() &&
"Could not create Impeller pipeline");
104 if (desc.has_value()) {
106 desc->ClearStencilAttachments();
107 desc->ClearDepthAttachment();
111 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
112 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui pipeline.");
113 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui sampler.");
128 if (draw_data->CmdListsCount == 0) {
132 render_pass.
GetContext()->GetResourceAllocator());
134 using VS = impeller::ImguiRasterVertexShader;
135 using FS = impeller::ImguiRasterFragmentShader;
138 IM_ASSERT(bd !=
nullptr &&
"Did you call ImGui_ImplImpeller_Init()?");
140 size_t total_vtx_bytes = draw_data->TotalVtxCount *
sizeof(VS::PerVertexData);
141 size_t total_idx_bytes = draw_data->TotalIdxCount *
sizeof(ImDrawIdx);
142 if (!total_vtx_bytes || !total_idx_bytes) {
148 buffer_desc.
size = total_vtx_bytes + total_idx_bytes;
151 auto buffer = bd->context->GetResourceAllocator()->CreateBuffer(buffer_desc);
155 draw_data->DisplayPos.x, draw_data->DisplayPos.y,
156 draw_data->DisplaySize.x, draw_data->DisplaySize.y);
159 .
rect = display_rect.
Scale(draw_data->FramebufferScale.x,
160 draw_data->FramebufferScale.y)};
163 VS::UniformBuffer uniforms;
166 auto vtx_uniforms = host_buffer->EmplaceUniform(uniforms);
168 size_t vertex_buffer_offset = 0;
169 size_t index_buffer_offset = total_vtx_bytes;
171 for (
int draw_list_i = 0; draw_list_i < draw_data->CmdListsCount;
173 const ImDrawList* cmd_list = draw_data->CmdLists[draw_list_i];
183 std::vector<VS::PerVertexData> vtx_data;
184 vtx_data.reserve(cmd_list->VtxBuffer.size());
185 for (
const auto& v : cmd_list->VtxBuffer) {
186 ImVec4
color = ImGui::ColorConvertU32ToFloat4(v.col);
187 vtx_data.push_back({{v.pos.x, v.pos.y},
192 auto draw_list_vtx_bytes =
193 static_cast<size_t>(vtx_data.size() *
sizeof(VS::PerVertexData));
194 auto draw_list_idx_bytes =
195 static_cast<size_t>(cmd_list->IdxBuffer.size_in_bytes());
196 if (!
buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*
>(vtx_data.data()),
198 vertex_buffer_offset)) {
199 IM_ASSERT(
false &&
"Could not copy vertices to buffer.");
201 if (!
buffer->CopyHostBuffer(
202 reinterpret_cast<uint8_t*
>(cmd_list->IdxBuffer.Data),
204 IM_ASSERT(
false &&
"Could not copy indices to buffer.");
207 for (
int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
208 const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
210 if (pcmd->UserCallback) {
211 pcmd->UserCallback(cmd_list, pcmd);
215 (pcmd->ClipRect.x - draw_data->DisplayPos.x) *
216 draw_data->FramebufferScale.x,
217 (pcmd->ClipRect.y - draw_data->DisplayPos.y) *
218 draw_data->FramebufferScale.y,
219 (pcmd->ClipRect.z - draw_data->DisplayPos.x) *
220 draw_data->FramebufferScale.x,
221 (pcmd->ClipRect.w - draw_data->DisplayPos.y) *
222 draw_data->FramebufferScale.y);
225 auto visible_clip = clip_rect.Intersection(viewport.rect);
226 if (!visible_clip.has_value()) {
229 clip_rect = visible_clip.value();
234 auto visible_clip = clip_rect.Intersection(
236 if (!visible_clip.has_value()) {
239 clip_rect = visible_clip.value();
243 "ImGui draw list %d (command %d)", draw_list_i, cmd_i));
247 VS::BindUniformBuffer(render_pass, vtx_uniforms);
248 FS::BindTex(render_pass, bd->font_texture, bd->sampler);
251 vertex_buffer_offset + pcmd->VtxOffset *
sizeof(ImDrawVert);
260 index_buffer_offset + pcmd->IdxOffset *
sizeof(ImDrawIdx),
261 pcmd->ElemCount *
sizeof(ImDrawIdx))};
271 vertex_buffer_offset += draw_list_vtx_bytes;
272 index_buffer_offset += draw_list_idx_bytes;
274 host_buffer->Reset();
static const uint8_t buffer[]
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...