| 150 | } |
| 151 | |
| 152 | void ImguiRenderer::UpdateBuffers() |
| 153 | { |
| 154 | UiDataBuffer & dataBuffer = m_uiDataBuffer[m_updateIndex]; |
| 155 | dataBuffer.m_drawCalls.clear(); |
| 156 | |
| 157 | ImDrawData * dd = ImGui::GetDrawData(); |
| 158 | auto const fbWidth = static_cast<int>(dd->DisplaySize.x * dd->FramebufferScale.x); |
| 159 | auto const fbHeight = static_cast<int>(dd->DisplaySize.y * dd->FramebufferScale.y); |
| 160 | if (fbWidth <= 0 || fbHeight <= 0 || dd->CmdListsCount == 0 || dd->TotalIdxCount == 0 || dd->TotalVtxCount == 0) |
| 161 | return; |
| 162 | dataBuffer.m_width = static_cast<uint32_t>(fbWidth); |
| 163 | dataBuffer.m_height = static_cast<uint32_t>(fbHeight); |
| 164 | |
| 165 | CHECK(dd->TotalVtxCount <= std::numeric_limits<uint16_t>::max(), |
| 166 | ("UI is so complex and now requires 32-bit indices. You need to improve dp::MeshObject or simplify UI")); |
| 167 | |
| 168 | CHECK((ImGui::GetIO().BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) == 0, ()); |
| 169 | |
| 170 | dataBuffer.m_vertices.resize(dd->TotalVtxCount); |
| 171 | dataBuffer.m_indices.resize(dd->TotalIdxCount); |
| 172 | |
| 173 | int totalDrawCallsCount = 0; |
| 174 | for (int i = 0; i < dd->CmdListsCount; ++i) |
| 175 | totalDrawCallsCount += dd->CmdLists[i]->CmdBuffer.Size; |
| 176 | dataBuffer.m_drawCalls.reserve(totalDrawCallsCount); |
| 177 | |
| 178 | ImVec2 const clipOff = dd->DisplayPos; |
| 179 | ImVec2 const clipScale = dd->FramebufferScale; |
| 180 | |
| 181 | uint32_t vertexOffset = 0; |
| 182 | uint32_t indexOffset = 0; |
| 183 | for (int i = 0; i < dd->CmdListsCount; ++i) |
| 184 | { |
| 185 | ImDrawList const * cmdList = dd->CmdLists[i]; |
| 186 | for (int j = 0; j < cmdList->VtxBuffer.Size; ++j) |
| 187 | { |
| 188 | dp::Color color(cmdList->VtxBuffer.Data[j].col); |
| 189 | dataBuffer.m_vertices[j + vertexOffset] = { |
| 190 | .position = {cmdList->VtxBuffer.Data[j].pos.x, cmdList->VtxBuffer.Data[j].pos.y}, |
| 191 | .texCoords = {cmdList->VtxBuffer.Data[j].uv.x, cmdList->VtxBuffer.Data[j].uv.y}, |
| 192 | .color = {color.GetAlphaF(), color.GetBlueF(), color.GetGreenF(), |
| 193 | color.GetRedF()} // Byte order is reversed in imGui |
| 194 | }; |
| 195 | } |
| 196 | |
| 197 | static_assert(sizeof(uint16_t) == sizeof(ImDrawIdx)); |
| 198 | memcpy(dataBuffer.m_indices.data() + indexOffset, cmdList->IdxBuffer.Data, |
| 199 | cmdList->IdxBuffer.Size * sizeof(ImDrawIdx)); |
| 200 | for (int j = 0; j < cmdList->IdxBuffer.Size; ++j) |
| 201 | { |
| 202 | uint32_t indexValue = dataBuffer.m_indices[j + indexOffset]; |
| 203 | indexValue += vertexOffset; |
| 204 | CHECK(indexValue <= std::numeric_limits<uint16_t>::max(), ()); |
| 205 | dataBuffer.m_indices[j + indexOffset] = static_cast<uint16_t>(indexValue); |
| 206 | } |
| 207 | |
| 208 | for (int cmdIndex = 0; cmdIndex < cmdList->CmdBuffer.Size; ++cmdIndex) |
| 209 | { |