Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickrhiitem_intro.cpp
Go to the documentation of this file.
1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
4#include <QtQuick/QQuickRhiItem>
5#include <rhi/qrhi.h>
6
7//![0]
8class ExampleRhiItemRenderer : public QQuickRhiItemRenderer
9{
10public:
11 void initialize(QRhiCommandBuffer *cb) override;
12 void synchronize(QQuickRhiItem *item) override;
13 void render(QRhiCommandBuffer *cb) override;
14
15private:
16 QRhi *m_rhi = nullptr;
17 std::unique_ptr<QRhiBuffer> m_vbuf;
18 std::unique_ptr<QRhiBuffer> m_ubuf;
19 std::unique_ptr<QRhiShaderResourceBindings> m_srb;
20 std::unique_ptr<QRhiGraphicsPipeline> m_pipeline;
21 QMatrix4x4 m_viewProjection;
22 float m_angle = 0.0f;
23};
24
26{
27 Q_OBJECT
28 QML_NAMED_ELEMENT(ExampleRhiItem)
30
31public:
33
34 float angle() const { return m_angle; }
35 void setAngle(float a);
36
39
40private:
41 float m_angle = 0.0f;
42};
43
44QQuickRhiItemRenderer *ExampleRhiItem::createRenderer()
45{
46 return new ExampleRhiItemRenderer;
47}
48
50{
51 if (m_angle == a)
52 return;
53
54 m_angle = a;
55 emit angleChanged();
56 update();
57}
58
59void ExampleRhiItemRenderer::synchronize(QQuickRhiItem *rhiItem)
60{
61 ExampleRhiItem *item = static_cast<ExampleRhiItem *>(rhiItem);
62 if (item->angle() != m_angle)
63 m_angle = item->angle();
64}
65
66static QShader getShader(const QString &name)
67{
68 QFile f(name);
69 return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
70}
71
72static float vertexData[] = {
73 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
74 -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
75 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
76};
77
78void ExampleRhiItemRenderer::initialize(QRhiCommandBuffer *cb)
79{
80 if (m_rhi != rhi()) {
81 m_pipeline.reset();
82 m_rhi = rhi();
83 }
84
85 if (!m_pipeline) {
86 m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
87 m_vbuf->create();
88
89 m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64));
90 m_ubuf->create();
91
92 m_srb.reset(m_rhi->newShaderResourceBindings());
93 m_srb->setBindings({
94 QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()),
95 });
96 m_srb->create();
97
98 m_pipeline.reset(m_rhi->newGraphicsPipeline());
99 m_pipeline->setShaderStages({
100 { QRhiShaderStage::Vertex, getShader(QLatin1String(":/shaders/color.vert.qsb")) },
101 { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shaders/color.frag.qsb")) }
102 });
103 QRhiVertexInputLayout inputLayout;
104 inputLayout.setBindings({
105 { 5 * sizeof(float) }
106 });
107 inputLayout.setAttributes({
108 { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
109 { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
110 });
111 m_pipeline->setVertexInputLayout(inputLayout);
112 m_pipeline->setShaderResourceBindings(m_srb.get());
113 m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor());
114 m_pipeline->create();
115
116 QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
117 resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
118 cb->resourceUpdate(resourceUpdates);
119 }
120
121 const QSize outputSize = renderTarget()->pixelSize();
122 m_viewProjection = m_rhi->clipSpaceCorrMatrix();
123 m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f);
124 m_viewProjection.translate(0, 0, -4);
125}
126
127void ExampleRhiItemRenderer::render(QRhiCommandBuffer *cb)
128{
129 QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
130 QMatrix4x4 modelViewProjection = m_viewProjection;
131 modelViewProjection.rotate(m_angle, 0, 1, 0);
132 resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData());
133
134 const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
135 cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates);
136
137 cb->setGraphicsPipeline(m_pipeline.get());
138 const QSize outputSize = renderTarget()->pixelSize();
139 cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
140 cb->setShaderResources();
141 const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
142 cb->setVertexInput(0, 1, &vbufBinding);
143 cb->draw(3);
144
145 cb->endPass();
146}
147//![0]
\inmodule QtGuiPrivate \inheaderfile rhi/qrhi.h
Definition qrhi.h:322
static float vertexData[]
static QShader getShader(const QString &name)