5#include "zeroerr/assert.h"
14 ASSERT(owner !=
nullptr);
17 if (!owner)
throw Exception(
"OffscreenCanvas: null owner");
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)
33 auto sets = vkb::DescriptorSetBuilder()
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()))
62 device->destroyFramebuffer(fb);
66 device->destroyFramebuffer(fb3D);
77 bool v = hasPendingClear;
78 hasPendingClear =
false;
88 device, uint32_t(width), uint32_t(height), {color.asAttachment(), depth.asAttachment()});
92 clearColor = colorOpt.value_or(
Color(0.f, 0.f, 0.f, 1.f));
93 hasPendingClear =
true;
96void OffscreenCanvas::readAllPixels(std::vector<uint8_t> &outRgba) {
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);
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);
116 outRgba.resize(
size_t(byteSize));
117 void *mapped =
device->mapMemory(staging.memory, 0, byteSize);
120 std::memcpy(outRgba.data(), mapped,
size_t(byteSize));
121 device->unmapMemory(staging.memory);
125Color OffscreenCanvas::getPixel(
int x,
int y) {
131 throw Exception(
"OffscreenCanvas::getPixel: out of bounds (%d,%d)",
x,
y);
132 std::vector<uint8_t>
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);
139 std::vector<uint8_t>
px;
142 std::memcpy(img->getData(),
px.data(),
px.size());
const vkb::BuiltRenderPass & getOffscreen3DRenderPass()
vk::CommandPool getUploadPool() const
const vkb::BuiltRenderPass & getOffscreenRenderPass() const
vk::DescriptorSetLayout getTexSetLayout() const
vkb::Device & getDevice()
vk::Format getDepthFormat() const
vk::DescriptorPool getDescriptorPool() const
OffscreenCanvas(Graphics *owner, int width, int height)
~OffscreenCanvas() override
void clear(std::optional< Color > color, std::optional< int > stencil, std::optional< double > depth) override
void ensure3D()
Ensure a D32 depth attachment + 3D (color+depth) framebuffer exist.
Represents raw pixel data.
glm::vec4 Color
RGBA color used by every graphics draw call. Lives inside eve::graphics so including a graphics heade...
vk::ImageView viewOverride
vkb::BoundSet descriptorSet