Put imgui buffers into render targets
Makes imgui multiviewports work now!
This commit is contained in:
parent
77c9561868
commit
bb00009041
8 changed files with 93 additions and 70 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Reference in a new issue