Model preview: AVA2 render-target window on a Vulkan colour target
Port of AVA2's CRenderTarget / GrpRenderTargetTexture / renderTarget module. The host gains an RGBA8 offscreen colour pass for D3D colour render targets; mt_preview shows wearable items on every allowed race and monsters with motions, reached by X+click in the inventory and shop and from the wiki. Player races are created as TYPE_PC so their parts exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
32372c2a73
commit
84404cf1f1
@@ -270,15 +270,23 @@ void VulkanWindow::ensure_ui_capacity(std::size_t command_count) {
|
||||
}
|
||||
|
||||
VulkanWindow::RenderTarget* VulkanWindow::get_render_target(const std::string& name) {
|
||||
if (auto it = render_targets_.find(name); it != render_targets_.end()) return &it->second;
|
||||
if (auto it = render_targets_.find(name); it != render_targets_.end()) {
|
||||
it->second.last_used_frame = frame_number_;
|
||||
return &it->second;
|
||||
}
|
||||
unsigned id = 0, w = 0, h = 0;
|
||||
if (std::sscanf(name.c_str(), "rt:%u:%ux%u", &id, &w, &h) != 3 || !w || !h || w > 4096 || h > 4096)
|
||||
int end = 0;
|
||||
if (std::sscanf(name.c_str(), "rt:%u:%ux%u%n", &id, &w, &h, &end) != 3 || !w || !h || w > 4096 || h > 4096)
|
||||
return nullptr;
|
||||
const bool color = name.compare(std::size_t(end), std::string::npos, ":c") == 0;
|
||||
if (!color && name[std::size_t(end)] != '\0') return nullptr;
|
||||
RenderTarget& target = render_targets_[name];
|
||||
target.width = w;
|
||||
target.height = h;
|
||||
target.color = color;
|
||||
target.last_used_frame = frame_number_;
|
||||
auto make_image = [&](VkFormat format, VkImageUsageFlags usage, VkImageAspectFlags aspect,
|
||||
VkImage& image, VkDeviceMemory& memory, VkImageView& view) {
|
||||
VkImage& image, VkDeviceMemory& memory, VkImageView& view, bool opaque = false) {
|
||||
VkImageCreateInfo info{VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};
|
||||
info.imageType = VK_IMAGE_TYPE_2D;
|
||||
info.format = format;
|
||||
@@ -299,18 +307,20 @@ VulkanWindow::RenderTarget* VulkanWindow::get_render_target(const std::string& n
|
||||
VkImageViewCreateInfo view_info{VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};
|
||||
view_info.image = image; view_info.viewType = VK_IMAGE_VIEW_TYPE_2D; view_info.format = format;
|
||||
view_info.subresourceRange = {aspect, 0, 1, 0, 1};
|
||||
// A colour target is D3DFMT_X8R8G8B8: sampled alpha is always 1.
|
||||
if (opaque) view_info.components.a = VK_COMPONENT_SWIZZLE_ONE;
|
||||
check(vkCreateImageView(device_, &view_info, nullptr, &view), "vkCreateImageView render target");
|
||||
};
|
||||
make_image(offscreen_format_,
|
||||
make_image(color ? VK_FORMAT_R8G8B8A8_UNORM : offscreen_format_,
|
||||
VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
|
||||
VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, target.texture.image, target.texture.memory, target.texture.view);
|
||||
VK_IMAGE_ASPECT_COLOR_BIT, target.texture.image, target.texture.memory, target.texture.view, color);
|
||||
make_image(VK_FORMAT_D32_SFLOAT,
|
||||
VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VK_IMAGE_ASPECT_DEPTH_BIT, target.depth_image, target.depth_memory, target.depth_view);
|
||||
const VkImageView views[2] = {target.texture.view, target.depth_view};
|
||||
VkFramebufferCreateInfo fb{VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO};
|
||||
fb.renderPass = offscreen_pass_;
|
||||
fb.renderPass = color ? offscreen_color_pass_ : offscreen_pass_;
|
||||
fb.attachmentCount = 2; fb.pAttachments = views;
|
||||
fb.width = w; fb.height = h; fb.layers = 1;
|
||||
check(vkCreateFramebuffer(device_, &fb, nullptr, &target.framebuffer), "vkCreateFramebuffer render target");
|
||||
@@ -343,7 +353,8 @@ void VulkanWindow::initialize_render_target(RenderTarget& target) {
|
||||
barriers[1].subresourceRange = {VK_IMAGE_ASPECT_DEPTH_BIT, 0, 1, 0, 1};
|
||||
vkCmdPipelineBarrier(f_->command, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, nullptr, 0, nullptr, 2, barriers);
|
||||
const VkClearColorValue white{{1.0f, 1.0f, 1.0f, 1.0f}};
|
||||
const float shade = target.color ? 0.0f : 1.0f;
|
||||
const VkClearColorValue white{{shade, shade, shade, 1.0f}};
|
||||
const VkClearDepthStencilValue far{1.0f, 0};
|
||||
vkCmdClearColorImage(f_->command, target.texture.image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &white, 1,
|
||||
&barriers[0].subresourceRange);
|
||||
|
||||
Reference in New Issue
Block a user