some time ago I followed some SDL tutorial to blit some images and have a test function that loops through a vector of SDL textures and destination reacts and then call the following function to copy the image into the window.
void SpriteSheets::draw(const Sprite* sprite, SDL_Rect* dest) {
SDL_RenderCopy(renderer, sprite->texture, sprite->rect, dest);
SDL_RenderPresent(renderer);
}
// this is probably not relevant but including the clear/calling the draw function
void SpriteSheets::clearScreen() {
SDL_SetRenderDrawColor(renderer, 150, 0, 100, 0); // debug color
SDL_RenderClear(renderer);
}
void GameContext::drawSprites() {
const auto& sprites = std::get<comp::sprite>(c.components);
const auto& position = std::get<comp::position>(c.components);
SpriteSheets::clearScreen();
for ( size_t i = 0; i < sprites.size(); i++ ) {
SDL_Rect dest;
dest.h = 50;
dest.w = 50;
dest.x = position[i].x();
dest.y = position[i].y();
SpriteSheets::draw(&sprites[i], &dest);
}
}
This all "works" in that it renders all the "sprites" just fine
Then I setup imgui which was fine (I rewrote most of the sdl/vulkan example to use the vulkan c++ bindings instead of the c api) 90% of the code/structure is from the imgui example https://github.com/ocornut/imgui/blob/master/examples/example_sdl_vulkan/main.cpp with each part organized into separate functions.
// relevant gui clear...
// at some point clear color is set to this
this->clear_color = ImVec4(0.0f, 1.0f, 0.5f, 0.00f); //gross color for debugging
// snip
void Gui::clear(bool should_clear) {
ImGui::Render();
if ( should_clear ) memcpy(&wd.ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
}
// snip
void GraphicContext::mainLoop(GameContext* game) {
//Frame Setup
gui.frameSetup(); //rebuild swapchain if needed and then call imgui begin frame
// draw the "game"
// which is just a few static png's at different locations
game->drawSprites(); //when surounded by imgui functions it is hidden and not displayed
//draw the imgui menu overtop
if ( gui.show_demo_window ) ImGui::ShowDemoWindow(&gui.show_demo_window);
//End frame
gui.clear(false); // has ImGui::Render(); and conditional copy clear color
gui.frameRender(); // put all the imgui commands into a command buffer
gui.framePresent(); // submit Queue
}
Again the imgui setup "works" in that I successfully show the demo window. additionally, I can make my own windows easily and don't have an issue with the API.
My problem is that I can only get these two concepts to work separately.
If I remove the clear screen/ copy clear value to clear_color the background color gui.clear(false);
instead of gui.clear(true)
for imgui the clear color is black/it still covers the sdl sprites. (same with setting the clear value to have an alpha of 0.)
I've tried ordering the "drawSprites" call before and after the imgui frame but its always overwriting it/covering it.
I realize I'm not including a minimal reproducible example and I'm not including all of the imgui functions but its alot of boilerplate (vulkan makes the setup/render/present functions 100+ lines and including the setup for the contexts pushes that another 600+ lines.)
Does anyone know how to either prevent imgui from clearing the screen (I'm already clearing the screen in the sdl section) (change the render pass maybe?)
//relevant part of frameRender()
{
VkRenderPassBeginInfo info{
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.pNext = NULL,
.renderPass = wd.RenderPass,
.framebuffer = fd->Framebuffer,
//.renderArea = {{0,0}, {wd.Width, wd.Height}},
.clearValueCount = 1,
.pClearValues = &wd.ClearValue
};
// the initializer for this doesn't work and idk why.
// when I set the second two zeros in the render area initalizer list to width and height
// it wants to be converted to uint32 but when I do that it crashes with a read acess violation.
info.renderArea.extent.width = wd.Width;
info.renderArea.extent.height = wd.Height;
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
}
I tried setting the clear value count/pClearValue to NULL but that just makes the info struct no longer valid/crash (there must be at least 1 entry) and I rechecked that the alpha was 0 for the clear color at this point.
Alternatively, I could try to combine all the sdl draws into the imgui command buffer (or replace drawing with sdl with pure vulkan)
I've been debugging this for hours slowly rewriting all the example code to get a feel for how its setup but I'm in the exact same position I was ages ago with little to no progress on it drawing overtop of the rest of the window.
I probably have to redo the whole Vulkan tutorial because its been a year since I touched it and my problems probably obvious but I was hoping because I was using imgui and sdl I could write a bit of an engine first and dip back into the rendering backend to optimize stuff later if needed.