Merge "Merge remote-tracking branch 'origin/5.14' into 5.15"
This commit is contained in:
commit
fbda189e08
@ -71,7 +71,8 @@ qt {
|
||||
# Add the same default rpaths as Xcode does for new projects.
|
||||
# This is especially important for iOS/tvOS/watchOS where no other option is possible.
|
||||
!no_default_rpath {
|
||||
QMAKE_RPATHDIR += @executable_path/../Frameworks
|
||||
uikit: QMAKE_RPATHDIR += @executable_path/Frameworks
|
||||
else: QMAKE_RPATHDIR += @executable_path/../Frameworks
|
||||
equals(TEMPLATE, lib):!plugin:lib_bundle: QMAKE_RPATHDIR += @loader_path/Frameworks
|
||||
}
|
||||
|
||||
|
7
mkspecs/features/mac/no_warn_empty_obj_files.prf
Normal file
7
mkspecs/features/mac/no_warn_empty_obj_files.prf
Normal file
@ -0,0 +1,7 @@
|
||||
# Prevent warnings about object files without any symbols. This is a common
|
||||
# thing in Qt as we tend to build files unconditionally, and then use ifdefs
|
||||
# to compile out parts that are not relevant.
|
||||
QMAKE_RANLIB += -no_warning_for_no_symbols
|
||||
|
||||
# We have to tell 'ar' to not run ranlib by itself
|
||||
QMAKE_AR += -S
|
@ -88,6 +88,9 @@ cross_compile: \
|
||||
android|uikit|winrt: \
|
||||
CONFIG += builtin_testdata
|
||||
|
||||
# Prevent warnings about object files without any symbols
|
||||
macos: CONFIG += no_warn_empty_obj_files
|
||||
|
||||
CONFIG += \
|
||||
utf8_source \
|
||||
create_prl link_prl \
|
||||
|
@ -107,10 +107,51 @@ QT_BEGIN_NAMESPACE
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Implements qFpClassify() for qfloat16.
|
||||
*/
|
||||
\internal
|
||||
\since 5.14
|
||||
bool qfloat16::isInf() const noexcept
|
||||
|
||||
Tests whether this \c qfloat16 value is an infinity.
|
||||
|
||||
\sa qIsInf()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\since 5.14
|
||||
bool qfloat16::isNaN() const noexcept
|
||||
|
||||
Tests whether this \c qfloat16 value is "not a number".
|
||||
|
||||
\sa qIsNaN()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
bool qfloat16::isNormal() const noexcept
|
||||
|
||||
Tests whether this \c qfloat16 value is finite and in normal form.
|
||||
|
||||
\sa qFpClassify()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\since 5.14
|
||||
bool qfloat16::isFinite() const noexcept
|
||||
|
||||
Tests whether this \c qfloat16 value is finite.
|
||||
|
||||
\sa qIsFinite()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\internal
|
||||
\since 5.14
|
||||
Implements qFpClassify() for qfloat16.
|
||||
|
||||
\sa qFpClassify()
|
||||
*/
|
||||
int qfloat16::fpClassify() const noexcept
|
||||
{
|
||||
return isInf() ? FP_INFINITE : isNaN() ? FP_NAN
|
||||
|
@ -48,6 +48,10 @@
|
||||
#include "qoperatingsystemversion_p.h"
|
||||
#if defined(Q_OS_WIN) || defined(Q_OS_CYGWIN) || defined(Q_OS_WINRT)
|
||||
#include "qoperatingsystemversion_win_p.h"
|
||||
# if QT_CONFIG(settings)
|
||||
# include "qsettings.h"
|
||||
# include "qvariant.h"
|
||||
# endif
|
||||
#endif
|
||||
#include <private/qlocale_tools_p.h>
|
||||
|
||||
@ -2186,12 +2190,36 @@ const QSysInfo::WinVersion QSysInfo::WindowsVersion = QSysInfo::windowsVersion()
|
||||
QT_WARNING_POP
|
||||
#endif
|
||||
|
||||
static QString readRegistryString(const QString &key, const QString &subKey)
|
||||
{
|
||||
#if QT_CONFIG(settings)
|
||||
QSettings settings(key, QSettings::NativeFormat);
|
||||
return settings.value(subKey).toString();
|
||||
#else
|
||||
Q_UNUSED(key);
|
||||
Q_UNUSED(subKey);
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline QString windowsVersionKey() { return QStringLiteral(R"(HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion)"); }
|
||||
|
||||
static inline QString windows10ReleaseId()
|
||||
{
|
||||
return readRegistryString(windowsVersionKey(), QStringLiteral("ReleaseId"));
|
||||
}
|
||||
|
||||
static inline QString windows7Build()
|
||||
{
|
||||
return readRegistryString(windowsVersionKey(), QStringLiteral("CurrentBuild"));
|
||||
}
|
||||
|
||||
static QString winSp_helper()
|
||||
{
|
||||
const auto osv = qWindowsVersionInfo();
|
||||
const qint16 major = osv.wServicePackMajor;
|
||||
if (major) {
|
||||
QString sp = QStringLiteral(" SP ") + QString::number(major);
|
||||
QString sp = QStringLiteral("SP ") + QString::number(major);
|
||||
const qint16 minor = osv.wServicePackMinor;
|
||||
if (minor)
|
||||
sp += QLatin1Char('.') + QString::number(minor);
|
||||
@ -2904,19 +2932,35 @@ QString QSysInfo::prettyProductName()
|
||||
{
|
||||
#if (defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)) || defined(Q_OS_DARWIN) || defined(Q_OS_WIN)
|
||||
const auto version = QOperatingSystemVersion::current();
|
||||
const int majorVersion = version.majorVersion();
|
||||
const QString versionString = QString::number(majorVersion) + QLatin1Char('.')
|
||||
+ QString::number(version.minorVersion());
|
||||
QString result = version.name() + QLatin1Char(' ');
|
||||
const char *name = osVer_helper(version);
|
||||
if (name)
|
||||
return version.name() + QLatin1Char(' ') + QLatin1String(name)
|
||||
# if defined(Q_OS_WIN)
|
||||
+ winSp_helper()
|
||||
# endif
|
||||
+ QLatin1String(" (") + QString::number(version.majorVersion())
|
||||
+ QLatin1Char('.') + QString::number(version.minorVersion())
|
||||
+ QLatin1Char(')');
|
||||
else
|
||||
return version.name() + QLatin1Char(' ')
|
||||
+ QString::number(version.majorVersion()) + QLatin1Char('.')
|
||||
+ QString::number(version.minorVersion());
|
||||
if (!name)
|
||||
return result + versionString;
|
||||
result += QLatin1String(name);
|
||||
# if !defined(Q_OS_WIN)
|
||||
return result + QLatin1String(" (") + versionString + QLatin1Char(')');
|
||||
# else
|
||||
// (resembling winver.exe): Windows 10 "Windows 10 Version 1809"
|
||||
result += QLatin1String(" Version ");
|
||||
if (majorVersion >= 10) {
|
||||
const auto releaseId = windows10ReleaseId();
|
||||
if (!releaseId.isEmpty())
|
||||
result += QLatin1String(" Version ") + releaseId;
|
||||
return result;
|
||||
}
|
||||
// Windows 7: "Windows 7 Version 6.1 (Build 7601: Service Pack 1)"
|
||||
result += versionString + QLatin1String(" (");
|
||||
const auto build = windows7Build();
|
||||
if (!build.isEmpty())
|
||||
result += QLatin1String("Build ") + build;
|
||||
const auto servicePack = winSp_helper();
|
||||
if (!servicePack.isEmpty())
|
||||
result += QLatin1String(": ") + servicePack;
|
||||
return result + QLatin1Char(')');
|
||||
# endif // Windows
|
||||
#elif defined(Q_OS_HAIKU)
|
||||
return QLatin1String("Haiku ") + productVersion();
|
||||
#elif defined(Q_OS_UNIX)
|
||||
|
@ -701,7 +701,7 @@ const QCalendarBackend *QCalendarBackend::fromEnum(QCalendar::System system)
|
||||
calendar being constructed by other means first. With no argument, the
|
||||
default constructor returns the Gregorian calendar.
|
||||
|
||||
\sa QCalendar, System
|
||||
\sa QCalendar, System, isValid()
|
||||
*/
|
||||
|
||||
QCalendar::QCalendar()
|
||||
@ -723,6 +723,15 @@ QCalendar::QCalendar(QLatin1String name)
|
||||
QCalendar::QCalendar(QStringView name)
|
||||
: d(QCalendarBackend::fromName(name)) {}
|
||||
|
||||
/*
|
||||
\fn bool QCalendar::isValid() const
|
||||
|
||||
Returns true if this is a valid calendar object.
|
||||
|
||||
Constructing a calendar with an unrecognised calendar name may result in an
|
||||
invalid object. Use this method to check after creating a calendar by name.
|
||||
*/
|
||||
|
||||
// Date queries:
|
||||
|
||||
/*!
|
||||
|
@ -137,7 +137,7 @@ public:
|
||||
explicit QCalendar(QStringView name);
|
||||
|
||||
// QCalendar is a trivially copyable value type.
|
||||
bool isValid() { return d != nullptr; }
|
||||
bool isValid() const { return d != nullptr; }
|
||||
|
||||
// Date queries:
|
||||
int daysInMonth(int month, int year = Unspecified) const;
|
||||
|
@ -3548,6 +3548,7 @@ inline qint64 QDateTimePrivate::zoneMSecsToEpochMSecs(qint64 zoneMSecs, const QT
|
||||
*/
|
||||
|
||||
/*!
|
||||
\since 5.14
|
||||
\enum QDateTime::YearRange
|
||||
|
||||
This enumerated type describes the range of years (in the Gregorian
|
||||
|
@ -186,7 +186,7 @@ const QDBusArgument &operator>>(const QDBusArgument &argument, MyDictionary &myd
|
||||
argument.beginMap();
|
||||
mydict.clear();
|
||||
|
||||
while ( !argMap.atEnd() ) {
|
||||
while ( !argument.atEnd() ) {
|
||||
int key;
|
||||
MyValue value;
|
||||
argument.beginMapEntry();
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include <QDir>
|
||||
#include <QSaveFile>
|
||||
#include <QLoggingCategory>
|
||||
#include <QCryptographicHash>
|
||||
|
||||
#ifdef Q_OS_UNIX
|
||||
#include <sys/mman.h>
|
||||
@ -94,6 +95,15 @@ GLEnvInfo::GLEnvInfo()
|
||||
glversion = QByteArray(version);
|
||||
}
|
||||
|
||||
QByteArray QOpenGLProgramBinaryCache::ProgramDesc::cacheKey() const
|
||||
{
|
||||
QCryptographicHash keyBuilder(QCryptographicHash::Sha1);
|
||||
for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : shaders)
|
||||
keyBuilder.addData(shader.source);
|
||||
|
||||
return keyBuilder.result().toHex();
|
||||
}
|
||||
|
||||
static inline bool qt_ensureWritableDir(const QString &name)
|
||||
{
|
||||
QDir::root().mkpath(name);
|
||||
|
@ -71,6 +71,7 @@ public:
|
||||
};
|
||||
struct ProgramDesc {
|
||||
QVector<ShaderDesc> shaders;
|
||||
QByteArray cacheKey() const;
|
||||
};
|
||||
|
||||
QOpenGLProgramBinaryCache();
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <QtCore/qloggingcategory.h>
|
||||
#include <QtCore/qcryptographichash.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtGui/qtransform.h>
|
||||
#include <QtGui/QColor>
|
||||
@ -3819,11 +3818,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary()
|
||||
|
||||
Q_Q(QOpenGLShaderProgram);
|
||||
|
||||
QCryptographicHash keyBuilder(QCryptographicHash::Sha1);
|
||||
for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders))
|
||||
keyBuilder.addData(shader.source);
|
||||
|
||||
const QByteArray cacheKey = keyBuilder.result().toHex();
|
||||
const QByteArray cacheKey = binaryProgram.cacheKey();
|
||||
if (DBG_SHADER_CACHE().isEnabled(QtDebugMsg))
|
||||
qCDebug(DBG_SHADER_CACHE, "program with %d shaders, cache key %s",
|
||||
binaryProgram.shaders.count(), cacheKey.constData());
|
||||
|
@ -707,8 +707,8 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
|
||||
|
||||
Used with QRhiCommandBuffer::setViewport().
|
||||
|
||||
\note QRhi assumes OpenGL-style viewport coordinates, meaning x and y are
|
||||
bottom-left.
|
||||
QRhi assumes OpenGL-style viewport coordinates, meaning x and y are
|
||||
bottom-left. Negative width or height are not allowed.
|
||||
|
||||
Typical usage is like the following:
|
||||
|
||||
@ -737,7 +737,9 @@ QDebug operator<<(QDebug dbg, const QRhiDepthStencilClearValue &v)
|
||||
Constructs a viewport description with the rectangle specified by \a x, \a
|
||||
y, \a w, \a h and the depth range \a minDepth and \a maxDepth.
|
||||
|
||||
\note x and y are assumed to be the bottom-left position.
|
||||
\note \a x and \a y are assumed to be the bottom-left position. \a w and \a
|
||||
h should not be negative, the viewport will be ignored by
|
||||
QRhiCommandBuffer::setViewport() otherwise.
|
||||
|
||||
\sa QRhi::clipSpaceCorrMatrix()
|
||||
*/
|
||||
@ -810,8 +812,12 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
|
||||
only possible with a QRhiGraphicsPipeline that has
|
||||
QRhiGraphicsPipeline::UsesScissor set.
|
||||
|
||||
\note QRhi assumes OpenGL-style scissor coordinates, meaning x and y are
|
||||
bottom-left.
|
||||
QRhi assumes OpenGL-style scissor coordinates, meaning x and y are
|
||||
bottom-left. Negative width or height are not allowed. However, apart from
|
||||
that, the flexible OpenGL semantics apply: negative x and y, partially out
|
||||
of bounds rectangles, etc. will be handled gracefully, clamping as
|
||||
appropriate. Therefore, any rendering logic targeting OpenGL can feed
|
||||
scissor rectangles into QRhiScissor as-is, without any adaptation.
|
||||
|
||||
\sa QRhiCommandBuffer::setScissor(), QRhiViewport
|
||||
*/
|
||||
@ -826,7 +832,11 @@ QDebug operator<<(QDebug dbg, const QRhiViewport &v)
|
||||
Constructs a scissor with the rectangle specified by \a x, \a y, \a w, and
|
||||
\a h.
|
||||
|
||||
\note x and y are assumed to be the bottom-left position.
|
||||
\note \a x and \a y are assumed to be the bottom-left position. Negative \a w
|
||||
or \a h are not allowed, such scissor rectangles will be ignored by
|
||||
QRhiCommandBuffer. Other than that, the flexible OpenGL semantics apply:
|
||||
negative x and y, partially out of bounds rectangles, etc. will be handled
|
||||
gracefully, clamping as appropriate.
|
||||
*/
|
||||
QRhiScissor::QRhiScissor(int x, int y, int w, int h)
|
||||
: m_rect { { x, y, w, h } }
|
||||
|
@ -233,27 +233,37 @@ bool qrhi_toTopLeftRenderTargetRect(const QSize &outputSize, const std::array<T,
|
||||
T *x, T *y, T *w, T *h)
|
||||
{
|
||||
// x,y are bottom-left in QRhiScissor and QRhiViewport but top-left in
|
||||
// Vulkan/Metal/D3D. We also need proper clamping since some
|
||||
// validation/debug layers are allergic to out of bounds scissor or
|
||||
// viewport rects.
|
||||
// Vulkan/Metal/D3D. Our input is an OpenGL-style scissor rect where both
|
||||
// negative x or y, and partly or completely out of bounds rects are
|
||||
// allowed. The only thing the input here cannot have is a negative width
|
||||
// or height. We must handle all other input gracefully, clamping to a zero
|
||||
// width or height rect in the worst case, and ensuring the resulting rect
|
||||
// is inside the rendertarget's bounds because some APIs' validation/debug
|
||||
// layers are allergic to out of bounds scissor or viewport rects.
|
||||
|
||||
const T outputWidth = outputSize.width();
|
||||
const T outputHeight = outputSize.height();
|
||||
const T inputWidth = r[2];
|
||||
const T inputHeight = r[3];
|
||||
|
||||
*x = qMax<T>(0, r[0]);
|
||||
*y = qMax<T>(0, outputHeight - (r[1] + inputHeight));
|
||||
*w = inputWidth;
|
||||
*h = inputHeight;
|
||||
|
||||
if (*x >= outputWidth || *y >= outputHeight)
|
||||
if (inputWidth < 0 || inputHeight < 0)
|
||||
return false;
|
||||
|
||||
*x = r[0];
|
||||
*y = outputHeight - (r[1] + inputHeight);
|
||||
|
||||
const T widthOffset = *x < 0 ? -*x : 0;
|
||||
const T heightOffset = *y < 0 ? -*y : 0;
|
||||
|
||||
*x = qBound<T>(0, *x, outputWidth - 1);
|
||||
*y = qBound<T>(0, *y, outputHeight - 1);
|
||||
*w = qMax<T>(0, inputWidth - widthOffset);
|
||||
*h = qMax<T>(0, inputHeight - heightOffset);
|
||||
|
||||
if (*x + *w > outputWidth)
|
||||
*w = outputWidth - *x;
|
||||
*w = qMax<T>(0, outputWidth - *x - 1);
|
||||
if (*y + *h > outputHeight)
|
||||
*h = outputHeight - *y;
|
||||
*h = qMax<T>(0, outputHeight - *y - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1004,8 +1004,12 @@ void QRhiGles2::setViewport(QRhiCommandBuffer *cb, const QRhiViewport &viewport)
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
cmd.cmd = QGles2CommandBuffer::Command::Viewport;
|
||||
const std::array<float, 4> r = viewport.viewport();
|
||||
cmd.args.viewport.x = qMax(0.0f, r[0]);
|
||||
cmd.args.viewport.y = qMax(0.0f, r[1]);
|
||||
// A negative width or height is an error. A negative x or y is not.
|
||||
if (r[2] < 0.0f || r[3] < 0.0f)
|
||||
return;
|
||||
|
||||
cmd.args.viewport.x = r[0];
|
||||
cmd.args.viewport.y = r[1];
|
||||
cmd.args.viewport.w = r[2];
|
||||
cmd.args.viewport.h = r[3];
|
||||
cmd.args.viewport.d0 = viewport.minDepth();
|
||||
@ -1021,8 +1025,12 @@ void QRhiGles2::setScissor(QRhiCommandBuffer *cb, const QRhiScissor &scissor)
|
||||
QGles2CommandBuffer::Command cmd;
|
||||
cmd.cmd = QGles2CommandBuffer::Command::Scissor;
|
||||
const std::array<int, 4> r = scissor.scissor();
|
||||
cmd.args.scissor.x = qMax(0, r[0]);
|
||||
cmd.args.scissor.y = qMax(0, r[1]);
|
||||
// A negative width or height is an error. A negative x or y is not.
|
||||
if (r[2] < 0 || r[3] < 0)
|
||||
return;
|
||||
|
||||
cmd.args.scissor.x = r[0];
|
||||
cmd.args.scissor.y = r[1];
|
||||
cmd.args.scissor.w = r[2];
|
||||
cmd.args.scissor.h = r[3];
|
||||
cbD->commands.append(cmd);
|
||||
@ -2250,6 +2258,7 @@ void QRhiGles2::executeBindGraphicsPipeline(QRhiGraphicsPipeline *ps)
|
||||
}
|
||||
} else {
|
||||
f->glDisable(GL_BLEND);
|
||||
f->glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
}
|
||||
if (psD->m_depthTest)
|
||||
f->glEnable(GL_DEPTH_TEST);
|
||||
|
@ -838,8 +838,15 @@ void QRhiMetal::setGraphicsPipeline(QRhiCommandBuffer *cb, QRhiGraphicsPipeline
|
||||
|
||||
[cbD->d->currentRenderPassEncoder setRenderPipelineState: psD->d->ps];
|
||||
[cbD->d->currentRenderPassEncoder setDepthStencilState: psD->d->ds];
|
||||
[cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
|
||||
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding];
|
||||
|
||||
if (cbD->currentCullMode == -1 || psD->d->cullMode != uint(cbD->currentCullMode)) {
|
||||
[cbD->d->currentRenderPassEncoder setCullMode: psD->d->cullMode];
|
||||
cbD->currentCullMode = int(psD->d->cullMode);
|
||||
}
|
||||
if (cbD->currentFrontFaceWinding == -1 || psD->d->winding != uint(cbD->currentFrontFaceWinding)) {
|
||||
[cbD->d->currentRenderPassEncoder setFrontFacingWinding: psD->d->winding];
|
||||
cbD->currentFrontFaceWinding = int(psD->d->winding);
|
||||
}
|
||||
}
|
||||
|
||||
psD->lastActiveFrameSlot = currentFrameSlot;
|
||||
@ -3450,6 +3457,10 @@ void QMetalCommandBuffer::resetPerPassCachedState()
|
||||
currentSrbGeneration = 0;
|
||||
currentResSlot = -1;
|
||||
currentIndexBuffer = nullptr;
|
||||
currentIndexOffset = 0;
|
||||
currentIndexFormat = QRhiCommandBuffer::IndexUInt16;
|
||||
currentCullMode = -1;
|
||||
currentFrontFaceWinding = -1;
|
||||
|
||||
d->currentFirstVertexBinding = -1;
|
||||
d->currentVertexInputsBuffers.clear();
|
||||
|
@ -271,8 +271,11 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
|
||||
ComputePass
|
||||
};
|
||||
|
||||
// per-pass (render or compute command encoder) persistent state
|
||||
PassType recordingPass;
|
||||
QRhiRenderTarget *currentTarget;
|
||||
|
||||
// per-pass (render or compute command encoder) volatile (cached) state
|
||||
QRhiGraphicsPipeline *currentGraphicsPipeline;
|
||||
QRhiComputePipeline *currentComputePipeline;
|
||||
uint currentPipelineGeneration;
|
||||
@ -283,6 +286,8 @@ struct QMetalCommandBuffer : public QRhiCommandBuffer
|
||||
QRhiBuffer *currentIndexBuffer;
|
||||
quint32 currentIndexOffset;
|
||||
QRhiCommandBuffer::IndexFormat currentIndexFormat;
|
||||
int currentCullMode;
|
||||
int currentFrontFaceWinding;
|
||||
|
||||
const QRhiNativeHandles *nativeHandles();
|
||||
void resetState();
|
||||
|
@ -1110,16 +1110,32 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
|
||||
glyph_buffer.reset(new uchar[glyph_buffer_size]);
|
||||
|
||||
if (slot->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) {
|
||||
Q_ASSERT(format == Format_Mono);
|
||||
uchar *src = slot->bitmap.buffer;
|
||||
uchar *dst = glyph_buffer.data();
|
||||
int h = slot->bitmap.rows;
|
||||
|
||||
int bytes = ((info.width + 7) & ~7) >> 3;
|
||||
while (h--) {
|
||||
memcpy (dst, src, bytes);
|
||||
dst += pitch;
|
||||
src += slot->bitmap.pitch;
|
||||
// Some fonts return bitmaps even when we requested something else:
|
||||
if (format == Format_Mono) {
|
||||
int bytes = ((info.width + 7) & ~7) >> 3;
|
||||
while (h--) {
|
||||
memcpy (dst, src, bytes);
|
||||
dst += pitch;
|
||||
src += slot->bitmap.pitch;
|
||||
}
|
||||
} else if (format == Format_A8) {
|
||||
while (h--) {
|
||||
for (int x = 0; x < int{info.width}; x++)
|
||||
dst[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
|
||||
dst += pitch;
|
||||
src += slot->bitmap.pitch;
|
||||
}
|
||||
} else {
|
||||
while (h--) {
|
||||
uint *dd = reinterpret_cast<uint *>(dst);
|
||||
for (int x = 0; x < int{info.width}; x++)
|
||||
dd[x] = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffffff : 0x00000000);
|
||||
dst += pitch;
|
||||
src += slot->bitmap.pitch;
|
||||
}
|
||||
}
|
||||
} else if (slot->bitmap.pixel_mode == 7 /*FT_PIXEL_MODE_BGRA*/) {
|
||||
Q_ASSERT(format == Format_ARGB);
|
||||
|
@ -182,7 +182,7 @@ void Window::customRender()
|
||||
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
|
@ -197,7 +197,7 @@ void Window::customRender()
|
||||
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
|
@ -195,7 +195,7 @@ void Window::customRender()
|
||||
cb->endComputePass();
|
||||
|
||||
// graphics pass
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 });
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
|
||||
cb->setGraphicsPipeline(d.graphicsPipeline);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
QRhiCommandBuffer::VertexInput vbufBinding(d.sbuf, 0);
|
||||
|
@ -217,7 +217,7 @@ void Window::customRender()
|
||||
cb->dispatch(d.imageSize.width() / 16, d.imageSize.height() / 16, 1);
|
||||
cb->endComputePass();
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 });
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
cb->setShaderResources();
|
||||
|
@ -168,7 +168,7 @@ void Window::customRender()
|
||||
// no translation
|
||||
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
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();
|
||||
|
241
tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp
Normal file
241
tests/manual/rhi/cubemap_scissor/cubemap_scissor.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2018 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** BSD License Usage
|
||||
** Alternatively, you may use this file under the terms of the BSD license
|
||||
** as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of The Qt Company Ltd nor the names of its
|
||||
** contributors may be used to endorse or promote products derived
|
||||
** from this software without specific prior written permission.
|
||||
**
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
// This is a test for scissoring. Based on the cubemap test (because there the
|
||||
// rendering covers the entire viewport which is what we need here). The
|
||||
// scissor rectangle moves first up, then down, then from the center to the
|
||||
// left and then to right. The important part is to ensure that the behavior
|
||||
// identical between all backends, especially when the rectangle is partly or
|
||||
// fully off window.
|
||||
|
||||
#include "../shared/examplefw.h"
|
||||
#include "../shared/cube.h"
|
||||
|
||||
struct {
|
||||
QVector<QRhiResource *> releasePool;
|
||||
QRhiBuffer *vbuf = nullptr;
|
||||
QRhiBuffer *ubuf = nullptr;
|
||||
QRhiTexture *tex = nullptr;
|
||||
QRhiSampler *sampler = nullptr;
|
||||
QRhiShaderResourceBindings *srb = nullptr;
|
||||
QRhiGraphicsPipeline *ps = nullptr;
|
||||
QRhiResourceUpdateBatch *initialUpdates = nullptr;
|
||||
|
||||
QPoint scissorBottomLeft;
|
||||
QSize scissorSize;
|
||||
int scissorAnimState = 0;
|
||||
QSize outputSize;
|
||||
} d;
|
||||
|
||||
void Window::customInit()
|
||||
{
|
||||
d.vbuf = m_r->newBuffer(QRhiBuffer::Immutable, QRhiBuffer::VertexBuffer, sizeof(cube));
|
||||
d.vbuf->build();
|
||||
d.releasePool << d.vbuf;
|
||||
|
||||
d.ubuf = m_r->newBuffer(QRhiBuffer::Dynamic, QRhiBuffer::UniformBuffer, 64);
|
||||
d.ubuf->build();
|
||||
d.releasePool << d.ubuf;
|
||||
|
||||
const QSize cubeMapSize(512, 512);
|
||||
d.tex = m_r->newTexture(QRhiTexture::RGBA8, cubeMapSize, 1, QRhiTexture::CubeMap);
|
||||
d.releasePool << d.tex;
|
||||
d.tex->build();
|
||||
|
||||
d.initialUpdates = m_r->nextResourceUpdateBatch();
|
||||
d.initialUpdates->uploadStaticBuffer(d.vbuf, cube);
|
||||
|
||||
QImage img = QImage(":/c.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
|
||||
// just use the same image for all faces for now
|
||||
QRhiTextureSubresourceUploadDescription subresDesc(img);
|
||||
QRhiTextureUploadDescription desc({
|
||||
{ 0, 0, subresDesc }, // +X
|
||||
{ 1, 0, subresDesc }, // -X
|
||||
{ 2, 0, subresDesc }, // +Y
|
||||
{ 3, 0, subresDesc }, // -Y
|
||||
{ 4, 0, subresDesc }, // +Z
|
||||
{ 5, 0, subresDesc } // -Z
|
||||
});
|
||||
d.initialUpdates->uploadTexture(d.tex, desc);
|
||||
|
||||
d.sampler = m_r->newSampler(QRhiSampler::Linear, QRhiSampler::Linear, QRhiSampler::None,
|
||||
QRhiSampler::Repeat, QRhiSampler::Repeat);
|
||||
d.releasePool << d.sampler;
|
||||
d.sampler->build();
|
||||
|
||||
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->build();
|
||||
|
||||
d.ps = m_r->newGraphicsPipeline();
|
||||
d.releasePool << d.ps;
|
||||
|
||||
d.ps->setFlags(QRhiGraphicsPipeline::UsesScissor);
|
||||
|
||||
d.ps->setDepthTest(true);
|
||||
d.ps->setDepthWrite(true);
|
||||
d.ps->setDepthOp(QRhiGraphicsPipeline::LessOrEqual);
|
||||
|
||||
d.ps->setCullMode(QRhiGraphicsPipeline::Front); // we are inside the cube so cull front, not back
|
||||
d.ps->setFrontFace(QRhiGraphicsPipeline::CCW); // front is ccw in the cube data
|
||||
|
||||
QShader vs = getShader(QLatin1String(":/cubemap.vert.qsb"));
|
||||
Q_ASSERT(vs.isValid());
|
||||
QShader fs = getShader(QLatin1String(":/cubemap.frag.qsb"));
|
||||
Q_ASSERT(fs.isValid());
|
||||
d.ps->setShaderStages({
|
||||
{ QRhiShaderStage::Vertex, vs },
|
||||
{ QRhiShaderStage::Fragment, fs }
|
||||
});
|
||||
|
||||
QRhiVertexInputLayout inputLayout;
|
||||
inputLayout.setBindings({
|
||||
{ 3 * sizeof(float) }
|
||||
});
|
||||
inputLayout.setAttributes({
|
||||
{ 0, 0, QRhiVertexInputAttribute::Float3, 0 }
|
||||
});
|
||||
|
||||
d.ps->setVertexInputLayout(inputLayout);
|
||||
d.ps->setShaderResourceBindings(d.srb);
|
||||
d.ps->setRenderPassDescriptor(m_rp);
|
||||
|
||||
d.ps->build();
|
||||
|
||||
d.scissorAnimState = 0;
|
||||
}
|
||||
|
||||
void Window::customRelease()
|
||||
{
|
||||
qDeleteAll(d.releasePool);
|
||||
d.releasePool.clear();
|
||||
}
|
||||
|
||||
static void advanceScissor()
|
||||
{
|
||||
switch (d.scissorAnimState) {
|
||||
case 1: // up
|
||||
d.scissorBottomLeft.setX(d.outputSize.width() / 4);
|
||||
d.scissorBottomLeft.ry() += 1;
|
||||
if (d.scissorBottomLeft.y() > d.outputSize.height() + 100)
|
||||
d.scissorAnimState = 2;
|
||||
break;
|
||||
case 2: // down
|
||||
d.scissorBottomLeft.ry() -= 1;
|
||||
if (d.scissorBottomLeft.y() < -d.scissorSize.height() - 100)
|
||||
d.scissorAnimState = 3;
|
||||
break;
|
||||
case 3: // left
|
||||
d.scissorBottomLeft.setY(d.outputSize.height() / 4);
|
||||
d.scissorBottomLeft.rx() += 1;
|
||||
if (d.scissorBottomLeft.x() > d.outputSize.width() + 100)
|
||||
d.scissorAnimState = 4;
|
||||
break;
|
||||
case 4: // right
|
||||
d.scissorBottomLeft.rx() -= 1;
|
||||
if (d.scissorBottomLeft.x() < -d.scissorSize.width() - 100)
|
||||
d.scissorAnimState = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
qDebug() << "scissor bottom-left" << d.scissorBottomLeft << "size" << d.scissorSize;
|
||||
}
|
||||
|
||||
void Window::customRender()
|
||||
{
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
|
||||
QRhiResourceUpdateBatch *u = m_r->nextResourceUpdateBatch();
|
||||
|
||||
if (d.initialUpdates) {
|
||||
u->merge(d.initialUpdates);
|
||||
d.initialUpdates->release();
|
||||
d.initialUpdates = nullptr;
|
||||
}
|
||||
|
||||
d.outputSize = outputSizeInPixels;
|
||||
if (d.scissorAnimState == 0) {
|
||||
d.scissorBottomLeft = QPoint(outputSizeInPixels.width() / 4, 0);
|
||||
d.scissorSize = QSize(outputSizeInPixels.width() / 2, outputSizeInPixels.height() / 2);
|
||||
d.scissorAnimState = 1;
|
||||
}
|
||||
|
||||
QMatrix4x4 mvp = m_r->clipSpaceCorrMatrix();
|
||||
mvp.perspective(90.0f, outputSizeInPixels.width() / (float) outputSizeInPixels.height(), 0.01f, 1000.0f);
|
||||
// cube vertices go from -1..1
|
||||
mvp.scale(10);
|
||||
static float rx = 0;
|
||||
mvp.rotate(rx, 1, 0, 0);
|
||||
rx += 0.5f;
|
||||
// no translation
|
||||
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport(QRhiViewport(0, 0, outputSizeInPixels.width(), outputSizeInPixels.height()));
|
||||
|
||||
// Apply a scissor rectangle that moves around on the screen, also
|
||||
// exercising the out of screen (negative x or y) case.
|
||||
cb->setScissor(QRhiScissor(d.scissorBottomLeft.x(), d.scissorBottomLeft.y(),
|
||||
d.scissorSize.width(), d.scissorSize.height()));
|
||||
|
||||
cb->setShaderResources();
|
||||
|
||||
const QRhiCommandBuffer::VertexInput vbufBinding(d.vbuf, 0);
|
||||
cb->setVertexInput(0, 1, &vbufBinding);
|
||||
cb->draw(36);
|
||||
cb->endPass();
|
||||
|
||||
advanceScissor();
|
||||
}
|
8
tests/manual/rhi/cubemap_scissor/cubemap_scissor.pro
Normal file
8
tests/manual/rhi/cubemap_scissor/cubemap_scissor.pro
Normal file
@ -0,0 +1,8 @@
|
||||
TEMPLATE = app
|
||||
|
||||
QT += gui-private
|
||||
|
||||
SOURCES = \
|
||||
cubemap_scissor.cpp
|
||||
|
||||
RESOURCES = cubemap_scissor.qrc
|
7
tests/manual/rhi/cubemap_scissor/cubemap_scissor.qrc
Normal file
7
tests/manual/rhi/cubemap_scissor/cubemap_scissor.qrc
Normal file
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="cubemap.vert.qsb">../cubemap/cubemap.vert.qsb</file>
|
||||
<file alias="cubemap.frag.qsb">../cubemap/cubemap.frag.qsb</file>
|
||||
<file alias="c.png">../cubemap/c.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -317,7 +317,7 @@ void Window::customRender()
|
||||
}
|
||||
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
cb->setShaderResources();
|
||||
|
@ -161,7 +161,7 @@ void Window::customRender()
|
||||
u->updateDynamicBuffer(d.ubuf, 0, 64, mvp.constData());
|
||||
}
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
cb->setShaderResources();
|
||||
|
@ -283,7 +283,7 @@ void Window::customRender()
|
||||
}
|
||||
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
vbufBinding.second = 0;
|
||||
|
@ -248,7 +248,7 @@ void Window::customRender()
|
||||
|
||||
// onscreen (quad)
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 });
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
cb->setShaderResources();
|
||||
|
@ -315,7 +315,7 @@ void Window::customRender()
|
||||
|
||||
// onscreen
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 });
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
|
||||
cb->setGraphicsPipeline(d.psLeft); // showing the non-msaa version
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
cb->setShaderResources();
|
||||
|
@ -8,6 +8,7 @@ SUBDIRS += \
|
||||
msaatexture \
|
||||
msaarenderbuffer \
|
||||
cubemap \
|
||||
cubemap_scissor \
|
||||
multiwindow \
|
||||
multiwindow_threaded \
|
||||
triquadcube \
|
||||
|
@ -296,7 +296,7 @@ void Window::customRender()
|
||||
cb->endPass();
|
||||
|
||||
// main pass
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 });
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 });
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
enqueueScene(cb, d.srb, oneRoundedUniformBlockSize, 0);
|
||||
|
@ -127,6 +127,7 @@ QRhiSwapChain::Flags scFlags = 0;
|
||||
QRhi::BeginFrameFlags beginFrameFlags = 0;
|
||||
QRhi::EndFrameFlags endFrameFlags = 0;
|
||||
int framesUntilTdr = -1;
|
||||
bool transparentBackground = false;
|
||||
|
||||
class Window : public QWindow
|
||||
{
|
||||
@ -167,6 +168,8 @@ protected:
|
||||
QOffscreenSurface *m_fallbackSurface = nullptr;
|
||||
#endif
|
||||
|
||||
QColor m_clearColor;
|
||||
|
||||
friend int main(int, char**);
|
||||
};
|
||||
|
||||
@ -194,6 +197,8 @@ Window::Window()
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
m_clearColor = transparentBackground ? Qt::transparent : QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
Window::~Window()
|
||||
@ -477,6 +482,9 @@ int main(int argc, char **argv)
|
||||
QCommandLineOption swOption(QLatin1String("software"), QLatin1String("Prefer a software renderer when choosing the adapter. "
|
||||
"Only applicable with some APIs and platforms."));
|
||||
cmdLineParser.addOption(swOption);
|
||||
// Allow testing having a semi-transparent window.
|
||||
QCommandLineOption transparentOption(QLatin1String("transparent"), QLatin1String("Make background transparent"));
|
||||
cmdLineParser.addOption(transparentOption);
|
||||
|
||||
cmdLineParser.process(app);
|
||||
if (cmdLineParser.isSet(nullOption))
|
||||
@ -493,6 +501,11 @@ int main(int argc, char **argv)
|
||||
qDebug("Selected graphics API is %s", qPrintable(graphicsApiName()));
|
||||
qDebug("This is a multi-api example, use command line arguments to override:\n%s", qPrintable(cmdLineParser.helpText()));
|
||||
|
||||
if (cmdLineParser.isSet(transparentOption)) {
|
||||
transparentBackground = true;
|
||||
scFlags |= QRhiSwapChain::SurfaceHasPreMulAlpha;
|
||||
}
|
||||
|
||||
#ifdef EXAMPLEFW_PREINIT
|
||||
void preInit();
|
||||
preInit();
|
||||
@ -508,6 +521,9 @@ int main(int argc, char **argv)
|
||||
fmt.setSwapInterval(0);
|
||||
if (scFlags.testFlag(QRhiSwapChain::sRGB))
|
||||
fmt.setColorSpace(QSurfaceFormat::sRGBColorSpace);
|
||||
// Exception: The alpha size is not necessarily OpenGL specific.
|
||||
if (transparentBackground)
|
||||
fmt.setAlphaBufferSize(8);
|
||||
QSurfaceFormat::setDefaultFormat(fmt);
|
||||
|
||||
// Vulkan setup.
|
||||
|
@ -296,7 +296,7 @@ void Window::customRender()
|
||||
QRhiCommandBuffer *cb = m_sc->currentFrameCommandBuffer();
|
||||
const QSize outputSizeInPixels = m_sc->currentPixelSize();
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
|
||||
cb->setGraphicsPipeline(d.ps);
|
||||
cb->setViewport({ 0, 0, float(outputSizeInPixels.width()), float(outputSizeInPixels.height()) });
|
||||
|
@ -230,7 +230,7 @@ void Window::customRender()
|
||||
if (!d.onScreenOnly)
|
||||
d.liveTexCubeRenderer.queueResourceUpdates(u);
|
||||
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), QColor::fromRgbF(0.4f, 0.7f, 0.0f, 1.0f), { 1.0f, 0 }, u);
|
||||
cb->beginPass(m_sc->currentFrameRenderTarget(), m_clearColor, { 1.0f, 0 }, u);
|
||||
cb->debugMarkBegin(QByteArrayLiteral("Triangle"));
|
||||
d.triRenderer.queueDraw(cb, outputSize);
|
||||
cb->debugMarkEnd();
|
||||
|
Loading…
Reference in New Issue
Block a user