14 #include "impeller/playground/imgui/imgui_raster.frag.h"
15 #include "impeller/playground/imgui/imgui_raster.vert.h"
16 #include "third_party/imgui/imgui.h"
37 std::shared_ptr<impeller::Context>
context;
39 std::shared_ptr<impeller::Pipeline<impeller::PipelineDescriptor>>
pipeline;
40 std::shared_ptr<const impeller::Sampler>
sampler;
44 return ImGui::GetCurrentContext()
46 ImGui::GetIO().BackendRendererUserData)
51 const std::shared_ptr<impeller::Context>& context) {
52 ImGuiIO& io = ImGui::GetIO();
53 IM_ASSERT(io.BackendRendererUserData ==
nullptr &&
54 "Already initialized a renderer backend!");
58 io.BackendRendererUserData =
reinterpret_cast<void*
>(bd);
59 io.BackendRendererName =
"imgui_impl_impeller";
61 ImGuiBackendFlags_RendererHasVtxOffset;
65 bd->context = context;
69 unsigned char* pixels;
71 io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
76 texture_descriptor.size = {width, height};
77 texture_descriptor.mip_count = 1u;
80 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
81 IM_ASSERT(bd->font_texture !=
nullptr &&
82 "Could not allocate ImGui font texture.");
83 bd->font_texture->SetLabel(
"ImGui Font Texture");
85 [[maybe_unused]]
bool uploaded = bd->font_texture->SetContents(
86 pixels, texture_descriptor.GetByteSizeOfBaseMipLevel());
88 "Could not upload ImGui font texture to device memory.");
94 impeller::ImguiRasterFragmentShader>::
95 MakeDefaultPipelineDescriptor(*context);
96 IM_ASSERT(desc.has_value() &&
"Could not create Impeller pipeline");
97 if (desc.has_value()) {
99 desc->ClearStencilAttachments();
100 desc->ClearDepthAttachment();
104 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
105 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui pipeline.");
107 bd->sampler = context->GetSamplerLibrary()->GetSampler({});
108 IM_ASSERT(bd->pipeline !=
nullptr &&
"Could not create ImGui sampler.");
116 IM_ASSERT(bd !=
nullptr &&
117 "No renderer backend to shutdown, or already shutdown?");
123 if (draw_data->CmdListsCount == 0) {
127 using VS = impeller::ImguiRasterVertexShader;
128 using FS = impeller::ImguiRasterFragmentShader;
131 IM_ASSERT(bd !=
nullptr &&
"Did you call ImGui_ImplImpeller_Init()?");
133 size_t total_vtx_bytes = draw_data->TotalVtxCount *
sizeof(VS::PerVertexData);
134 size_t total_idx_bytes = draw_data->TotalIdxCount *
sizeof(ImDrawIdx);
135 if (!total_vtx_bytes || !total_idx_bytes) {
141 buffer_desc.
size = total_vtx_bytes + total_idx_bytes;
144 auto buffer = bd->context->GetResourceAllocator()->CreateBuffer(buffer_desc);
148 draw_data->DisplayPos.x, draw_data->DisplayPos.y,
149 draw_data->DisplaySize.x, draw_data->DisplaySize.y);
152 .
rect = display_rect.
Scale(draw_data->FramebufferScale.x,
153 draw_data->FramebufferScale.y)};
156 VS::UniformBuffer uniforms;
162 size_t vertex_buffer_offset = 0;
163 size_t index_buffer_offset = total_vtx_bytes;
165 for (
int draw_list_i = 0; draw_list_i < draw_data->CmdListsCount;
167 const ImDrawList* cmd_list = draw_data->CmdLists[draw_list_i];
177 std::vector<VS::PerVertexData> vtx_data;
178 vtx_data.reserve(cmd_list->VtxBuffer.size());
179 for (
const auto& v : cmd_list->VtxBuffer) {
180 ImVec4 color = ImGui::ColorConvertU32ToFloat4(v.col);
181 vtx_data.push_back({{v.pos.x, v.pos.y},
183 {color.x, color.y, color.z, color.w}});
186 auto draw_list_vtx_bytes =
187 static_cast<size_t>(vtx_data.size() *
sizeof(VS::PerVertexData));
188 auto draw_list_idx_bytes =
189 static_cast<size_t>(cmd_list->IdxBuffer.size_in_bytes());
190 if (!buffer->CopyHostBuffer(
reinterpret_cast<uint8_t*
>(vtx_data.data()),
192 vertex_buffer_offset)) {
193 IM_ASSERT(
false &&
"Could not copy vertices to buffer.");
195 if (!buffer->CopyHostBuffer(
196 reinterpret_cast<uint8_t*
>(cmd_list->IdxBuffer.Data),
198 IM_ASSERT(
false &&
"Could not copy indices to buffer.");
201 for (
int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
202 const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
204 if (pcmd->UserCallback) {
205 pcmd->UserCallback(cmd_list, pcmd);
209 (pcmd->ClipRect.x - draw_data->DisplayPos.x) *
210 draw_data->FramebufferScale.x,
211 (pcmd->ClipRect.y - draw_data->DisplayPos.y) *
212 draw_data->FramebufferScale.y,
213 (pcmd->ClipRect.z - draw_data->DisplayPos.x) *
214 draw_data->FramebufferScale.x,
215 (pcmd->ClipRect.w - draw_data->DisplayPos.y) *
216 draw_data->FramebufferScale.y);
219 auto visible_clip = clip_rect.Intersection(viewport.rect);
220 if (!visible_clip.has_value()) {
223 clip_rect = visible_clip.value();
228 auto visible_clip = clip_rect.Intersection(
230 if (!visible_clip.has_value()) {
233 clip_rect = visible_clip.value();
239 draw_list_i, cmd_i));
245 VS::BindUniformBuffer(cmd, vtx_uniforms);
246 FS::BindTex(cmd, bd->font_texture, bd->sampler);
249 vertex_buffer_offset + pcmd->VtxOffset *
sizeof(ImDrawVert);
258 index_buffer_offset + pcmd->IdxOffset *
sizeof(ImDrawIdx),
259 pcmd->ElemCount *
sizeof(ImDrawIdx))};
269 vertex_buffer_offset += draw_list_vtx_bytes;
270 index_buffer_offset += draw_list_idx_bytes;