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,12 +764,10 @@ void Engine::render(const int index) {
}
_imgui->render(0);
_app->render(commandbuffer);
}
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,12 +18,13 @@ 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]] int index) {}
[[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,56 +19,58 @@ void ImGuiPass::initialize() {
create_font_texture();
}
void ImGuiPass::resize(const prism::Extent extent) {
GFXGraphicsPipelineCreateInfo createInfo;
createInfo.label = "ImGui";
createInfo.shaders.vertex_src = file::Path("imgui.vert");
createInfo.shaders.fragment_src = file::Path("imgui.frag");
void ImGuiPass::create_render_target_resources(RenderTarget& target) {
if(pipeline == nullptr) {
GFXGraphicsPipelineCreateInfo createInfo;
createInfo.label = "ImGui";
createInfo.shaders.vertex_src = file::Path("imgui.vert");
createInfo.shaders.fragment_src = file::Path("imgui.frag");
GFXVertexInput vertexInput = {};
vertexInput.stride = sizeof(ImDrawVert);
GFXVertexInput vertexInput = {};
vertexInput.stride = sizeof(ImDrawVert);
createInfo.vertex_input.inputs.push_back(vertexInput);
createInfo.vertex_input.inputs.push_back(vertexInput);
GFXVertexAttribute positionAttribute = {};
positionAttribute.format = GFXVertexFormat::FLOAT2;
positionAttribute.offset = offsetof(ImDrawVert, pos);
GFXVertexAttribute positionAttribute = {};
positionAttribute.format = GFXVertexFormat::FLOAT2;
positionAttribute.offset = offsetof(ImDrawVert, pos);
createInfo.vertex_input.attributes.push_back(positionAttribute);
createInfo.vertex_input.attributes.push_back(positionAttribute);
GFXVertexAttribute uvAttribute = {};
uvAttribute.location = 1;
uvAttribute.format = GFXVertexFormat::FLOAT2;
uvAttribute.offset = offsetof(ImDrawVert, uv);
GFXVertexAttribute uvAttribute = {};
uvAttribute.location = 1;
uvAttribute.format = GFXVertexFormat::FLOAT2;
uvAttribute.offset = offsetof(ImDrawVert, uv);
createInfo.vertex_input.attributes.push_back(uvAttribute);
createInfo.vertex_input.attributes.push_back(uvAttribute);
GFXVertexAttribute colAttribute = {};
colAttribute.location = 2;
colAttribute.format = GFXVertexFormat::UNORM4;
colAttribute.offset = offsetof(ImDrawVert, col);
GFXVertexAttribute colAttribute = {};
colAttribute.location = 2;
colAttribute.format = GFXVertexFormat::UNORM4;
colAttribute.offset = offsetof(ImDrawVert, col);
createInfo.vertex_input.attributes.push_back(colAttribute);
createInfo.vertex_input.attributes.push_back(colAttribute);
createInfo.blending.enable_blending = true;
createInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
createInfo.blending.src_alpha= GFXBlendFactor::SrcAlpha;
createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.blending.enable_blending = true;
createInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
createInfo.blending.src_alpha= GFXBlendFactor::SrcAlpha;
createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.shader_input.push_constants = {
{sizeof(Matrix4x4), 0}
};
createInfo.shader_input.push_constants = {
{sizeof(Matrix4x4), 0}
};
createInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture}
};
createInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture}
};
pipeline = engine->get_gfx()->create_graphics_pipeline(createInfo);
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();
}