QtBase  v6.3.1
tex3d.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2021 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the examples of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** BSD License Usage
18 ** Alternatively, you may use this file under the terms of the BSD license
19 ** as follows:
20 **
21 ** "Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions are
23 ** met:
24 ** * Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** * Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in
28 ** the documentation and/or other materials provided with the
29 ** distribution.
30 ** * Neither the name of The Qt Company Ltd nor the names of its
31 ** contributors may be used to endorse or promote products derived
32 ** from this software without specific prior written permission.
33 **
34 **
35 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
46 **
47 ** $QT_END_LICENSE$
48 **
49 ****************************************************************************/
50 
51 #include "../shared/examplefw.h"
52 #include <QImage>
53 #include <QPainter>
54 
55 // Create a 3D texture of 256x256x3, where we will render to one of the slices
56 // in a render pass, while providing data to two other slices in texture
57 // uploads. Finally we use the texture to in the on-screen rendering: texture 3
58 // quads with the same volume texture, in each draw the shader will sample with
59 // a w that selects slice 0, 1, or 2, respectively.
60 
61 const int TEXTURE_DEPTH = 3;
62 
63 // Tests mipmap generation and linear-mipmap filtering when true. Note: Be
64 // aware what a mipmap chain for a 3D texture is and isn't, do not confuse with
65 // 2D (array) textures. The expected result on-screen is the black-red (slice
66 // 1) content mixed in to slice 0 and 2 on lower mip levels (resize the window
67 // to a smaller size -> the effect becomes more apparent, with totally taking
68 // over at small sizes)
69 // See https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-resources-textures-intro
70 //
71 const bool MIPMAP = true;
72 
73 static float quadVertexData[] =
74 { // Y up, CCW
75  -0.5f, 0.5f, 0.0f, 0.0f,
76  -0.5f, -0.5f, 0.0f, 1.0f,
77  0.5f, -0.5f, 1.0f, 1.0f,
78  0.5f, 0.5f, 1.0f, 0.0f
79 };
80 
81 static quint16 quadIndexData[] =
82 {
83  0, 1, 2, 0, 2, 3
84 };
85 
86 struct {
89  QRhiTexture *tex = nullptr;
92  QRhiBuffer *vbuf = nullptr;
93  QRhiBuffer *ibuf = nullptr;
94  QRhiBuffer *ubuf = nullptr;
95  QRhiSampler *sampler = nullptr;
100 } d;
101 
102 void Window::customInit()
103 {
105  qWarning("3D textures are not supported");
106 
108  if (MIPMAP)
111  256, 256, TEXTURE_DEPTH,
112  1, texFlags);
113  d.releasePool << d.tex;
114  d.tex->create();
115 
116  d.initialUpdates = m_r->nextResourceUpdateBatch();
117 
118  QImage imgWhiteText(256, 256, QImage::Format_RGBA8888);
119  imgWhiteText.fill(Qt::blue);
120  QPainter p(&imgWhiteText);
121  p.setPen(Qt::white);
122  p.drawText(10, 10, "Slice 2:\nWhite text on blue background");
123  p.end();
124 
125  // imgWhiteText -> slice 2 of the 3D texture
126  QRhiTextureUploadEntry uploadSlice2(2, 0, QRhiTextureSubresourceUploadDescription(imgWhiteText));
127  d.initialUpdates->uploadTexture(d.tex, uploadSlice2);
128 
129  QImage imgYellowText(256, 256, QImage::Format_RGBA8888);
130  imgYellowText.fill(Qt::green);
131  p.begin(&imgYellowText);
132  p.setPen(Qt::yellow);
133  p.drawText(10, 10, "Slice 0: Yellow text on green background");
134  p.end();
135 
136  // imgYellowText -> slice 0 of the 3D texture
137  QRhiTextureUploadEntry uploadSlice0(0, 0, QRhiTextureSubresourceUploadDescription(imgYellowText));
138  d.initialUpdates->uploadTexture(d.tex, uploadSlice0);
139 
140  // slice 1 -> clear to some color in a render pass
141  QRhiColorAttachment att(d.tex);
142  att.setLayer(1);
144  d.rt = m_r->newTextureRenderTarget(rtDesc);
145  d.releasePool << d.rt;
146  d.rtRp = d.rt->newCompatibleRenderPassDescriptor();
147  d.releasePool << d.rtRp;
148  d.rt->setRenderPassDescriptor(d.rtRp);
149  d.rt->create();
150 
151  // set up resources needed to render a quad
152  d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(quadVertexData));
153  d.vbuf->create();
154  d.releasePool << d.vbuf;
155 
156  d.ibuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::IndexBuffer, sizeof(quadIndexData));
157  d.ibuf->create();
158  d.releasePool << d.ibuf;
159 
160  d.initialUpdates->uploadStaticBuffer(d.vbuf, 0, sizeof(quadVertexData), quadVertexData);
161  d.initialUpdates->uploadStaticBuffer(d.ibuf, quadIndexData);
162 
164  d.ubuf->create();
165  d.releasePool << d.ubuf;
166 
167  for (int i = 0; i < TEXTURE_DEPTH; ++i) {
168  qint32 flip = 0;
169  if (i == 1) // this slice will be rendered to in a render pass so needs flipping with OpenGL when on screen
170  flip = m_r->isYUpInFramebuffer() ? 1 : 0;
171  d.initialUpdates->updateDynamicBuffer(d.ubuf, m_r->ubufAligned(72) * i + 64, 4, &flip);
172  qint32 idx = i;
173  d.initialUpdates->updateDynamicBuffer(d.ubuf, m_r->ubufAligned(72) * i + 68, 4, &idx);
174  }
175 
178  d.releasePool << d.sampler;
179  d.sampler->create();
180 
182  d.releasePool << d.srb;
183  d.srb->setBindings({
186  });
187  d.srb->create();
188 
189  d.ps = m_r->newGraphicsPipeline();
190  d.releasePool << d.ps;
191  d.ps->setShaderStages({
192  { QRhiShaderStage::Vertex, getShader(QLatin1String(":/texture3d.vert.qsb")) },
193  { QRhiShaderStage::Fragment, getShader(QLatin1String(":/texture3d.frag.qsb")) }
194  });
195  QRhiVertexInputLayout inputLayout;
196  inputLayout.setBindings({
197  { 4 * sizeof(float) }
198  });
199  inputLayout.setAttributes({
201  { 0, 1, QRhiVertexInputAttribute::Float2, quint32(2 * sizeof(float)) }
202  });
203  d.ps->setVertexInputLayout(inputLayout);
204  d.ps->setShaderResourceBindings(d.srb);
205  d.ps->setRenderPassDescriptor(m_rp);
206  d.ps->create();
207 }
208 
210 {
211  qDeleteAll(d.releasePool);
212  d.releasePool.clear();
213 }
214 
216 {
217  QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
219  if (d.initialUpdates) {
220  u->merge(d.initialUpdates);
221  d.initialUpdates->release();
222  d.initialUpdates = nullptr;
223  }
224 
225  if (d.winProj != m_proj) {
226  d.winProj = m_proj;
227  for (int i = 0; i < TEXTURE_DEPTH; ++i) {
228  QMatrix4x4 mvp = m_proj;
229  switch (i) {
230  case 0:
231  mvp.translate(-2.0f, 0.0f, 0.0f);
232  break;
233  case 2:
234  mvp.translate(2.0f, 0.0f, 0.0f);
235  break;
236  default:
237  break;
238  }
239  u->updateDynamicBuffer(d.ubuf, m_r->ubufAligned(72) * i, 64, mvp.constData());
240  }
241  }
242 
243  const QColor slice1ClearColor = QColor::fromRgbF(d.slice1ClearColor.x(), d.slice1ClearColor.y(), d.slice1ClearColor.z());
244  d.slice1ClearColor.setX(d.slice1ClearColor.x() + 0.01f);
245  if (d.slice1ClearColor.x() > 1.0f)
246  d.slice1ClearColor.setX(0.0f);
247  cb->beginPass(d.rt, slice1ClearColor, { 1.0f, 0 }, u);
248  cb->endPass();
249 
250  // now all 3 slices have something, regenerate the mipmaps
252  if (MIPMAP)
253  u->generateMips(d.tex);
254 
255  const QSize outputSizeInPixels = m_sc->currentPixelSize();
256  cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
257  cb->setGraphicsPipeline(d.ps);
258  QRhiCommandBuffer::DynamicOffset dynOfs = { 0, 0 };
259  cb->setShaderResources(d.srb, 1, &dynOfs);
260  cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
261  QRhiCommandBuffer::VertexInput vbufBinding(d.vbuf, 0);
262  cb->setVertexInput(0, 1, &vbufBinding, d.ibuf, 0, QRhiCommandBuffer::IndexUInt16);
263  cb->drawIndexed(6);
264 
265  dynOfs.second = m_r->ubufAligned(72);
266  cb->setShaderResources(d.srb, 1, &dynOfs);
267  cb->drawIndexed(6);
268 
269  dynOfs.second = m_r->ubufAligned(72) * 2;
270  cb->setShaderResources(d.srb, 1, &dynOfs);
271  cb->drawIndexed(6);
272 
273  cb->endPass();
274 }
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
FT_UInt idx
Definition: cffcmap.c:135
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
static QColor fromRgbF(float r, float g, float b, float a=1.0)
Definition: qcolor.cpp:2424
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:73
@ Format_RGBA8888
Definition: qimage.h:95
void fill(uint pixel)
Definition: qimage.cpp:1736
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal.
Definition: qstring.h:84
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
Definition: qmatrix4x4.h:61
const float * constData() const
Definition: qmatrix4x4.h:183
void translate(const QVector3D &vector)
Definition: qmatrix4x4.cpp:965
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:82
@ Immutable
Definition: qrhi_p.h:717
@ Dynamic
Definition: qrhi_p.h:719
@ IndexBuffer
Definition: qrhi_p.h:724
@ VertexBuffer
Definition: qrhi_p.h:723
@ UniformBuffer
Definition: qrhi_p.h:725
void setLayer(int layer)
Definition: qrhi_p.h:470
QPair< QRhiBuffer *, quint32 > VertexInput
Definition: qrhi_p.h:1426
QPair< int, quint32 > DynamicOffset
Definition: qrhi_p.h:1422
int ubufAligned(int v) const
Definition: qrhi.cpp:6207
bool isYUpInFramebuffer() const
Definition: qrhi.cpp:6238
bool isFeatureSupported(QRhi::Feature feature) const
Definition: qrhi.cpp:6318
QRhiShaderResourceBindings * newShaderResourceBindings()
Definition: qrhi.cpp:6543
QRhiBuffer * newBuffer(QRhiBuffer::Type type, QRhiBuffer::UsageFlags usage, int size)
Definition: qrhi.cpp:6562
QRhiSampler * newSampler(QRhiSampler::Filter magFilter, QRhiSampler::Filter minFilter, QRhiSampler::Filter mipmapMode, QRhiSampler::AddressMode addressU, QRhiSampler::AddressMode addressV, QRhiSampler::AddressMode addressW=QRhiSampler::Repeat)
Definition: qrhi.cpp:6679
QRhiTextureRenderTarget * newTextureRenderTarget(const QRhiTextureRenderTargetDescription &desc, QRhiTextureRenderTarget::Flags flags={})
Definition: qrhi.cpp:6696
QRhiGraphicsPipeline * newGraphicsPipeline()
Definition: qrhi.cpp:6520
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
Definition: qrhi.cpp:6609
@ ThreeDimensionalTextures
Definition: qrhi_p.h:1590
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
Definition: qrhi.cpp:5568
@ ClampToEdge
Definition: qrhi_p.h:884
static QRhiShaderResourceBinding uniformBufferWithDynamicOffset(int binding, StageFlags stage, QRhiBuffer *buf, int size)
Definition: qrhi.cpp:3342
static QRhiShaderResourceBinding sampledTexture(int binding, StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
Definition: qrhi.cpp:3374
@ UsedWithGenerateMips
Definition: qrhi_p.h:771
@ MipMapped
Definition: qrhi_p.h:768
@ RenderTarget
Definition: qrhi_p.h:766
Definition: qrhi_p.h:565
void setBindings(std::initializer_list< QRhiVertexInputBinding > list)
Definition: qrhi_p.h:257
void setAttributes(std::initializer_list< QRhiVertexInputAttribute > list)
Definition: qrhi_p.h:268
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:55
constexpr int height() const noexcept
Definition: qsize.h:160
constexpr int width() const noexcept
Definition: qsize.h:157
The QVector3D class represents a vector or vertex in 3D space.
Definition: qvectornd.h:205
std::unique_ptr< QRhiSwapChain > m_sc
Definition: window.h:89
std::unique_ptr< QRhiRenderPassDescriptor > m_rp
Definition: window.h:91
virtual void customRender()
QColor m_clearColor
Definition: examplefw.h:176
QMatrix4x4 m_proj
Definition: window.h:94
virtual void customInit()
QRhi * m_r
Definition: examplefw.h:161
qDeleteAll(list.begin(), list.end())
QShader getShader(const QString &name)
Definition: examplefw.h:86
@ white
Definition: qnamespace.h:62
@ blue
Definition: qnamespace.h:68
@ yellow
Definition: qnamespace.h:71
@ green
Definition: qnamespace.h:67
Flags
unsigned int quint32
Definition: qglobal.h:288
unsigned short quint16
Definition: qglobal.h:286
int qint32
Definition: qglobal.h:287
#define qWarning
Definition: qlogging.h:179
GLuint sampler
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
QRhiBuffer * ibuf
Definition: tex3d.cpp:93
QRhiBuffer * ubuf
Definition: tex3d.cpp:94
QList< QRhiResource * > releasePool
Definition: tex3d.cpp:87
QRhiTextureRenderTarget * rt
Definition: tex3d.cpp:90
const int TEXTURE_DEPTH
Definition: tex3d.cpp:61
QRhiRenderPassDescriptor * rtRp
Definition: tex3d.cpp:91
QRhiTexture * tex
Definition: tex3d.cpp:89
struct @924 d
QVector3D slice1ClearColor
Definition: tex3d.cpp:99
QRhiShaderResourceBindings * srb
Definition: tex3d.cpp:97
QRhiBuffer * vbuf
Definition: tex3d.cpp:92
QMatrix4x4 winProj
Definition: tex3d.cpp:98
const bool MIPMAP
Definition: tex3d.cpp:71
QRhiGraphicsPipeline * ps
Definition: tex3d.cpp:96
QRhiResourceUpdateBatch * initialUpdates
Definition: tex3d.cpp:88