Archived
1
Fork 0

Put imgui buffers into render targets

Makes imgui multiviewports work now!
This commit is contained in:
redstrate 2021-02-17 01:32:46 -05:00
parent 77c9561868
commit bb00009041
8 changed files with 93 additions and 70 deletions

View file

@ -755,6 +755,8 @@ void Engine::render(const int index) {
if(window == nullptr)
return;
GFXCommandBuffer* commandbuffer = _gfx->acquire_command_buffer(true);
if(index == 0) {
if(_current_screen != nullptr && _current_screen->view_changed) {
_renderer->update_screen();
@ -762,11 +764,9 @@ void Engine::render(const int index) {
}
_imgui->render(0);
}
GFXCommandBuffer* commandbuffer = _gfx->acquire_command_buffer(true);
_app->render(commandbuffer);
}
if(_renderer != nullptr)
_renderer->render(commandbuffer, _current_scene, *window->render_target, index);

View file

@ -15,23 +15,17 @@ class ImGuiPass : public Pass {
public:
void initialize() override;
void resize(const prism::Extent extent) override;
void create_render_target_resources(RenderTarget& target) override;
void render_post(GFXCommandBuffer* command_buffer, const int index) override;
void render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const int index) override;
private:
void load_font(const std::string_view filename);
void create_font_texture();
void update_buffers(const ImDrawData& draw_data);
void update_buffers(RenderTarget& target, const ImDrawData& draw_data);
std::unique_ptr<file::File> font_file;
GFXPipeline* pipeline = nullptr;
GFXTexture* font_texture = nullptr;
GFXBuffer* vertex_buffer = nullptr;
int current_vertex_size = 0;
GFXBuffer* index_buffer = nullptr;
int current_index_size = 0;
};

View file

