10int main(
int argc,
char **argv)
12 QGuiApplication app(argc, argv);
17 std::unique_ptr<QRhi> rhi;
19 QRhiD3D12InitParams params;
20 rhi.reset(QRhi::create(QRhi::D3D12, ¶ms));
22 QRhiMetalInitParams params;
23 rhi.reset(QRhi::create(QRhi::Metal, ¶ms));
24#elif QT_CONFIG(vulkan)
25 inst.setExtensions(QRhiVulkanInitParams::preferredInstanceExtensions());
27 QRhiVulkanInitParams params;
29 rhi.reset(QRhi::create(QRhi::Vulkan, ¶ms));
31 qFatal(
"Failed to create Vulkan instance");
35 qDebug() << rhi->backendName() << rhi->driverInfo();
37 qFatal(
"Failed to initialize RHI");
39 float rotation = 0.0f;
43 std::unique_ptr<QRhiTexture> tex(rhi->newTexture(QRhiTexture::RGBA8,
46 QRhiTexture::RenderTarget | QRhiTexture::UsedAsTransferSource));
48 std::unique_ptr<QRhiTextureRenderTarget> rt(rhi->newTextureRenderTarget({ tex.get() }));
49 std::unique_ptr<QRhiRenderPassDescriptor> rp(rt->newCompatibleRenderPassDescriptor());
50 rt->setRenderPassDescriptor(rp.get());
53 QMatrix4x4 viewProjection = rhi->clipSpaceCorrMatrix();
54 viewProjection.perspective(45.0f, 1280 / 720.f, 0.01f, 1000.0f);
55 viewProjection.translate(0, 0, -4);
57 static float vertexData[] = {
58 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
59 -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
60 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
63 std::unique_ptr<QRhiBuffer> vbuf(rhi->newBuffer(QRhiBuffer::Immutable,
64 QRhiBuffer::VertexBuffer,
68 std::unique_ptr<QRhiBuffer> ubuf(rhi->newBuffer(QRhiBuffer::Dynamic,
69 QRhiBuffer::UniformBuffer,
73 std::unique_ptr<QRhiShaderResourceBindings> srb(rhi->newShaderResourceBindings());
75 QRhiShaderResourceBinding::uniformBuffer(0,
76 QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage,
81 std::unique_ptr<QRhiGraphicsPipeline> ps(rhi->newGraphicsPipeline());
82 QRhiGraphicsPipeline::TargetBlend premulAlphaBlend;
83 premulAlphaBlend.enable =
true;
84 ps->setTargetBlends({ premulAlphaBlend });
85 static auto getShader = [](
const QString &name) {
87 return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
90 { QRhiShaderStage::Vertex, getShader(QLatin1String(
"color.vert.qsb")) },
91 { QRhiShaderStage::Fragment, getShader(QLatin1String(
"color.frag.qsb")) }
94 inputLayout.setBindings({
97 inputLayout.setAttributes({
98 { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
99 { 0, 1, QRhiVertexInputAttribute::Float3, 2 *
sizeof(
float) }
101 ps->setVertexInputLayout(inputLayout);
102 ps->setShaderResourceBindings(srb.get());
103 ps->setRenderPassDescriptor(rp.get());
106 QRhiCommandBuffer *cb;
107 for (
int frame = 0; frame < 20; ++frame) {
108 rhi->beginOffscreenFrame(&cb);
110 QRhiResourceUpdateBatch *u = rhi->nextResourceUpdateBatch();
112 u->uploadStaticBuffer(vbuf.get(), vertexData);
114 QMatrix4x4 mvp = viewProjection;
115 mvp.rotate(rotation, 0, 1, 0);
116 u->updateDynamicBuffer(ubuf.get(), 0, 64, mvp.constData());
119 u->updateDynamicBuffer(ubuf.get(), 64, 4, &opacity);
120 opacity += opacityDir * 0.2f;
121 if (opacity < 0.0f || opacity > 1.0f) {
123 opacity = qBound(0.0f, opacity, 1.0f);
126 cb->beginPass(rt.get(), Qt::green, { 1.0f, 0 }, u);
127 cb->setGraphicsPipeline(ps.get());
128 cb->setViewport({ 0, 0, 1280, 720 });
129 cb->setShaderResources();
130 const QRhiCommandBuffer::VertexInput vbufBinding(vbuf.get(), 0);
131 cb->setVertexInput(0, 1, &vbufBinding);
133 QRhiReadbackResult readbackResult;
134 u = rhi->nextResourceUpdateBatch();
135 u->readBackTexture({ tex.get() }, &readbackResult);
138 rhi->endOffscreenFrame();
140 QImage image(
reinterpret_cast<
const uchar *>(readbackResult.data.constData()),
141 readbackResult.pixelSize.width(),
142 readbackResult.pixelSize.height(),
143 QImage::Format_RGBA8888_Premultiplied);
144 if (rhi->isYUpInFramebuffer())
146 image.save(QString::asprintf(
"frame%d.png", frame));