fbb26c2b88
Having a simple Dear ImGui bridge is not just useful for the manual tests, which do not have any other means to displays GUIs, but is in itself an important exercise for the QRhi machinery. Have a new manual test that exercises the built-in ImGui demo window. Then use it in the displacement test for real, to replace the myriads of key presses with on-screen sliders and checkboxes (with less code). Change-Id: I296bafae2a5cce6fc7a447d97e68e5bcec15f451 Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
129 lines
4.2 KiB
C++
129 lines
4.2 KiB
C++
// Copyright (C) 2023 The Qt Company Ltd.
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
|
|
|
#define EXAMPLEFW_IMGUI
|
|
#include "../shared/examplefw.h"
|
|
|
|
#include "../shared/cube.h"
|
|
|
|
struct {
|
|
QMatrix4x4 winProj;
|
|
QList<QRhiResource *> releasePool;
|
|
QRhiResourceUpdateBatch *initialUpdates = nullptr;
|
|
QRhiBuffer *vbuf = nullptr;
|
|
QRhiBuffer *ubuf = nullptr;
|
|
QRhiTexture *tex = nullptr;
|
|
QRhiSampler *sampler = nullptr;
|
|
QRhiShaderResourceBindings *srb = nullptr;
|
|
QRhiGraphicsPipeline *ps = nullptr;
|
|
bool showDemoWindow = true;
|
|
float rotation = 0.0f;
|
|
} d;
|
|
|
|
void Window::customInit()
|
|
{
|
|
d.initialUpdates = m_r->nextResourceUpdateBatch();
|
|
|
|
d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(cube));
|
|
d.vbuf->create();
|
|
d.releasePool << d.vbuf;
|
|
|
|
d.initialUpdates->uploadStaticBuffer(d.vbuf, cube);
|
|
|
|
d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 68);
|
|
d.ubuf->create();
|
|
d.releasePool << d.ubuf;
|
|
float opacity = 1.0f;
|
|
d.initialUpdates->updateDynamicBuffer(d.ubuf, 64, 4, &opacity);
|
|
|
|
QImage image = QImage(QLatin1String(":/qt256.png")).convertToFormat(QImage::Format_RGBA8888).mirrored();
|
|
d.tex = m_r->newTexture(QRhiTexture::RGBA8, QSize(image.width(), image.height()), 1, {});
|
|
d.releasePool << d.tex;
|
|
d.tex->create();
|
|
d.initialUpdates->uploadTexture(d.tex, image);
|
|
|
|
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
|
|
QRhiSampler::ClampToEdge, QRhiSampler::ClampToEdge);
|
|
d.releasePool << d.sampler;
|
|
d.sampler->create();
|
|
|
|
d.srb = m_r->newShaderResourceBindings();
|
|
d.releasePool << d.srb;
|
|
d.srb->setBindings({
|
|
QRhiShaderResourceBinding::uniformBuffer(0, QRhiShaderResourceBinding::VertexStage | QRhiShaderResourceBinding::FragmentStage, d.ubuf),
|
|
QRhiShaderResourceBinding::sampledTexture(1, QRhiShaderResourceBinding::FragmentStage, d.tex, d.sampler)
|
|
});
|
|
d.srb->create();
|
|
|
|
d.ps = m_r->newGraphicsPipeline();
|
|
d.releasePool << d.ps;
|
|
d.ps->setCullMode(QRhiGraphicsPipeline::Back);
|
|
const QRhiShaderStage stages[] = {
|
|
{ QRhiShaderStage::Vertex, getShader(QLatin1String(":/texture.vert.qsb")) },
|
|
{ QRhiShaderStage::Fragment, getShader(QLatin1String(":/texture.frag.qsb")) }
|
|
};
|
|
d.ps->setShaderStages(stages, stages + 2);
|
|
QRhiVertexInputLayout inputLayout;
|
|
inputLayout.setBindings({
|
|
{ 3 * sizeof(float) },
|
|
{ 2 * sizeof(float) }
|
|
});
|
|
inputLayout.setAttributes({
|
|
{ 0, 0, QRhiVertexInputAttribute::Float3, 0 },
|
|
{ 1, 1, QRhiVertexInputAttribute::Float2, 0 }
|
|
});
|
|
d.ps->setVertexInputLayout(inputLayout);
|
|
d.ps->setShaderResourceBindings(d.srb);
|
|
d.ps->setRenderPassDescriptor(m_rp);
|
|
d.ps->create();
|
|
}
|
|
|
|
void Window::customRelease()
|
|
{
|
|
qDeleteAll(d.releasePool);
|
|
d.releasePool.clear();
|
|
}
|
|
|
|
void Window::customRender()
|
|
{
|
|
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
|
|
QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch();
|
|
if (d.initialUpdates) {
|
|
u->merge(d.initialUpdates);
|
|
d.initialUpdates->release();
|
|
d.initialUpdates = nullptr;
|
|
}
|
|
|
|
QMatrix4x4 mvp = m_proj;
|
|
mvp.rotate(d.rotation, 0, 1, 0);
|
|
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
|
|
|
|
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
|
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
|
|
|
cb->setGraphicsPipeline(d.ps);
|
|
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
|
|
cb->setShaderResources();
|
|
const QRhiCommandBuffer::VertexInput vbufBindings[] = {
|
|
{ d.vbuf, 0 },
|
|
{ d.vbuf, quint32(36 * 3 * sizeof(float)) }
|
|
};
|
|
cb->setVertexInput(0, 2, vbufBindings);
|
|
cb->draw(36);
|
|
|
|
m_imguiRenderer->render();
|
|
|
|
cb->endPass();
|
|
}
|
|
|
|
void Window::customGui()
|
|
{
|
|
ImGui::ShowDemoWindow(&d.showDemoWindow);
|
|
|
|
ImGui::SetNextWindowPos(ImVec2(50, 120), ImGuiCond_FirstUseEver);
|
|
ImGui::SetNextWindowSize(ImVec2(400, 100), ImGuiCond_FirstUseEver);
|
|
ImGui::Begin("Test");
|
|
ImGui::SliderFloat("Rotation", &d.rotation, 0.0f, 360.0f);
|
|
ImGui::End();
|
|
}
|