Implement ImguiBackend::Render()

Create geometry in Render() before calling Draw()
This commit is contained in:
Attila Uygun 2023-10-29 23:16:08 +01:00
parent e4f020d359
commit 874fec434a
3 changed files with 25 additions and 19 deletions

View File

@ -143,6 +143,8 @@ void Engine::Update(float delta_time) {
if (stats_visible_) if (stats_visible_)
ShowStats(); ShowStats();
imgui_backend_.Render();
} }
void Engine::Draw(float frame_frac) { void Engine::Draw(float frame_frac) {

View File

@ -65,8 +65,6 @@ void ImguiBackend::Initialize() {
Engine::Get().RefreshImage("imgui_atlas"); Engine::Get().RefreshImage("imgui_atlas");
ImGui::GetIO().Fonts->SetTexID( ImGui::GetIO().Fonts->SetTexID(
(ImTextureID)(intptr_t)Engine::Get().AcquireTexture("imgui_atlas")); (ImTextureID)(intptr_t)Engine::Get().AcquireTexture("imgui_atlas"));
NewFrame(0);
} }
void ImguiBackend::Shutdown() { void ImguiBackend::Shutdown() {
@ -117,9 +115,9 @@ std::unique_ptr<InputEvent> ImguiBackend::OnInputEvent(
} }
void ImguiBackend::NewFrame(float delta_time) { void ImguiBackend::NewFrame(float delta_time) {
if (is_new_frame_) for (auto& id : geometries_)
ImGui::EndFrame(); renderer_->DestroyGeometry(id);
is_new_frame_ = true; geometries_.clear();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(), io.DisplaySize = ImVec2((float)renderer_->GetScreenWidth(),
@ -128,11 +126,24 @@ void ImguiBackend::NewFrame(float delta_time) {
ImGui::NewFrame(); ImGui::NewFrame();
} }
void ImguiBackend::Draw() { void ImguiBackend::Render() {
is_new_frame_ = false;
ImGui::Render(); ImGui::Render();
ImDrawData* draw_data = ImGui::GetDrawData(); ImDrawData* draw_data = ImGui::GetDrawData();
if (draw_data->CmdListsCount <= 0) geometries_.resize(draw_data->CmdListsCount);
for (int n = 0; n < draw_data->CmdListsCount; n++) {
const ImDrawList* cmd_list = draw_data->CmdLists[n];
auto mesh = std::make_unique<Mesh>();
mesh->Create(kPrimitive_Triangles, vertex_description,
cmd_list->VtxBuffer.Size, cmd_list->VtxBuffer.Data,
kDataType_UShort, cmd_list->IdxBuffer.Size,
cmd_list->IdxBuffer.Data);
geometries_[n] = renderer_->CreateGeometry(std::move(mesh));
}
}
void ImguiBackend::Draw() {
ImDrawData* draw_data = ImGui::GetDrawData();
if (!draw_data || draw_data->CmdListsCount <= 0)
return; return;
renderer_->SetViewport(0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y); renderer_->SetViewport(0, 0, draw_data->DisplaySize.x, draw_data->DisplaySize.y);
@ -149,26 +160,17 @@ void ImguiBackend::Draw() {
for (int n = 0; n < draw_data->CmdListsCount; n++) { for (int n = 0; n < draw_data->CmdListsCount; n++) {
const ImDrawList* cmd_list = draw_data->CmdLists[n]; const ImDrawList* cmd_list = draw_data->CmdLists[n];
auto mesh = std::make_unique<Mesh>();
mesh->Create(kPrimitive_Triangles, vertex_description,
cmd_list->VtxBuffer.Size, cmd_list->VtxBuffer.Data,
kDataType_UShort, cmd_list->IdxBuffer.Size,
cmd_list->IdxBuffer.Data);
auto geometry_id = renderer_->CreateGeometry(std::move(mesh));
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) {
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
if (pcmd->ClipRect.z <= pcmd->ClipRect.x || if (pcmd->ClipRect.z <= pcmd->ClipRect.x ||
pcmd->ClipRect.w <= pcmd->ClipRect.y) pcmd->ClipRect.w <= pcmd->ClipRect.y)
continue; continue;
reinterpret_cast<Texture*>(pcmd->GetTexID())->Activate(0); reinterpret_cast<Texture*>(pcmd->GetTexID())->Activate(0);
renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y), renderer_->SetScissor(int(pcmd->ClipRect.x), int(pcmd->ClipRect.y),
int(pcmd->ClipRect.z - pcmd->ClipRect.x), int(pcmd->ClipRect.z - pcmd->ClipRect.x),
int(pcmd->ClipRect.w - pcmd->ClipRect.y)); int(pcmd->ClipRect.w - pcmd->ClipRect.y));
renderer_->Draw(geometry_id, pcmd->ElemCount, pcmd->IdxOffset); renderer_->Draw(geometries_[n], pcmd->ElemCount, pcmd->IdxOffset);
} }
renderer_->DestroyGeometry(geometry_id);
} }
renderer_->ResetScissor(); renderer_->ResetScissor();
renderer_->ResetViewport(); renderer_->ResetViewport();

View File

@ -2,6 +2,7 @@
#define ENGINE_IMGUI_BACKEND_H #define ENGINE_IMGUI_BACKEND_H
#include <memory> #include <memory>
#include <vector>
namespace eng { namespace eng {
@ -22,12 +23,13 @@ class ImguiBackend {
std::unique_ptr<InputEvent> OnInputEvent(std::unique_ptr<InputEvent> event); std::unique_ptr<InputEvent> OnInputEvent(std::unique_ptr<InputEvent> event);
void NewFrame(float delta_time); void NewFrame(float delta_time);
void Render();
void Draw(); void Draw();
private: private:
std::vector<uint64_t> geometries_;
std::unique_ptr<Shader> shader_; std::unique_ptr<Shader> shader_;
Renderer* renderer_ = nullptr; Renderer* renderer_ = nullptr;
bool is_new_frame_ = false;
}; };
} // namespace eng } // namespace eng