19#include <QtQuick3DRuntimeRender/private/qssgrenderlayer_p.h>
20#include <QtQuick3DRuntimeRender/private/qssglayerrenderdata_p.h>
22#include <QtQuick3DUtils/private/qssgassert_p.h>
25#include <QSGSimpleTextureNode>
26#include <QSGRendererInterface>
27#include <QQuickWindow>
28#include <QtQuick/private/qquickitem_p.h>
29#include <QtQuick/private/qquickpointerhandler_p.h>
33#include <QtGui/private/qeventpoint_p.h>
35#include <QtCore/private/qnumeric_p.h>
56 o->setSceneTransform(
nullptr);
74 if (rayResult.has_value()) {
76 auto ret = pickResult.m_localUVCoords.toPointF();
81 const bool outOfModel = pickResult.m_localUVCoords.isNull();
82 qCDebug(lcEv) << viewportPoint <<
"->" << (outOfModel ?
"OOM" :
"") <<
ret <<
"@" << pickResult.m_scenePosition
83 <<
"UV" << pickResult.m_localUVCoords <<
"dist" <<
qSqrt(pickResult.m_distanceSq);
115 if (
const auto idx = that->m_extensions.indexOf(
extension); idx == -1) {
117 extension->setParentItem(that->m_sceneRoot);
119 that->m_extensionListDirty =
true;
129 if (that->m_extensions.size() >
index)
141 ret = that->m_extensions.size();
150 that->m_extensions.clear();
151 that->m_extensionListDirty =
true;
159 if (that->m_extensions.size() > idx && idx > -1) {
160 that->m_extensions.replace(idx,
o);
161 that->m_extensionListDirty =
true;
170 that->m_extensions.removeLast();
171 that->m_extensionListDirty =
true;
247 m_enableInputProcessing =
true;
248 updateInputProcessing();
263 if (
auto wa = sceneManager->wattached)
264 wa->queueForCleanup(sceneManager);
268 m_sceneRoot =
nullptr;
286 itemProperty.
append(&itemProperty, sceneObject);
298 return itemProperty.
count(&itemProperty);
305 return itemProperty.
at(&itemProperty,
i);
312 return itemProperty.
clear(&itemProperty);
351 return m_environment;
381 return m_importScene;
455 return m_renderFormat;
469 return m_renderStats;
478 auto rci = wa->rci();
483 QSSG_CHECK_X(rhi !=
nullptr,
"No QRhi from QQuickWindow, this cannot happen");
493 rci = std::make_shared<QSSGRenderContextInterface>(rhi);
501 qWarning(
"The Qt Quick scene is using a rendering method that is not based on QRhi and a 3D graphics API. "
502 "Qt Quick 3D is not functional in such an environment. The View3D item is not going to display anything.");
536 qWarning(
"QSSGView3D::textureProvider: can only be queried on the rendering thread of an exposed window");
549 void run()
override {
delete m_renderer; }
556 if (m_directRenderer) {
557 window()->scheduleRenderJob(
new CleanupJob(m_directRenderer), QQuickWindow::BeforeSynchronizingStage);
558 m_directRenderer =
nullptr;
566 delete m_directRenderer;
567 m_directRenderer =
nullptr;
574 if (newGeometry.
size() != oldGeometry.
size())
581 if (m_renderModeDirty) {
586 m_renderNode =
nullptr;
588 if (m_directRenderer) {
589 delete m_directRenderer;
590 m_directRenderer =
nullptr;
594 m_renderModeDirty =
false;
596 switch (m_renderMode) {
601 setupDirectRenderer(m_renderMode);
605 node = setupOffscreenRenderer(node);
609 node = setupInlineRenderer(node);
615 const auto inputHandlingEnabled =
617 const auto enable = inputHandlingEnabled > 0;
618 if (m_enableInputProcessing !=
enable) {
619 m_enableInputProcessing =
enable;
645 if (m_enableInputProcessing &&
event->isPointerEvent())
680 if (m_environment && !m_environment->parentItem())
698 if (m_sceneRoot ==
scene) {
699 qmlWarning(
this) <<
"Cannot allow self-import or cross-import!";
707 m_importScene = inScene;
710 if (!privateObject->sceneManager) {
718 privateObject->refSceneManager(*
manager);
721 Q_ASSERT(privateObject->sceneManager);
750 m_renderModeDirty =
true;
757 if (m_renderFormat ==
format)
761 m_renderModeDirty =
true;
762 emit renderFormatChanged();
786 qmlWarning(
this) <<
"Cannot resolve view position without a camera assigned!";
792 if (_width == 0 || _height == 0)
796 return normalizedPos *
QVector3D(
float(_width),
float(_height), 1);
819 qmlWarning(
this) <<
"Cannot resolve scene position without a camera assigned!";
825 if (_width == 0 || _height == 0)
828 const QVector3D normalizedPos = viewPos /
QVector3D(
float(_width),
float(_height), 1);
848 std::optional<QSSGRenderRay> rayResult =
renderer->getRayFromViewportPos(
position);
849 if (!rayResult.has_value())
852 return processPickResult(
renderer->syncPick(rayResult.value()));
876 std::optional<QSSGRenderRay> rayResult =
renderer->getRayFromViewportPos(
position);
877 if (!rayResult.has_value())
880 const auto resultList =
renderer->syncPickAll(rayResult.value());
882 processedResultList.
reserve(resultList.size());
883 for (
const auto &
result : resultList)
886 return processedResultList;
910 return processPickResult(
renderer->syncPick(ray));
937 const auto resultList =
renderer->syncPickAll(ray);
939 processedResultList.
reserve(resultList.size());
940 for (
const auto &
result : resultList)
943 return processedResultList;
953 return m_lightmapBaker;
958 if (!m_lightmapBaker)
961 return m_lightmapBaker;
981void QQuick3DViewport::invalidateSceneGraph()
991 }
else if (m_renderNode) {
993 }
else if (m_directRenderer) {
999void QQuick3DViewport::updateDynamicTextures()
1005 for (
auto *
texture :
std::as_const(sceneManager->qsgDynamicTextures))
1011 if (importSm != sceneManager) {
1012 for (
auto *
texture :
std::as_const(importSm->qsgDynamicTextures))
1037 n->renderer->fboNode =
n;
1045 n->devicePixelRatio =
window()->effectiveDevicePixelRatio();
1046 desiredFboSize *=
n->devicePixelRatio;
1051 n->renderer->synchronize(
this, desiredFboSize,
n->devicePixelRatio);
1052 if (
n->renderer->m_textureNeedsFlip)
1054 updateDynamicTextures();
1055 n->scheduleRender();
1083 n->renderer->synchronize(
this,
targetSize,
window()->effectiveDevicePixelRatio());
1084 updateDynamicTextures();
1092void QQuick3DViewport::setupDirectRenderer(RenderMode
mode)
1096 if (!m_directRenderer) {
1109 updateDynamicTextures();
1116bool QQuick3DViewport::checkIsVisible()
const
1119 return (childPrivate->explicitVisible ||
1120 (childPrivate->extra.isAllocated() && childPrivate->extra->effectRefCount));
1141 const auto frontendObject = findFrontendNode(backendObject);
1142 if (!frontendObject)
1149 if (frontendObjectPrivate->type == QQuick3DObjectPrivate::Type::Item2D) {
1152 auto item2D = qobject_cast<QQuick3DItem2D *>(frontendObject);
1154 subsceneRootItem = item2D->contentItem();
1165 }
else if (frontendObjectPrivate->type == QQuick3DObjectPrivate::Type::Model) {
1167 int materialSubset = pickResult.
m_subset;
1168 const auto backendModel =
static_cast<const QSSGRenderModel *
>(backendObject);
1170 if (backendModel->materials.size() < (pickResult.
m_subset + 1))
1171 materialSubset = backendModel->
materials.size() - 1;
1172 if (materialSubset < 0)
1174 const auto backendMaterial = backendModel->materials.at(materialSubset);
1175 const auto frontendMaterial =
static_cast<QQuick3DMaterial*
>(findFrontendNode(backendMaterial));
1176 subsceneRootItem = getSubSceneRootItem(frontendMaterial);
1178 if (subsceneRootItem) {
1186 if (subsceneRootItem) {
1187 SubsceneInfo &subscene = visitedSubscenes[subsceneRootItem];
1188 subscene.obj = frontendObject;
1189 if (subscene.eventPointScenePositions.size() !=
event->pointCount()) {
1192 subscene.eventPointScenePositions.resize(
event->pointCount(), inf);
1194 subscene.eventPointScenePositions[pointIndex] = subscenePosition;
1216 if (frontendMaterialPrivate->type == QQuick3DObjectPrivate::Type::DefaultMaterial) {
1218 const auto defaultMaterial = qobject_cast<QQuick3DDefaultMaterial *>(material);
1219 if (defaultMaterial) {
1221 if (defaultMaterial->diffuseMap() && defaultMaterial->diffuseMap()->sourceItem())
1222 subsceneRootItem = defaultMaterial->diffuseMap()->sourceItem();
1225 }
else if (frontendMaterialPrivate->type == QQuick3DObjectPrivate::Type::PrincipledMaterial) {
1227 const auto principledMaterial = qobject_cast<QQuick3DPrincipledMaterial *>(material);
1228 if (principledMaterial) {
1230 if (principledMaterial->baseColorMap() && principledMaterial->baseColorMap()->sourceItem())
1231 subsceneRootItem = principledMaterial->baseColorMap()->sourceItem();
1233 }
else if (frontendMaterialPrivate->type == QQuick3DObjectPrivate::Type::SpecularGlossyMaterial) {
1235 const auto specularGlossyMaterial = qobject_cast<QQuick3DSpecularGlossyMaterial *>(material);
1236 if (specularGlossyMaterial) {
1238 if (specularGlossyMaterial->albedoMap() && specularGlossyMaterial->albedoMap()->sourceItem())
1239 subsceneRootItem = specularGlossyMaterial->albedoMap()->sourceItem();
1241 }
else if (frontendMaterialPrivate->type == QQuick3DObjectPrivate::Type::CustomMaterial) {
1243 const auto customMaterial = qobject_cast<QQuick3DCustomMaterial *>(material);
1244 if (customMaterial) {
1246 const auto &texturesInputs = customMaterial->m_dynamicTextureMaps;
1247 for (
const auto &textureInput : texturesInputs) {
1248 if (
auto texture = textureInput->texture()) {
1250 subsceneRootItem =
texture->sourceItem();
1257 return subsceneRootItem;
1277 originalScenePositions.
resize(
event->pointCount());
1278 for (
int pointIndex = 0; pointIndex <
event->pointCount(); ++pointIndex)
1279 originalScenePositions[pointIndex] =
event->point(pointIndex).scenePosition();
1280 for (
auto subscene : visitedSubscenes) {
1282 auto &subsceneInfo = subscene.second;
1283 Q_ASSERT(subsceneInfo.eventPointScenePositions.size() ==
event->pointCount());
1285 for (
int pointIndex = 0; pointIndex <
event->pointCount(); ++pointIndex) {
1286 const auto &pt = subsceneInfo.eventPointScenePositions.at(pointIndex);
1292 QMutableEventPoint::setPosition(ep, pt);
1293 QMutableEventPoint::setScenePosition(ep, pt);
1296 if (
event->isBeginEvent())
1297 da->setSceneTransform(
nullptr);
1298 if (da->event(
event)) {
1306 const bool item2Dcase = (frontendObjectPrivate->type == QQuick3DObjectPrivate::Type::Item2D);
1312 transform->uvCoordsArePixels = item2Dcase;
1314 qCDebug(lcPick) <<
event->type() <<
"created ViewportTransformHelper on" << da;
1317 qCDebug(lcPick) << subsceneRoot <<
"didn't want" <<
event;
1319 event->setAccepted(
false);
1321 if (visitedSubscenes.
isEmpty()) {
1322 event->setAccepted(
false);
1324 for (
int pointIndex = 0; pointIndex <
event->pointCount(); ++pointIndex)
1325 QMutableEventPoint::setScenePosition(
event->point(pointIndex), originalScenePositions.
at(pointIndex));
1338 const bool useRayPicking = !
direction.isNull();
1340 for (
int pointIndex = 0; pointIndex <
event->pointCount(); ++pointIndex) {
1341 auto &eventPoint =
event->point(pointIndex);
1346 pickResults = getPickResults(
renderer, eventPoint);
1349 for (
const auto &pickResult : pickResults)
1350 processPickedObject(pickResult.m_hitObject, pickResult, pointIndex,
event, visitedSubscenes);
1352 eventPoint.setAccepted(
false);
1355 return forwardEventToSubscenes(
event, useRayPicking,
renderer, visitedSubscenes);
1370 std::optional<QSSGRenderRay> rayResult =
renderer->getRayFromViewportPos(realPosition);
1371 if (rayResult.has_value())
1372 pickResults =
renderer->syncPickAll(rayResult.value());
1388 QQuick3DObject *frontendObject = sceneManager->lookUpNode(backendObject);
1389 if (!frontendObject && m_importScene) {
1391 frontendObject = importSceneManager->lookUpNode(backendObject);
1393 return frontendObject;
1433void QQuick3DViewport::updateInputProcessing()
1441void QQuick3DViewport::onReleaseCachedResources()
1444 renderer->releaseCachedResources();
1453 &m_extensionListDirty,
void run() override
Implement this pure virtual function in your subclass.
CleanupJob(QQuick3DSGDirectRenderer *renderer)
The QEventPoint class provides information about a point in a QPointerEvent.
QPointF position
the position of this point.
bool isEmpty() const noexcept
bool isEmpty() const noexcept
void reserve(qsizetype size)
void append(parameter_type t)
const QObjectList & children() const
Returns a list of child objects.
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
void setParent(QObject *parent)
Makes the object a child of parent.
void deleteLater()
\threadsafe
\inmodule QtCore\reentrant
A base class for pointer events.
The QQmlListProperty class allows applications to expose list-like properties of QObject-derived clas...
Q_INVOKABLE QVector3D mapFromViewport(const QVector3D &viewportPos) const
\qmlmethod vector3d Camera::mapFromViewport(vector3d viewportPos)
void updateGlobalVariables(const QRectF &inViewport)
Q_INVOKABLE QVector3D mapToViewport(const QVector3D &scenePos) const
\qmlmethod vector3d Camera::mapToViewport(vector3d scenePos)
static void extensionClear(QQmlListProperty< QQuick3DObject > *list)
static void extensionReplace(QQmlListProperty< QQuick3DObject > *list, qsizetype idx, QQuick3DObject *o)
static void extensionAppend(QQmlListProperty< QQuick3DObject > *list, QQuick3DObject *extension)
static QQuick3DObject * extensionAt(QQmlListProperty< QQuick3DObject > *list, qsizetype index)
static void extensionRemoveLast(QQmlListProperty< QQuick3DObject > *list)
static qsizetype extensionCount(QQmlListProperty< QQuick3DObject > *list)
void bake(Callback callback)
Triggers a new frame where lightmap baking will take place.
QList< QQuick3DObject * > childItems
QPointer< QQuick3DSceneManager > sceneManager
void refSceneManager(QQuick3DSceneManager &)
static void attachWatcherPriv(SceneContext *sceneContext, CallContext *callContext, Setter setter, QQuick3DObject *newO, QObject *oldO)
static QQuick3DObjectPrivate * get(QQuick3DObject *item)
QQmlListProperty< QObject > data()
\qmltype Object3D \inqmlmodule QtQuick3D \instantiates QQuick3DObject \inherits QtObject
void setParentItem(QQuick3DObject *parentItem)
void setWindow(QQuickWindow *window)
QQuick3DSceneRenderer * renderer()
void setViewport(const QRectF &viewport)
void setVisibility(bool visible)
QQuick3DSceneRenderer * renderer
void setWindow(QQuickWindow *window)
static QQuick3DWindowAttachment * getOrSetWindowAttachment(QQuickWindow &window)
QSSGRenderPickResult syncPickOne(const QSSGRenderRay &ray, QSSGRenderNode *node)
void synchronize(QQuick3DViewport *view3D, const QSize &size, float dpr)
std::optional< QSSGRenderRay > getRayFromViewportPos(const QPointF &pos)
QQuick3DViewport * view3D()
QQuick3DNode * importScene
bool isTextureProvider() const override
Returns true if this item is a texture provider.
QQmlListProperty< QObject > data
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
void releaseResources() override
This function is called when an item should release graphics resources which are not already managed ...
QQuick3DLightmapBaker * lightmapBaker()
void processPointerEventFromRay(const QVector3D &origin, const QVector3D &direction, QPointerEvent *event)
void setGlobalPickingEnabled(bool isEnabled)
void setCamera(QQuick3DCamera *camera)
QQuickShaderEffectSource::Format renderFormat
\qmlproperty enumeration QtQuick3D::View3D::renderFormat
void environmentChanged()
void setImportScene(QQuick3DNode *inScene)
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setEnvironment(QQuick3DSceneEnvironment *environment)
~QQuick3DViewport() override
void itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) override
Called when change occurs for this item.
Q_INVOKABLE QQuick3DPickResult pick(float x, float y) const
\qmlmethod PickResult View3D::pick(float x, float y)
bool event(QEvent *) override
This virtual function receives events to an object and should return true if the event e was recogniz...
Q_INVOKABLE QVector3D mapTo3DScene(const QVector3D &viewPos) const
\qmlmethod vector3d View3D::mapTo3DScene(vector3d viewPos)
QQuick3DSceneRenderer * createRenderer() const
QSGNode * updatePaintNode(QSGNode *, UpdatePaintNodeData *) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
QSGTextureProvider * textureProvider() const override
Returns the texture provider for an item.
void importSceneChanged()
QQuick3DViewport(QQuickItem *parent=nullptr)
\qmltype View3D \inherits QQuickItem \inqmlmodule QtQuick3D
QQuick3DLightmapBaker * maybeLightmapBaker()
Q_INVOKABLE QVector3D mapFrom3DScene(const QVector3D &scenePos) const
\qmlmethod vector3d View3D::mapFrom3DScene(vector3d scenePos)
void setRenderMode(QQuick3DViewport::RenderMode renderMode)
Q_INVOKABLE void bakeLightmap()
QQuick3DRenderStats * renderStats
QQmlListProperty< QQuick3DObject > extensions
QQuick3DSceneEnvironment * environment
Q_REVISION(6, 4) void setRenderFormat(QQuickShaderEffectSource void cleanupDirectRenderer()
void releaseCachedResources()
static bool anyPointGrabbed(const QPointerEvent *ev)
void setSceneTransform(Transform *transform)
QQuickDeliveryAgent * deliveryAgent()
QSGContext * sceneGraphContext() const
static void data_append(QQmlListProperty< QObject > *, QObject *)
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
QPointF mapToScene(const QPointF &point) const
Maps the given point in this item's coordinate system to the equivalent point within the scene's coor...
bool event(QEvent *) override
\reimp
QList< QQuickItem * > childItems() const
Returns the children of this item.
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
qreal x
\qmlproperty real QtQuick::Item::x \qmlproperty real QtQuick::Item::y \qmlproperty real QtQuick::Item...
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
void setAcceptHoverEvents(bool enabled)
If enabled is true, this sets the item to accept hover events; otherwise, hover events are not accept...
qreal y
Defines the item's y position relative to its parent.
void setAcceptTouchEvents(bool accept)
If enabled is true, this sets the item to accept touch events; otherwise, touch events are not accept...
virtual QSGTextureProvider * textureProvider() const
Returns the texture provider for an item.
QRectF childrenRect()
\qmlpropertygroup QtQuick::Item::childrenRect \qmlproperty real QtQuick::Item::childrenRect....
void setAcceptedMouseButtons(Qt::MouseButtons buttons)
Sets the mouse buttons accepted by this item to buttons.
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal width
This property holds the width of this item.
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
Q_INVOKABLE void forceActiveFocus()
\qmlmethod point QtQuick::Item::mapToItem(Item item, real x, real y) \qmlmethod point QtQuick::Item::...
bool smooth
\qmlproperty bool QtQuick::Item::smooth
qreal height
This property holds the height of this item.
ItemChange
Used in conjunction with QQuickItem::itemChange() to notify the item about certain types of changes.
void update()
Schedules a call to updatePaintNode() for this item.
virtual bool isTextureProvider() const
Returns true if this item is a texture provider.
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
void sceneGraphInvalidated()
\qmlsignal QtQuick::Window::sceneGraphInitialized()
\inmodule QtCore\reentrant
bool contains(const QRectF &r) const noexcept
This is an overloaded member function, provided for convenience. It differs from the above function o...
constexpr QSizeF size() const noexcept
Returns the size of the rectangle.
\inmodule QtCore\reentrant
virtual QSize minimumFBOSize() const
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
An interface providing access to some of the graphics API specific internals of the scenegraph.
static bool isApiRhiBased(GraphicsApi api)
virtual GraphicsApi graphicsApi() const =0
Returns the graphics API that is in use by the Qt Quick scenegraph.
virtual void * getResource(QQuickWindow *window, Resource resource) const
Queries a graphics resource in window.
The QSGTextureProvider class encapsulates texture based entities in QML.
The QScreen class is used to query screen properties. \inmodule QtGui.
constexpr int height() const noexcept
Returns the height.
constexpr int width() const noexcept
Returns the width.
const T & at(qsizetype idx) const
void resize(qsizetype sz)
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr QPointF toPointF() const noexcept
Returns the QPointF form of this 2D vector.
The QVector3D class represents a vector or vertex in 3D space.
QQuick3DSceneRenderer * renderer
list append(new Employee("Blackpool", "Stephen"))
Combined button and popup list for selecting options.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
qfloat16 qSqrt(qfloat16 f)
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
constexpr static Q_DECL_CONST_FUNCTION double qt_inf() noexcept
GLsizei const GLfloat * v
[13]
GLint GLint GLint GLint GLint x
[0]
GLfloat GLfloat GLfloat w
[0]
GLint GLsizei GLsizei height
GLint GLsizei GLsizei GLenum format
GLuint GLenum GLenum transform
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
#define Q_QUICK3D_PROFILE_REGISTER(obj)
static QT_BEGIN_NAMESPACE bool isforceInputHandlingSet()
static qsizetype ssgn_count(QQmlListProperty< QObject > *property)
static QObject * ssgn_at(QQmlListProperty< QObject > *property, qsizetype i)
static void ssgn_append(QQmlListProperty< QObject > *property, QObject *obj)
static void ssgn_clear(QQmlListProperty< QObject > *property)
#define QSSG_CHECK_X(cond, msg)
#define QSSG_ASSERT(cond, action)
Q_CORE_EXPORT int qEnvironmentVariableIntValue(const char *varName, bool *ok=nullptr) noexcept
QSqlQueryModel * model
[16]
myObject disconnect()
[26]
QNetworkAccessManager manager
QSvgRenderer * renderer
[0]
QVector< QSSGRenderGraphObject * > materials
QVector3D m_localPosition
QVector3D m_scenePosition
const QSSGRenderGraphObject * m_hitObject
QVector2D m_localUVCoords
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent