9#include <QtQuick3DUtils/private/qssgutils_p.h>
11#include <QtQuick3DRuntimeRender/private/qssgrenderer_p.h>
12#include <QtQuick3DRuntimeRender/private/qssgrendercamera_p.h>
13#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
47 const int viewCount = cameras.
count();
49 const QMatrix4x4 projection = clipSpaceCorrMatrix * cameras[0]->projection;
50 shaders.setUniform(ubufData,
"qt_projectionMatrix", projection.
constData(), 16 *
sizeof(
float), &cui.projectionMatrixIdx);
51 const QMatrix4x4 viewMatrix = cameras[0]->globalTransform.inverted();
52 shaders.setUniform(ubufData,
"qt_viewMatrix", viewMatrix.constData(), 16 *
sizeof(
float), &cui.viewMatrixIdx);
54 QVarLengthArray<QMatrix4x4, 2> projectionMatrices(viewCount);
55 QVarLengthArray<QMatrix4x4, 2> viewMatrices(viewCount);
56 for (
int viewIndex = 0; viewIndex < viewCount; ++viewIndex) {
57 projectionMatrices[viewIndex] = clipSpaceCorrMatrix * cameras[viewIndex]->projection;
58 viewMatrices[viewIndex] = cameras[viewIndex]->globalTransform.inverted();
64 const QMatrix4x4 &modelMatrix = renderable.globalTransform;
65 shaders.setUniform(ubufData,
"qt_modelMatrix", modelMatrix.constData(), 16 *
sizeof(
float), &cui.modelMatrixIdx);
68 auto &particleBuffer = renderable.particles.m_particleBuffer;
69 const quint32 particlesPerSlice = particleBuffer.particlesPerSlice();
70 oneOverSize =
QVector2D(1.0f / particleBuffer.size().width(), 1.0f / particleBuffer.size().height());
71 shaders.setUniform(ubufData,
"qt_oneOverParticleImageSize", &oneOverSize, 2 *
sizeof(
float));
72 shaders.setUniform(ubufData,
"qt_countPerSlice", &particlesPerSlice, 1 *
sizeof(
quint32));
75 shaders.setUniform(ubufData,
"qt_opacity", &renderable.opacity, 1 *
sizeof(
float));
77 float blendImages = renderable.particles.m_blendImages ? 1.0f : 0.0f;
78 float imageCount = float(renderable.particles.m_spriteImageCount);
79 float ooImageCount = 1.0f / imageCount;
81 QVector4D spriteConfig(imageCount, ooImageCount, 0.0f, blendImages);
82 shaders.setUniform(ubufData,
"qt_spriteConfig", &spriteConfig, 4 *
sizeof(
float));
84 const float billboard = renderable.particles.m_billboard ? 1.0f : 0.0f;
85 shaders.setUniform(ubufData,
"qt_billboard", &billboard, 1 *
sizeof(
float));
89 bool hasLights = !renderable.particles.m_lights.isEmpty();
94 auto &lights = renderable.lights;
95 for (
quint32 lightIdx = 0, lightEnd = lights.size();
99 if (!renderable.particles.m_lights.contains(theLight))
101 if (theLight->type == QSSGRenderLight::Type::DirectionalLight) {
102 theLightAmbientTotal += theLight->m_diffuseColor * theLight->m_brightness;
103 }
else if (theLight->type == QSSGRenderLight::Type::PointLight && pointLight < 4) {
110 }
else if (theLight->type == QSSGRenderLight::Type::SpotLight && spotLight < 4) {
117 float coneAngle = theLight->m_coneAngle;
119 float innerConeAngle = std::min(theLight->m_innerConeAngle, coneAngle - 0.01f);
124 theLightAmbientTotal += theLight->m_ambientColor;
127 int lightOffset =
shaders.offsetOfUniform(
"qt_pointLightPosition");
128 if (lightOffset >= 0)
131 shaders.setUniform(ubufData,
"qt_light_ambient_total", &theLightAmbientTotal, 3 *
sizeof(
float), &cui.light_ambient_totalIdx);
132 int enablePointLights = pointLight > 0 ? 1 : 0;
133 int enableSpotLights = spotLight > 0 ? 1 : 0;
134 shaders.setUniform(ubufData,
"qt_pointLights", &enablePointLights,
sizeof(
int));
135 shaders.setUniform(ubufData,
"qt_spotLights", &enableSpotLights,
sizeof(
int));
141 float alphaFade = renderable.particles.m_alphaFade;
142 float sizeModifier = renderable.particles.m_sizeModifier;
143 float texcoordScale = renderable.particles.m_texcoordScale;
144 auto image = renderable.firstImage;
146 const auto size =
image->m_texture.m_texture->pixelSize();
147 texcoordScale *= float(
size.height()) / float(
size.width());
149 shaders.setUniform(ubufData,
"qt_alphaFade", &alphaFade,
sizeof(
float));
150 shaders.setUniform(ubufData,
"qt_sizeModifier", &sizeModifier,
sizeof(
float));
151 shaders.setUniform(ubufData,
"qt_texcoordScale", &texcoordScale,
sizeof(
float));
160 auto &particleBuffer = *
model->particleBuffer;
161 const quint32 particlesPerSlice = particleBuffer.particlesPerSlice();
162 const QVector2D oneOverSize =
QVector2D(1.0f / particleBuffer.size().width(), 1.0f / particleBuffer.size().height());
163 shaderPipeline.
setUniform(ubufData,
"qt_oneOverParticleImageSize", &oneOverSize, 2 *
sizeof(
float));
164 shaderPipeline.
setUniform(ubufData,
"qt_countPerSlice", &particlesPerSlice,
sizeof(
quint32));
166 shaderPipeline.
setUniform(ubufData,
"qt_particleMatrix", &particleMatrix, 16 *
sizeof(
float));
198 const QVector3D &cameraDirection,
bool animatedParticles)
204 auto particleCount =
buffer.particleCount();
205 const bool lineParticles =
segments > 0;
208 sortData.resize(particleCount);
220 const auto slices =
buffer.sliceCount();
221 const auto ss =
buffer.sliceStride();
222 const auto pps =
buffer.particlesPerSlice();
229 for (
i = 0;
i < particleCount;
i++) {
234 for (
int j = 1;
j <
buffer.segments();
j++) {
240 }
else if (animatedParticles) {
241 for (
int s = 0;
s < slices;
s++) {
243 for (
int p = 0;
p < pps &&
i < particleCount;
p++) {
252 for (
int s = 0;
s < slices;
s++) {
254 for (
int p = 0;
p < pps &&
i < particleCount;
p++) {
272 const auto slices =
buffer.sliceCount();
273 const auto ss =
buffer.sliceStride();
274 const auto pps =
buffer.particlesPerSlice();
276 char *dest =
dst.data();
281 for (
int s = 0;
s < slices;
s++) {
283 for (
int p = 0;
p < pps &&
i < particleCount;
p++) {
284 *dp = *srcParticlePointer(sdata->indexOrOffset, seg,
segments, ss, pps,
source);
295 }
else if (animatedParticles) {
296 for (
int s = 0;
s < slices;
s++) {
298 for (
int p = 0;
p < pps &&
i < particleCount;
p++) {
307 for (
int s = 0;
s < slices;
s++) {
309 for (
int p = 0;
p < pps &&
i < particleCount;
p++) {
348 const void *node = &renderable.particles;
355 char *ubufData = dcd.ubuf->beginFullDynamicBufferUpdateForCurrentFrame();
356 if (!alteredCamera) {
362 dcd.ubuf->endFullDynamicBufferUpdateForCurrentFrame();
379 bool sortingChanged = particleData.
sorting != renderable.particles.m_depthSorting;
380 if (sortingChanged && !renderable.particles.m_depthSorting) {
384 particleData.
sorting = renderable.particles.m_depthSorting;
388 if (renderable.particles.m_depthSorting) {
391 sortParticles(particleData.
sortedData, particleData.
sortData, particleBuffer, renderable.particles, inData.renderedCameraData.value()[0].direction, animatedParticles);
393 sortParticles(particleData.
sortedData, particleData.
sortData, particleBuffer, renderable.particles, alteredCamera->getScalingCorrectDirection(), animatedParticles);
403 rub->uploadTexture(particleData.
texture, uploadDesc);
414 if (renderable.renderableFlags.hasTransparency())
427 if (samplerBinding >= 0) {
428 QRhiTexture *
texture = renderableImage ? renderableImage->m_texture.m_texture :
nullptr;
429 if (samplerBinding >= 0 &&
texture) {
455 if (samplerBinding >= 0) {
457 if (samplerBinding >= 0 &&
texture) {
470 if (samplerBinding >= 0) {
471 bool hasTexture =
false;
472 if (renderable.colorTable) {
506 bool srbChanged =
false;
507 if (!srb || bindings != dcd.bindings) {
508 srb = rhiCtxD->srb(bindings);
509 dcd.bindings = bindings;
514 renderable.rhiRenderData.mainPass.srb = srb;
516 renderable.rhiRenderData.reflectionPass.srb[cubeFaceIdx] = srb;
521 && dcd.renderTargetDescriptionHash == pipelineKey.extra.renderTargetDescriptionHash
522 && dcd.renderTargetDescription == pipelineKey.renderTargetDescription
526 renderable.rhiRenderData.mainPass.pipeline = dcd.pipeline;
528 renderable.rhiRenderData.reflectionPass.pipeline = dcd.pipeline;
531 renderable.rhiRenderData.mainPass.pipeline = rhiCtxD->pipeline(pipelineKey,
532 renderPassDescriptor,
534 dcd.pipeline = renderable.rhiRenderData.mainPass.pipeline;
536 renderable.rhiRenderData.reflectionPass.pipeline = rhiCtxD->pipeline(pipelineKey,
537 renderPassDescriptor,
539 dcd.pipeline = renderable.rhiRenderData.reflectionPass.pipeline;
541 dcd.renderTargetDescriptionHash = pipelineKey.extra.renderTargetDescriptionHash;
542 dcd.renderTargetDescription = pipelineKey.renderTargetDescription;
556 bool update = particleBuffer.
serial() != particleData.
serial;
576 rub->uploadTexture(particleData.
texture, uploadDesc);
581 if (samplerBinding >= 0) {
583 if (samplerBinding >= 0 &&
texture) {
598 bool *needsSetViewport,
607 ps = renderable.rhiRenderData.reflectionPass.pipeline;
608 srb = renderable.rhiRenderData.reflectionPass.srb[cubeFaceIdx];
618 cb->setGraphicsPipeline(ps);
619 cb->setVertexInput(0, 0,
nullptr);
620 cb->setShaderResources(srb);
622 if (needsSetViewport && *needsSetViewport) {
623 cb->setViewport(
state.viewport);
624 *needsSetViewport =
false;
628 int S = renderable.particles.m_particleBuffer.segments();
629 int N = renderable.particles.m_particleBuffer.particleCount() / S;
635 cb->draw(4, renderable.particles.m_particleBuffer.particleCount());
637 Q_QUICK3D_PROFILE_END_WITH_ID(QQuick3DProfiler::Quick3DRenderCall, (4 |
quint64(renderable.particles.m_particleBuffer.particleCount()) << 32), renderable.particles.profilingId);
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
void clear()
Clears the contents of the byte array and makes it null.
void resize(qsizetype size)
Sets the size of the byte array to size bytes.
The QMatrix4x4 class represents a 4x4 transformation matrix in 3D space.
QMatrix4x4 inverted(bool *invertible=nullptr) const
Returns the inverse of this matrix.
const float * constData() const
Returns a constant pointer to the raw data of this matrix.
void resourceUpdate(QRhiResourceUpdateBatch *resourceUpdates)
Sometimes committing resource updates is necessary or just more convenient without starting a render ...
void setData(const QByteArray &data)
Sets data.
virtual bool create()=0
Creates the corresponding native graphics resources.
void setPixelSize(const QSize &sz)
Sets the texture size, specified in pixels, to sz.
bool isTextureFormatSupported(QRhiTexture::Format format, QRhiTexture::Flags flags={}) const
QMatrix4x4 clipSpaceCorrMatrix() const
QRhiTexture * newTexture(QRhiTexture::Format format, const QSize &pixelSize, int sampleCount=1, QRhiTexture::Flags flags={})
QRhiResourceUpdateBatch * nextResourceUpdateBatch()
static constexpr QSSGRenderTextureCubeFaceT indexOfCubeFace(QSSGRenderTextureCubeFace face) noexcept
static QSSGGraphicsPipelineStateKey create(const QSSGRhiGraphicsPipelineState &state, const QRhiRenderPassDescriptor *rpDesc, const QRhiShaderResourceBindings *srb)
static void updateUniformsForParticleModel(QSSGRhiShaderPipeline &shaderPipeline, char *ubufData, const QSSGRenderModel *model, quint32 offset)
static void rhiPrepareRenderable(QSSGRhiShaderPipeline &shaderPipeline, QSSGPassKey passKey, QSSGRhiContext *rhiCtx, QSSGRhiGraphicsPipelineState *ps, QSSGParticlesRenderable &renderable, const QSSGLayerRenderData &inData, QRhiRenderPassDescriptor *renderPassDescriptor, int samples, int viewCount, QSSGRenderCamera *alteredCamera=nullptr, QSSGRenderTextureCubeFace cubeFace=QSSGRenderTextureCubeFaceNone, QSSGReflectionMapEntry *entry=nullptr)
static void updateUniformsForParticles(QSSGRhiShaderPipeline &shaderPipeline, QSSGRhiContext *rhiCtx, char *ubufData, QSSGParticlesRenderable &renderable, const QSSGRenderCameraList &cameras)
static void rhiRenderRenderable(QSSGRhiContext *rhiCtx, QSSGParticlesRenderable &renderable, bool *needsSetViewport, QSSGRenderTextureCubeFace cubeFace, const QSSGRhiGraphicsPipelineState &state)
static void prepareParticlesForModel(QSSGRhiShaderPipeline &shaderPipeline, QSSGRhiContext *rhiCtx, QSSGRhiShaderResourceBindingList &bindings, const QSSGRenderModel *model)
static QSSGRhiContextPrivate * get(QSSGRhiContext *q)
QRhiCommandBuffer * commandBuffer() const
QRhiTexture * dummyTexture(QRhiTexture::Flags flags, QRhiResourceUpdateBatch *rub, const QSize &size=QSize(64, 64), const QColor &fillColor=Qt::black, int arraySize=0)
QRhiSampler * sampler(const QSSGRhiSamplerDescription &samplerDescription)
QRhiGraphicsPipeline::CullMode cullMode
QRhiGraphicsPipeline::TargetBlend targetBlend
void ensureUniformBuffer(QRhiBuffer **ubuf)
int bindingForTexture(const char *name, int hint=-1)
void setUniform(char *ubufData, const char *name, const void *data, size_t size, int *storeIndex=nullptr, UniformFlags flags={})
void addUniformBuffer(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiBuffer *buf, int offset=0, int size=0)
void addTexture(int binding, QRhiShaderResourceBinding::StageFlags stage, QRhiTexture *tex, QRhiSampler *sampler)
QString normalized(NormalizationForm mode, QChar::UnicodeVersion version=QChar::Unicode_Unassigned) const
Returns the string in the given Unicode normalization mode, according to the given version of the Uni...
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
static constexpr float dotProduct(QVector3D v1, QVector3D v2) noexcept
Returns the dot product of v1 and v2.
The QVector4D class represents a vector or vertex in 4D space.
\keyword 16-bit Floating Point Support\inmodule QtCore \inheaderfile QFloat16
QRhiSampler::Filter toRhi(QSSGRenderTextureFilterOp op)
Q_DECL_CONSTEXPR float translateLinearAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateConstantAttenuation(float attenuation)
Q_DECL_CONSTEXPR float translateQuadraticAttenuation(float attenuation)
Combined button and popup list for selecting options.
Q_CORE_EXPORT void qFloatToFloat16(qfloat16 *, const float *, qsizetype length) noexcept
constexpr float qDegreesToRadians(float degrees)
constexpr const T & qMin(const T &a, const T &b)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
GLsizei GLsizei GLuint * shaders
#define Q_QUICK3D_PROFILE_START(Type)
#define Q_QUICK3D_PROFILE_END_WITH_ID(Type, Payload, POID)
static int segmentCount(const QPainterPath &path, qreal pathLength)
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QSSGRenderTextureCubeFace
constexpr QSSGRenderTextureCubeFace QSSGRenderTextureCubeFaceNone
#define QSSGRHICTX_STAT(ctx, f)
#define QSSG_MAX_NUM_LIGHTS
static QByteArray convertParticleData(QByteArray &dest, const QByteArray &data, bool convert)
static void fillTargetBlend(QRhiGraphicsPipeline::TargetBlend &targetBlend, QSSGRenderParticles::BlendMode mode)
static QT_BEGIN_NAMESPACE const QRhiShaderResourceBinding::StageFlags VISIBILITY_ALL
static void sortParticles(QByteArray &result, QList< QSSGRhiSortData > &sortData, const QSSGParticleBuffer &buffer, const QSSGRenderParticles &particles, const QVector3D &cameraDirection, bool animatedParticles)
SSL_CTX int(* cb)(SSL *ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg)
unsigned long long quint64
QSqlQueryModel * model
[16]
myFilter draw(painter, QPoint(0, 0), originalPixmap)
QVector4D spotLightDir[4]
float pointLightLinearAtt[4]
QVector4D pointLightColor[4]
QVector4D spotLightPos[4]
float spotLightConstantAtt[4]
float spotLightLinearAtt[4]
float spotLightQuadAtt[4]
QVector4D spotLightColor[4]
float spotLightInnerConeAngle[4]
float pointLightConstantAtt[4]
float spotLightConeAngle[4]
float pointLightQuadAtt[4]
QVector4D pointLightPos[4]
int particleCount() const
QMatrix4x4 globalTransform
QList< QSSGRhiSortData > sortData