前段时间,我按照一些 SDL 教程对一些图像进行了 blit,并有一个测试函数循环遍历 SDL 纹理和目标反应的向量,然后调用以下函数将图像复制到窗口中。
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);
}
}
这一切都“有效”,因为它可以很好地渲染所有“精灵”
然后我设置了很好的 imgui(我重写了大部分 sdl/vulkan 示例以使用 vulkan c++ 绑定而不是 c api)90% 的代码/结构来自 imgui 示例https://github.com/ocornut /imgui/blob/master/examples/example_sdl_vulkan/main.cpp 每个部分组织成单独的函数。
// 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
}
imgui 设置再次“起作用”,因为我成功显示了演示窗口。此外,我可以轻松制作自己的窗口,而且 API 没有问题。
我的问题是我只能让这两个概念分开工作。如果我删除清除屏幕/将清除值复制到 clear_color 背景颜色gui.clear(false);
而不是gui.clear(true)
imgui 清除颜色为黑色/它仍然覆盖 sdl 精灵。(与将清除值设置为 0 的 alpha 相同。)我尝试在 imgui 框架之前和之后订购“drawSprites”调用,但它总是覆盖它/覆盖它。
我意识到我没有包括一个最小的可重现示例,我没有包括所有的 imgui 函数,而是它的大量样板文件(vulkan 使设置/渲染/呈现函数超过 100 行,并且包括上下文的设置推动了另一个600 多行。)
有谁知道如何防止 imgui 清除屏幕(我已经在 sdl 部分清除屏幕)(可能更改渲染通道?)
//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);
}
我尝试将清除值 count/pClearValue 设置为 NULL,但这只会使 info 结构不再有效/崩溃(必须至少有 1 个条目),并且我重新检查了此时清除颜色的 alpha 为 0。
或者,我可以尝试将所有 sdl 绘图合并到 imgui 命令缓冲区中(或者用纯 vulkan 替换 sdl 绘图)
我已经调试了好几个小时,慢慢地重写所有示例代码,以了解它的设置方式,但我处于与多年前完全相同的位置,在窗口的其余部分之上绘制几乎没有进展.
我可能不得不重做整个 Vulkan 教程,因为我接触它已经一年了,我的问题可能很明显,但我希望因为我使用 imgui 和 sdl,我可以先写一点引擎,然后再回到渲染后端如果需要,以后再优化东西。