Generate mipmaps for a texture using compute shaders, with ImGui and image loading.
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
{
class MipGenerationApp : public RenderApplication
{
public:
{
}
{
int x, y, n;
stbi_uc* data = stbi_load("data/assets/cameraman.jpg", &x, &y, &n, 4);
RHITextureDesc{.usage = RHITextureUsageBits::SampledImage | RHITextureUsageBits::StorageImage |
RHITextureUsageBits::TransferDestination,
.extent = {x, y, 1},
.format = RHIResourceFormat::R8G8B8A8Unorm,
.mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::min(x, y))))});
Span<char> span(reinterpret_cast<char*>(data), reinterpret_cast<char*>(data) + x * y * 4);
upload.SubmitAndWait();
}
{
ResourceHandle srcHandle = createResource(
mRenderer.get(),
"Image", srcTex);
ResourceHandle renderedHandle =
createResource(
mRenderer.get(),
"Rendered Image",
RHITextureDesc{
.usage = RHITextureUsageBits::SampledImage | RHITextureUsageBits::RenderTarget,
.extent = srcTex->mDesc.extent,
.format = RHIResourceFormat::R8G8B8A8Unorm,
});
ResourceHandle sampler = createSampler(
mRenderer.get(), {});
createCSMipGenerationPasses(
mRenderer.get(),
"Mip Gen", RHIDeviceQueueType::Compute, srcHandle, srcHandle,
RHITextureAspectFlagBits::Color, RHIResourceFormat::R8G8B8A8Unorm,
RHITextureAspectFlagBits::Color, RHIResourceFormat::R8G8B8A8Unorm, 16, 0);
createPass(
mRenderer.get(),
"Blur", RHIDeviceQueueType::Graphics,
[=](PassHandle self, Renderer* r)
{
r->BindShader(self, RHIShaderStageBits::Vertex, "vertMain", "data/shaders/VSFullscreen.spv");
r->BindShader(self, RHIShaderStageBits::Fragment, "fragMain", "data/shaders/MipGenerationBlur.spv");
r->BindTextureSRV(self, srcHandle, "srcTexture", RHIPipelineStageBits::FragmentShader,
{.format = RHIResourceFormat::R8G8B8A8Unorm,
.range = RHITextureSubresourceRange::Create(RHITextureAspectFlagBits::Color, 0,
srcTex->mDesc.mipLevels)});
r->BindTextureSampler(self, sampler, "srcSampler");
r->BindTextureRTV(
self, renderedHandle,
{.format = RHIResourceFormat::R8G8B8A8Unorm, .range = RHITextureSubresourceRange::Create()});
r->BindPushConstant(self, RHIShaderStageBits::Fragment, 0, sizeof(float));
},
[=, this](PassHandle self, Renderer* r, RHICommandList* cmd)
{
auto const& img_wh = r->DerefResource(renderedHandle).Get<RHITexture*>()->
mDesc.extent;
r->CmdBeginGraphics(self, cmd, img_wh, {}, {});
r->CmdSetPipeline(self, cmd);
r->CmdSetPushConstant(self, cmd, RHIShaderStageBits::Fragment, 0,
mBlur);
cmd->SetViewport(0, 0, img_wh.x, img_wh.y).SetScissor(0, 0, img_wh.x, img_wh.y);
cmd->Draw(3);
cmd->EndGraphics();
});
[=, this](PassHandle self, Renderer* r)
{
mRenderedSRV =
r->BindTextureSRV(self, renderedHandle, kBindpointIgnored,
RHIPipelineStageBits::FragmentShader,
{
.format = RHIResourceFormat::R8G8B8A8Unorm,
.range = RHITextureSubresourceRange::Create(),
});
});
}
ImTextureID mRenderedImageID{0};
void OnRendererPostSetup() override
{
if (mRenderedImageID != 0)
auto* srv = mRenderer->DerefTextureView(mRenderedSRV);
}
void OnBeforeFrame() override
{
ImGui::NewFrame();
ImGui::SetNextWindowPos({0, 0});
ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
ImGui::Begin("Viewer");
ImGui::Image(mRenderedImageID, ImVec2(512, 512));
ImGui::SliderFloat("Blur", &mBlur, 0.0f, 10.0f);
ImGui::End();
}
};
}
int main(
int argc,
char** argv)
{
app.
Initialize<VulkanApplication>({.windowTitle =
"Mipmap Generation"});
}
int main(int argc, char **argv)
Definition ImGui.cpp:26
auto * ImGui_ImplFoundation_CreatePass(Foundation::RenderCore::Renderer *renderer, Foundation::Core::StringView name, bool clear, FSetup &&setup)
Creates a render pass that will draw the ImGui UI.
Definition ImGui.hpp:97
void ImGui_ImplFoundation_Init(RHIDevice *device, Native::NativeWindow *window, Allocator *allocator)
Definition ImGui.cpp:35
void ImGui_ImplFoundation_NewFrame()
Starts a new ImGui frame.
Definition ImGui.cpp:52
void ImGui_ImplFoundation_Shutdown()
Shuts down the ImGui backend and releases all resources.
Definition ImGui.cpp:57
void ImGui_ImplFoundation_SetupContextWithDefaultStyles()
Applies a default, vaguely stylish theme to the ImGui context.
Definition ImGui.cpp:296
void ImGui_ImplFoundation_RemoveImage(ImTextureID textureID)
Unregisters a texture from the ImGui backend.
Definition ImGui.cpp:135
ImTextureID ImGui_ImplFoundation_AddImage(RHITextureView *textureView, ImGui_ImplFoundation_ImageSampler sampler)
Registers a texture with the ImGui backend so it can be displayed in the UI.
Definition ImGui.cpp:129
Definition MipGeneration.cpp:16
float mBlur
Definition MipGeneration.cpp:30
ResourceHandle mRenderedSRV
Definition MipGeneration.cpp:29
TexturePoolHandle mSampleImage
Definition MipGeneration.cpp:28
void OnRendererSetup() override
Set up the renderer by creating passes, resources, and other configurations.
Definition MipGeneration.cpp:50
UniquePtr< TexturePool > mTexturePool
Definition MipGeneration.cpp:21
~MipGenerationApp() override
Definition MipGeneration.cpp:22
void OnDeviceSetup() override
Actions to take after device specific resources has been set up.
Definition MipGeneration.cpp:31
Allocator * Ptr()
Definition Allocator.hpp:38
Allocator * GetAllocator()
Retrieve the allocator used for general application allocations.
Definition Application.hpp:244
ApplicationInitDesc mDesc
Definition Application.hpp:93
void Initialize(ApplicationInitDesc const &desc={}, Args &&... args)
Initialize the application with the specified RHI backend.
Definition Application.hpp:205
RHIApplicationScopedObjectHandle< RHIDevice > mDevice
Definition Application.hpp:99
Native::NativeWindow * GetNativeWindow()
Retrieve the current NativeWindow instance.
Definition Application.hpp:240
DefaultAllocator mAlloc
Definition Application.hpp:95
UniquePtr< Renderer > mRenderer
Definition Application.hpp:102
void RunForever()
Start the Render thread and run the application loop indefinitely, until the window is closed or the ...
Definition Application.cpp:127
For a complete list of examples, see the Examples Page.
Definition Examples.hpp:12