载入中...
搜索中...
未找到
Canvas.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4#include "image/ImageData.h"
5#include "zeroerr/assert.h"
6
7#include <array>
8#include <cstring>
9
10namespace eve::graphics::vulkan {
11
13 : owner(owner), width(width), height(height) {
14 ASSERT(owner != nullptr);
15 ASSERT_GT(width, 0);
16 ASSERT_GT(height, 0);
17 if (!owner) throw Exception("OffscreenCanvas: null owner");
18 if (width <= 0 || height <= 0) throw Exception("OffscreenCanvas: invalid size");
19
20 auto &device = owner->getDevice();
21 color = device.createColorTarget(uint32_t(width), uint32_t(height));
22
23 fb = owner->getOffscreenRenderPass().createFramebuffer(
24 device, uint32_t(width), uint32_t(height), {color.asAttachment()});
25
26 vkb::SamplerBuilder sb;
27 sampleGpu.sampler = sb.magFilter(vk::Filter::eNearest)
28 .minFilter(vk::Filter::eNearest)
29 .addressModeU(vk::SamplerAddressMode::eClampToEdge)
30 .addressModeV(vk::SamplerAddressMode::eClampToEdge)
31 .build(device);
32
33 auto sets = vkb::DescriptorSetBuilder()
34 .layout(owner->getTexSetLayout())
35 .build(device.instance, owner->getDescriptorPool());
36 sampleGpu.width = width;
37 sampleGpu.height = height;
38 sampleGpu.viewOverride = color.imageView();
39
40 vkb::UnboundSet unbound{sets[0]};
41 vkb::DescriptorSetUpdater updater;
42 updater.beginDescriptorSet(unbound)
43 .beginImages(0, 0, vk::DescriptorType::eCombinedImageSampler)
44 .image(vkb::SampledImage::forLaterSample(sampleGpu.sampler, color.imageView()))
45 .beginImages(1, 0, vk::DescriptorType::eCombinedImageSampler)
46 .image(vkb::SampledImage::forLaterSample(sampleGpu.sampler, color.imageView()))
47 .update(device.instance);
48 sampleGpu.descriptorSet = std::move(unbound).publish();
49
50 sampleTexture.width = width;
51 sampleTexture.height = height;
52 sampleTexture.pixelWidth = width;
53 sampleTexture.pixelHeight = height;
54 sampleTexture.gpuHandle = &sampleGpu;
55}
56
58 if (!owner) return;
59 auto &device = owner->getDevice();
60 device->waitIdle();
61 if (fb) {
62 device->destroyFramebuffer(fb);
63 fb = nullptr;
64 }
65 if (fb3D) {
66 device->destroyFramebuffer(fb3D);
67 fb3D = nullptr;
68 }
69 if (sampleGpu.sampler) {
70 device->destroySampler(sampleGpu.sampler);
71 sampleGpu.sampler = nullptr;
72 }
73 sampleTexture.gpuHandle = nullptr;
74}
75
77 bool v = hasPendingClear;
78 hasPendingClear = false;
79 return v;
80}
81
83 if (fb3D) return;
84 auto &device = owner->getDevice();
85 depth = device.createDepthTarget(uint32_t(width), uint32_t(height), owner->getDepthFormat(),
86 true);
87 fb3D = owner->getOffscreen3DRenderPass().createFramebuffer(
88 device, uint32_t(width), uint32_t(height), {color.asAttachment(), depth.asAttachment()});
89}
90
91void OffscreenCanvas::clear(std::optional<Color> colorOpt, std::optional<int>, std::optional<double>) {
92 clearColor = colorOpt.value_or(Color(0.f, 0.f, 0.f, 1.f));
93 hasPendingClear = true;
94}
95
96void OffscreenCanvas::readAllPixels(std::vector<uint8_t> &outRgba) {
97 auto &device = owner->getDevice();
98 device->waitIdle();
99
100 const vk::DeviceSize byteSize = vk::DeviceSize(width) * vk::DeviceSize(height) * 4;
101 vkb::GenericBuffer staging(device, vk::BufferUsageFlagBits::eTransferDst, byteSize,
102 vk::MemoryPropertyFlagBits::eHostVisible |
103 vk::MemoryPropertyFlagBits::eHostCoherent);
104
105 vkb::executeImmediately(device.instance, owner->getUploadPool(),
106 device.getQueue(vkb::QueueType::graphics), [&](vk::CommandBuffer cb) {
107 color.setLayout(cb, vk::ImageLayout::eTransferSrcOptimal);
108 vk::BufferImageCopy region{};
109 region.imageSubresource = {vk::ImageAspectFlagBits::eColor, 0, 0, 1};
110 region.imageExtent = vk::Extent3D{uint32_t(width), uint32_t(height), 1};
111 cb.copyImageToBuffer(color.image(), vk::ImageLayout::eTransferSrcOptimal,
112 staging.buffer, region);
113 color.setLayout(cb, vk::ImageLayout::eShaderReadOnlyOptimal);
114 });
115
116 outRgba.resize(size_t(byteSize));
117 void *mapped = device->mapMemory(staging.memory, 0, byteSize);
118 // Vulkan FB row 0 is NDC -Y (top). Batcher maps logical y=0 → NDC -1, so
119 // logical top-left matches FB top-left — copy as-is into Y-down buffer.
120 std::memcpy(outRgba.data(), mapped, size_t(byteSize));
121 device->unmapMemory(staging.memory);
122 staging.release();
123}
124
125Color OffscreenCanvas::getPixel(int x, int y) {
126 ASSERT_GE(x, 0);
127 ASSERT_GE(y, 0);
128 ASSERT_LT(x, width);
129 ASSERT_LT(y, height);
130 if (x < 0 || y < 0 || x >= width || y >= height)
131 throw Exception("OffscreenCanvas::getPixel: out of bounds (%d,%d)", x, y);
132 std::vector<uint8_t> px;
133 readAllPixels(px);
134 size_t i = (size_t(y) * size_t(width) + size_t(x)) * 4;
135 return Color(px[i + 0] / 255.f, px[i + 1] / 255.f, px[i + 2] / 255.f, px[i + 3] / 255.f);
136}
137
138image::ImageData *OffscreenCanvas::newImageData() {
139 std::vector<uint8_t> px;
140 readAllPixels(px);
141 auto *img = new image::ImageData(width, height, "RGBA8");
142 std::memcpy(img->getData(), px.data(), px.size());
143 return img;
144}
145
146} // namespace eve::graphics::vulkan
vkb::Device & device
int y
Definition Grass.cpp:135
float height
Definition Grass.cpp:235
int x
Definition Grass.cpp:135
std::vector< Colorf > px
int width
int v
const vkb::BuiltRenderPass & getOffscreen3DRenderPass()
Definition Graphics.h:325
vk::CommandPool getUploadPool() const
Definition Graphics.h:321
const vkb::BuiltRenderPass & getOffscreenRenderPass() const
Definition Graphics.h:324
vk::DescriptorSetLayout getTexSetLayout() const
Definition Graphics.h:322
vk::Format getDepthFormat() const
Definition Graphics.h:326
vk::DescriptorPool getDescriptorPool() const
Definition Graphics.h:323
OffscreenCanvas(Graphics *owner, int width, int height)
Definition Canvas.cpp:12
void clear(std::optional< Color > color, std::optional< int > stencil, std::optional< double > depth) override
Definition Canvas.cpp:91
void ensure3D()
Ensure a D32 depth attachment + 3D (color+depth) framebuffer exist.
Definition Canvas.cpp:82
Represents raw pixel data.
Definition ImageData.h:26
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
Definition Color.h:13