@ -10,6 +10,7 @@ enum class PassTextureType {
};
class GFXTexture;
class RenderTarget;
class Pass {
public:
@ -17,11 +18,12 @@ public:
virtual void initialize() {}
virtual void resize([[maybe_unused]] const prism::Extent extent) {}
virtual void create_render_target_resources([[maybe_used]] RenderTarget& target) {}
virtual void render_scene([[maybe_unused]] Scene& scene,
[[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
virtual void render_post([[maybe_unused]] GFXCommandBuffer* commandBuffer,
[[maybe_unused]] RenderTarget& target,
[[maybe_unused]] int index) {}
virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; }

View file

@ -31,4 +31,11 @@ public:
GFXFramebuffer* edge_framebuffer = nullptr;
GFXFramebuffer* blend_framebuffer = nullptr;
// imgui
GFXBuffer* vertex_buffer = nullptr;
int current_vertex_size = 0;
GFXBuffer* index_buffer = nullptr;
int current_index_size = 0;
};

View file

@ -19,7 +19,8 @@ void ImGuiPass::initialize() {
create_font_texture();
}
void ImGuiPass::resize(const prism::Extent extent) {
void ImGuiPass::create_render_target_resources(RenderTarget& target) {
if(pipeline == nullptr) {
GFXGraphicsPipelineCreateInfo createInfo;
createInfo.label = "ImGui";
createInfo.shaders.vertex_src = file::Path("imgui.vert");
@ -66,9 +67,10 @@ void ImGuiPass::resize(const prism::Extent extent) {
};
pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo);
}
}
void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, const int index) {
void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, RenderTarget& target, const int index) {
ImDrawData* draw_data = nullptr;
if(index == 0) {
draw_data = ImGui::GetDrawData();
@ -95,12 +97,12 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, const int index) {
Expects(framebuffer_width > 0);
Expects(framebuffer_height > 0);
update_buffers(*draw_data);
update_buffers(target, *draw_data);
command_buffer->set_graphics_pipeline(pipeline);
command_buffer->set_vertex_buffer(vertex_buffer, 0, 0);
command_buffer->set_index_buffer(index_buffer, IndexType::UINT16);
command_buffer->set_vertex_buffer(target.vertex_buffer, 0, 0);
command_buffer->set_index_buffer(target.index_buffer, IndexType::UINT16);
const Matrix4x4 projection = transform::orthographic(draw_data->DisplayPos.x,
draw_data->DisplayPos.x + draw_data->DisplaySize.x,
@ -187,21 +189,21 @@ void ImGuiPass::create_font_texture() {
io.Fonts->TexID = reinterpret_cast<void*>(font_texture);
}
void ImGuiPass::update_buffers(const ImDrawData& draw_data) {
void ImGuiPass::update_buffers(RenderTarget& target, const ImDrawData& draw_data) {
const int new_vertex_size = draw_data.TotalVtxCount * sizeof(ImDrawVert);
const int new_index_size = draw_data.TotalIdxCount * sizeof(ImDrawIdx);
Expects(new_vertex_size > 0);
Expects(new_index_size > 0);
if(vertex_buffer == nullptr || current_vertex_size < new_vertex_size) {
vertex_buffer = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex);
current_vertex_size = new_vertex_size;
if(target.vertex_buffer == nullptr || target.current_vertex_size < new_vertex_size) {
target.vertex_buffer = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex);
target.current_vertex_size = new_vertex_size;
}
if(index_buffer == nullptr || current_index_size < new_index_size) {
index_buffer = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index);
current_index_size = new_index_size;
if(target.index_buffer == nullptr || target.current_index_size < new_index_size) {
target.index_buffer = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index);
target.current_index_size = new_index_size;
}
int vertex_offset = 0;
@ -209,8 +211,8 @@ void ImGuiPass::update_buffers(const ImDrawData& draw_data) {
for(int i = 0; i < draw_data.CmdListsCount; i++) {
const ImDrawList* cmd_list = draw_data.CmdLists[i];
engine->get_gfx()->copy_buffer(vertex_buffer, cmd_list->VtxBuffer.Data, vertex_offset, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
engine->get_gfx()->copy_buffer(index_buffer, cmd_list->IdxBuffer.Data, index_offset, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
engine->get_gfx()->copy_buffer(target.vertex_buffer, cmd_list->VtxBuffer.Data, vertex_offset, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
engine->get_gfx()->copy_buffer(target.index_buffer, cmd_list->IdxBuffer.Data, index_offset, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vertex_offset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
index_offset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);

View file

@ -172,7 +172,7 @@ void Renderer::resize_render_target(RenderTarget& target, const prism::Extent ex
createUIPipeline();
for(auto& pass : passes)
pass->resize(extent);
pass->create_render_target_resources(target);
}
void Renderer::recreate_all_render_targets() {
@ -225,6 +225,24 @@ void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
const auto extent = target.extent;
const auto render_extent = target.get_render_extent();
if(index > 0) {
GFXRenderPassBeginInfo beginInfo = {};
beginInfo.render_area.extent = render_extent;
commandbuffer->set_render_pass(beginInfo);
Viewport viewport = {};
viewport.width = render_extent.width;
viewport.height = render_extent.height;
commandbuffer->set_viewport(viewport);
for(auto& pass : passes)
pass->render_post(commandbuffer, target, index);
return;
}
commandbuffer->push_group("Scene Rendering");
GFXRenderPassBeginInfo beginInfo = {};
@ -368,7 +386,7 @@ void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->push_group("Extra Passes");
for(auto& pass : passes)
pass->render_post(commandbuffer, index);
pass->render_post(commandbuffer, target, index);
commandbuffer->pop_group();
}

View file

@ -47,7 +47,7 @@ class DebugPass : public Pass {
public:
void initialize() override;
void resize(const prism::Extent extent) override;
void create_render_target_resources(RenderTarget& target) override;
void render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) override;

View file

@ -170,8 +170,8 @@ void DebugPass::initialize() {
}
}
void DebugPass::resize(const prism::Extent extent) {
this->extent = extent;
void DebugPass::create_render_target_resources(RenderTarget& target) {
this->extent = target.extent;
createOffscreenResources();
}