Revision control

++ // Copyright (C) 2023 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
++
++ #include "examplewidget.h"
++ #include <QFile>
++
++ static float vertexData[] = {
++ 0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
++ -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
++ 0.5f, -0.5f, 0.0f, 0.0f, 1.0f,
++ };
++
++ //![get-shader]
++ static QShader getShader(const QString &name)
++ {
++ QFile f(name);
++ return f.open(QIODevice::ReadOnly) ? QShader::fromSerialized(f.readAll()) : QShader();
++ }
++ //![get-shader]
++
++ //![init-1]
++ void ExampleRhiWidget::initialize(QRhiCommandBuffer *cb)
++ {
++ if (m_rhi != rhi()) {
++ m_pipeline.reset();
++ m_rhi = rhi();
++ }
++ //![init-1]
++ //![init-pipeline]
++ if (!m_pipeline) {
++ m_vbuf.reset(m_rhi->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(vertexData)));
++ m_vbuf->create();
++
++ m_ubuf.reset(m_rhi->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64));
++ m_ubuf->create();
++
++ m_srb.reset(m_rhi->newShaderResourceBindings());
++ m_srb->setBindings({
++ QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage, m_ubuf.get()),
++ });
++ m_srb->create();
++
++ m_pipeline.reset(m_rhi->newGraphicsPipeline());
++ m_pipeline->setShaderStages({
++ { QRhiShaderStage::Vertex, getShader(QLatin1String(":/shader_assets/color.vert.qsb")) },
++ { QRhiShaderStage::Fragment, getShader(QLatin1String(":/shader_assets/color.frag.qsb")) }
++ });
++ QRhiVertexInputLayout inputLayout;
++ inputLayout.setBindings({
++ { 5 * sizeof(float) }
++ });
++ inputLayout.setAttributes({
++ { 0, 0, QRhiVertexInputAttribute::Float2, 0 },
++ { 0, 1, QRhiVertexInputAttribute::Float3, 2 * sizeof(float) }
++ });
++ m_pipeline->setVertexInputLayout(inputLayout);
++ m_pipeline->setShaderResourceBindings(m_srb.get());
++ m_pipeline->setRenderPassDescriptor(renderTarget()->renderPassDescriptor());
++ m_pipeline->create();
++
++ QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
++ resourceUpdates->uploadStaticBuffer(m_vbuf.get(), vertexData);
++ cb->resourceUpdate(resourceUpdates);
++ }
++ //![init-pipeline]
++
++ //![init-matrix]
++ const QSize outputSize = renderTarget()->pixelSize();
++ m_viewProjection = m_rhi->clipSpaceCorrMatrix();
++ m_viewProjection.perspective(45.0f, outputSize.width() / (float) outputSize.height(), 0.01f, 1000.0f);
++ m_viewProjection.translate(0, 0, -4);
++ }
++ //![init-matrix]
++
++ //![render-1]
++ void ExampleRhiWidget::render(QRhiCommandBuffer *cb)
++ {
++ QRhiResourceUpdateBatch *resourceUpdates = m_rhi->nextResourceUpdateBatch();
++ m_rotation += 1.0f;
++ QMatrix4x4 modelViewProjection = m_viewProjection;
++ modelViewProjection.rotate(m_rotation, 0, 1, 0);
++ resourceUpdates->updateDynamicBuffer(m_ubuf.get(), 0, 64, modelViewProjection.constData());
++ //![render-1]
++ //![render-pass]
++ const QColor clearColor = QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
++ cb->beginPass(renderTarget(), clearColor, { 1.0f, 0 }, resourceUpdates);
++
++ cb->setGraphicsPipeline(m_pipeline.get());
++ const QSize outputSize = renderTarget()->pixelSize();
++ cb->setViewport(QRhiViewport(0, 0, outputSize.width(), outputSize.height()));
++ cb->setShaderResources();
++ const QRhiCommandBuffer::VertexInput vbufBinding(m_vbuf.get(), 0);
++ cb->setVertexInput(0, 1, &vbufBinding);
++ cb->draw(3);
++
++ cb->endPass();
++ //![render-pass]
++
++ //![render-2]
++ update();
++ }
++ //![render-2]