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) if(window == nullptr)
return; return;
GFXCommandBuffer* commandbuffer = _gfx->acquire_command_buffer(true);
if(index == 0) { if(index == 0) {
if(_current_screen != nullptr && _current_screen->view_changed) { if(_current_screen != nullptr && _current_screen->view_changed) {
_renderer->update_screen(); _renderer->update_screen();
@ -762,12 +764,10 @@ void Engine::render(const int index) {
} }
_imgui->render(0); _imgui->render(0);
_app->render(commandbuffer);
} }
GFXCommandBuffer* commandbuffer = _gfx->acquire_command_buffer(true);
_app->render(commandbuffer);
if(_renderer != nullptr) if(_renderer != nullptr)
_renderer->render(commandbuffer, _current_scene, *window->render_target, index); _renderer->render(commandbuffer, _current_scene, *window->render_target, index);

View file

@ -14,24 +14,18 @@ struct ImDrawData;
class ImGuiPass : public Pass { class ImGuiPass : public Pass {
public: public:
void initialize() override; 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: private:
void load_font(const std::string_view filename); void load_font(const std::string_view filename);
void create_font_texture(); 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; std::unique_ptr<file::File> font_file;
GFXPipeline* pipeline = nullptr; GFXPipeline* pipeline = nullptr;
GFXTexture* font_texture = 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 GFXTexture;
class RenderTarget;
class Pass { class Pass {
public: public:
@ -17,12 +18,13 @@ public:
virtual void initialize() {} 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, virtual void render_scene([[maybe_unused]] Scene& scene,
[[maybe_unused]] GFXCommandBuffer* commandBuffer) {} [[maybe_unused]] GFXCommandBuffer* commandBuffer) {}
virtual void render_post([[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; } virtual GFXTexture* get_requested_texture([[maybe_unused]] PassTextureType type) { return nullptr; }
}; };

View file

@ -31,4 +31,11 @@ public:
GFXFramebuffer* edge_framebuffer = nullptr; GFXFramebuffer* edge_framebuffer = nullptr;
GFXFramebuffer* blend_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(); create_font_texture();
} }
void ImGuiPass::resize(const prism::Extent extent) { void ImGuiPass::create_render_target_resources(RenderTarget& target) {
GFXGraphicsPipelineCreateInfo createInfo; if(pipeline == nullptr) {
createInfo.label = "ImGui"; GFXGraphicsPipelineCreateInfo createInfo;
createInfo.shaders.vertex_src = file::Path("imgui.vert"); createInfo.label = "ImGui";
createInfo.shaders.fragment_src = file::Path("imgui.frag"); createInfo.shaders.vertex_src = file::Path("imgui.vert");
createInfo.shaders.fragment_src = file::Path("imgui.frag");
GFXVertexInput vertexInput = {}; GFXVertexInput vertexInput = {};
vertexInput.stride = sizeof(ImDrawVert); vertexInput.stride = sizeof(ImDrawVert);
createInfo.vertex_input.inputs.push_back(vertexInput); createInfo.vertex_input.inputs.push_back(vertexInput);
GFXVertexAttribute positionAttribute = {}; GFXVertexAttribute positionAttribute = {};
positionAttribute.format = GFXVertexFormat::FLOAT2; positionAttribute.format = GFXVertexFormat::FLOAT2;
positionAttribute.offset = offsetof(ImDrawVert, pos); positionAttribute.offset = offsetof(ImDrawVert, pos);
createInfo.vertex_input.attributes.push_back(positionAttribute); createInfo.vertex_input.attributes.push_back(positionAttribute);
GFXVertexAttribute uvAttribute = {}; GFXVertexAttribute uvAttribute = {};
uvAttribute.location = 1; uvAttribute.location = 1;
uvAttribute.format = GFXVertexFormat::FLOAT2; uvAttribute.format = GFXVertexFormat::FLOAT2;
uvAttribute.offset = offsetof(ImDrawVert, uv); uvAttribute.offset = offsetof(ImDrawVert, uv);
createInfo.vertex_input.attributes.push_back(uvAttribute); createInfo.vertex_input.attributes.push_back(uvAttribute);
GFXVertexAttribute colAttribute = {}; GFXVertexAttribute colAttribute = {};
colAttribute.location = 2; colAttribute.location = 2;
colAttribute.format = GFXVertexFormat::UNORM4; colAttribute.format = GFXVertexFormat::UNORM4;
colAttribute.offset = offsetof(ImDrawVert, col); 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.enable_blending = true;
createInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha; createInfo.blending.src_rgb = GFXBlendFactor::SrcAlpha;
createInfo.blending.src_alpha= GFXBlendFactor::SrcAlpha; createInfo.blending.src_alpha= GFXBlendFactor::SrcAlpha;
createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha; createInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha; createInfo.blending.dst_alpha = GFXBlendFactor::OneMinusSrcAlpha;
createInfo.shader_input.push_constants = { createInfo.shader_input.push_constants = {
{sizeof(Matrix4x4), 0} {sizeof(Matrix4x4), 0}
}; };
createInfo.shader_input.bindings = { createInfo.shader_input.bindings = {
{1, GFXBindingType::PushConstant}, {1, GFXBindingType::PushConstant},
{2, GFXBindingType::Texture} {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; ImDrawData* draw_data = nullptr;
if(index == 0) { if(index == 0) {
draw_data = ImGui::GetDrawData(); draw_data = ImGui::GetDrawData();
@ -95,12 +97,12 @@ void ImGuiPass::render_post(GFXCommandBuffer* command_buffer, const int index) {
Expects(framebuffer_width > 0); Expects(framebuffer_width > 0);
Expects(framebuffer_height > 0); Expects(framebuffer_height > 0);
update_buffers(*draw_data); update_buffers(target, *draw_data);
command_buffer->set_graphics_pipeline(pipeline); command_buffer->set_graphics_pipeline(pipeline);
command_buffer->set_vertex_buffer(vertex_buffer, 0, 0); command_buffer->set_vertex_buffer(target.vertex_buffer, 0, 0);
command_buffer->set_index_buffer(index_buffer, IndexType::UINT16); command_buffer->set_index_buffer(target.index_buffer, IndexType::UINT16);
const Matrix4x4 projection = transform::orthographic(draw_data->DisplayPos.x, const Matrix4x4 projection = transform::orthographic(draw_data->DisplayPos.x,
draw_data->DisplayPos.x + draw_data->DisplaySize.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); 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_vertex_size = draw_data.TotalVtxCount * sizeof(ImDrawVert);
const int new_index_size = draw_data.TotalIdxCount * sizeof(ImDrawIdx); const int new_index_size = draw_data.TotalIdxCount * sizeof(ImDrawIdx);
Expects(new_vertex_size > 0); Expects(new_vertex_size > 0);
Expects(new_index_size > 0); Expects(new_index_size > 0);
if(vertex_buffer == nullptr || current_vertex_size < new_vertex_size) { if(target.vertex_buffer == nullptr || target.current_vertex_size < new_vertex_size) {
vertex_buffer = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex); target.vertex_buffer = engine->get_gfx()->create_buffer(nullptr, new_vertex_size, true, GFXBufferUsage::Vertex);
current_vertex_size = new_vertex_size; target.current_vertex_size = new_vertex_size;
} }
if(index_buffer == nullptr || current_index_size < new_index_size) { if(target.index_buffer == nullptr || target.current_index_size < new_index_size) {
index_buffer = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index); target.index_buffer = engine->get_gfx()->create_buffer(nullptr, new_index_size, true, GFXBufferUsage::Index);
current_index_size = new_index_size; target.current_index_size = new_index_size;
} }
int vertex_offset = 0; 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++) { for(int i = 0; i < draw_data.CmdListsCount; i++) {
const ImDrawList* cmd_list = draw_data.CmdLists[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(target.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.index_buffer, cmd_list->IdxBuffer.Data, index_offset, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
vertex_offset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert); vertex_offset += cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
index_offset += cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx); 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(); createUIPipeline();
for(auto& pass : passes) for(auto& pass : passes)
pass->resize(extent); pass->create_render_target_resources(target);
} }
void Renderer::recreate_all_render_targets() { void Renderer::recreate_all_render_targets() {
@ -224,6 +224,24 @@ void Renderer::update_screen() {
void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) { void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarget& target, int index) {
const auto extent = target.extent; const auto extent = target.extent;
const auto render_extent = target.get_render_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"); commandbuffer->push_group("Scene Rendering");
@ -368,7 +386,7 @@ void Renderer::render(GFXCommandBuffer* commandbuffer, Scene* scene, RenderTarge
commandbuffer->push_group("Extra Passes"); commandbuffer->push_group("Extra Passes");
for(auto& pass : passes) for(auto& pass : passes)
pass->render_post(commandbuffer, index); pass->render_post(commandbuffer, target, index);
commandbuffer->pop_group(); commandbuffer->pop_group();
} }

View file

@ -47,8 +47,8 @@ class DebugPass : public Pass {
public: public:
void initialize() override; 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; void render_scene(Scene& scene, GFXCommandBuffer* commandBuffer) override;
void get_selected_object(int x, int y, std::function<void(SelectableObject)> callback); void get_selected_object(int x, int y, std::function<void(SelectableObject)> callback);

View file

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