summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanny Pope <daniel.pope@nokia.com>2011-09-23 11:56:20 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-23 04:01:52 +0200
commit9e694b09e7a09430838718f31ff920492adb7ed0 (patch)
treea35335187dc74156ecefeb62b395490837317873 /src
parent23b9b3b53a83587a8cad65a24a476f0fc2baff83 (diff)
QTBUG-20075 & QTBUG-18450 Item3D and Billboarding
Change-Id: I6f71bded8d7f450d929bd57bed62adac4b0e3b47 Reviewed-on: http://codereview.qt-project.org/5361 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Patrick Burke <patrick.burke@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/imports/threed/billboarditem3d.cpp170
-rw-r--r--src/imports/threed/billboarditem3d.h73
-rw-r--r--src/imports/threed/threed.cpp3
-rw-r--r--src/imports/threed/threed.pro8
-rw-r--r--src/quick3d/qdeclarativeitem3d.cpp254
-rw-r--r--src/quick3d/qdeclarativeitem3d.h17
6 files changed, 463 insertions, 62 deletions
diff --git a/src/imports/threed/billboarditem3d.cpp b/src/imports/threed/billboarditem3d.cpp
new file mode 100644
index 00000000..eb94d26f
--- /dev/null
+++ b/src/imports/threed/billboarditem3d.cpp
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "billboarditem3d.h"
+#include "qgraphicsbillboardtransform.h"
+
+/*!
+ \qmlclass BillboardItem3D BillboardItem3D
+ \brief The BillboardItem3D will always face toward the viewer.
+ \since 4.8
+ \ingroup qt3d::qml3d
+
+ Sometimes it is desirable to have objects which always face toward the
+ camera. For example, a quad with text on it may always face the camera
+ so as to be readable at all times.
+
+ While this can be achieved with a QGraphicsLookAtTransform on a normal
+ Item3D, the BillboardItem3D class provides a more efficient "cheat" which
+ takes advantage of the underlying 3D mathematics.
+
+ To use a BillboardItem3D declare it exactly like a regular Item3D. When
+ the item is drawn a QGraphicsBillboardTransform will be applied to the item
+ after all other transforms have been performed.
+
+ For example:
+
+ \code
+ Viewport {
+ BillboardItem3D {
+ mesh: Mesh { source: "model.obj" }
+ effect: Effect {
+ blending: true
+ texture: "texture.png"
+ }
+ }
+ }
+ \endcode
+
+ For a practical illustration of its use see the forest example.
+*/
+BillboardItem3D::BillboardItem3D(QObject *parent)
+ : QDeclarativeItem3D(parent)
+{
+ m_preserveUpVector = false;
+}
+
+/*!
+ \qmlproperty bool BillboardItem3D::preserveUpVector
+
+ This property specifies whether the billboard transform should
+ preserve the "up vector" so that objects stay at right angles
+ to the ground plane in the scene.
+
+ The default value for this property is false, which indicates that
+ the object being transformed should always face directly to the camera
+ This is also known as a "spherical billboard".
+
+ If the value for this property is true, then the object will have
+ its up orientation preserved. This is also known as a "cylindrical
+ billboard".
+*/
+bool BillboardItem3D::preserveUpVector() const
+{
+ return m_preserveUpVector;
+}
+
+void BillboardItem3D::setPreserveUpVector(bool value)
+{
+ m_preserveUpVector = value;
+ update();
+}
+
+/*!
+ \internal
+ This replaces the standard draw() as used in Item3D. In this instance all drawing
+ carried out using \a painter follows the standard sequence. However, after the
+ transforms for the item have been applied, a QGraphicsBillboardTransform is applied
+ to the model-view matrix.
+
+ After the current item is drawn the model-view matrix from immediately before the
+ billboard transform being applied will be restored so child items are not affected by it.
+*/
+void BillboardItem3D::draw(QGLPainter *painter)
+{
+ // Bail out if this item and its children have been disabled.
+ if (!isEnabled())
+ return;
+ if (!isInitialized())
+ initialize(painter);
+
+ //Setup picking
+ int prevId = painter->objectPickId();
+ painter->setObjectPickId(objectPickId());
+
+ //Setup effect (lighting, culling, effects etc)
+ const QGLLightParameters *currentLight = 0;
+ QMatrix4x4 currentLightTransform;
+ drawLightingSetup(painter, currentLight, currentLightTransform);
+ bool viewportBlend, effectBlend;
+ drawEffectSetup(painter, viewportBlend, effectBlend);
+ drawCullSetup();
+
+ //Local and Global transforms
+ drawTransformSetup(painter);
+
+ //After all of the other transforms, apply the billboard transform to
+ //ensure forward facing.
+ painter->modelViewMatrix().push();
+ QGraphicsBillboardTransform bill;
+ bill.setPreserveUpVector(m_preserveUpVector);
+ bill.applyTo(const_cast<QMatrix4x4 *>(&painter->modelViewMatrix().top()));
+
+ //Drawing
+ drawItem(painter);
+
+ //Pop the billboard transform from the model-view matrix stack so that it
+ //is not applied to child items.
+ painter->modelViewMatrix().pop();
+
+ //Draw children
+ drawChildren(painter);
+
+ //Cleanup
+ drawTransformCleanup(painter);
+ drawLightingCleanup(painter, currentLight, currentLightTransform);
+ drawEffectCleanup(painter, viewportBlend, effectBlend);
+ drawCullCleanup();
+
+ //Reset pick id.
+ painter->setObjectPickId(prevId);
+}
+
diff --git a/src/imports/threed/billboarditem3d.h b/src/imports/threed/billboarditem3d.h
new file mode 100644
index 00000000..ae533201
--- /dev/null
+++ b/src/imports/threed/billboarditem3d.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BILLBOARDITEM3D_H
+#define BILLBOARDITEM3D_H
+
+#include "qdeclarativeitem3d.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class BillboardItem3D : public QDeclarativeItem3D
+{
+ Q_OBJECT
+ Q_PROPERTY(bool preserveUpVector READ preserveUpVector WRITE setPreserveUpVector)
+public:
+ BillboardItem3D(QObject *parent = 0);
+
+ bool preserveUpVector() const;
+ void setPreserveUpVector(bool value);
+
+ void draw(QGLPainter *painter);
+
+private:
+ bool m_preserveUpVector;
+};
+
+QML_DECLARE_TYPE(BillboardItem3D)
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // BILLBOARDITEM3D_H
diff --git a/src/imports/threed/threed.cpp b/src/imports/threed/threed.cpp
index a528fbc0..5faf87f0 100644
--- a/src/imports/threed/threed.cpp
+++ b/src/imports/threed/threed.cpp
@@ -61,6 +61,8 @@
#include "shaderprogram.h"
#include "qt3dnamespace.h"
+#include "billboarditem3d.h"
+
QT_BEGIN_NAMESPACE
QML_DECLARE_TYPE(QGraphicsTransform3D)
@@ -96,6 +98,7 @@ public:
qmlRegisterType<QGLMaterial>(uri,1,0,"Material");
qmlRegisterType<ShaderProgram>(uri,1,0,"ShaderProgram");
qmlRegisterType<Skybox>(uri, 1, 0, "Skybox");
+ qmlRegisterType<BillboardItem3D>(uri, 1, 0, "BillboardItem3D");
qmlRegisterType<Viewport>(uri,1,0,"Viewport");
diff --git a/src/imports/threed/threed.pro b/src/imports/threed/threed.pro
index a8f20f23..3648dfbc 100644
--- a/src/imports/threed/threed.pro
+++ b/src/imports/threed/threed.pro
@@ -35,7 +35,8 @@ SOURCES += \
viewport.cpp \
qgraphicslookattransform.cpp \
shaderprogram.cpp \
- skybox.cpp
+ skybox.cpp \
+ billboarditem3d.cpp
HEADERS += \
qt3dnamespace.h \
@@ -44,7 +45,8 @@ HEADERS += \
qgraphicslookattransform.h \
shaderprogram.h \
shaderprogram_p.h \
- skybox.h
+ skybox.h \
+ billboarditem3d.h
# See the file README.library_xml for more on this
qdeclarativesources.files += \
@@ -73,3 +75,5 @@ qdeclarativesources.files += \
OTHER_FILES += \
README.plugins_types \
README.library_xml
+
+
diff --git a/src/quick3d/qdeclarativeitem3d.cpp b/src/quick3d/qdeclarativeitem3d.cpp
index 8b1c8dbe..97a8f4e1 100644
--- a/src/quick3d/qdeclarativeitem3d.cpp
+++ b/src/quick3d/qdeclarativeitem3d.cpp
@@ -1014,47 +1014,91 @@ void QDeclarativeItem3D::setSortChildren(QDeclarativeItem3D::SortMode mode)
/*!
\internal
- Performs the actual drawing of the Item3D using \a painter.
-
- If the item is set to object picking mode this includes all of the infrastructure needed
- to support picking of objects.
-
- The basic premise of the draw function should be familiar to users of OpenGL or similar
- graphics libraries. Essentially it is a stepwise progress through the following stages:
+ Sets the lighting conditions for this item on the \a painter. The parameters \a currentLight and \a currentLightTransform
+ are used to store the current lighting parameters and transforms so that they can be reset on cleanup.
- \list
- \i 1. Iterate through the child objects of the item and set all lighting parameters found.
- \i 2. Set up culling mode in the painter.
- \i 3. Set effects if they exist.
- \i 4. Set all local model view transformations for this item.
- \i 5. Draw this item.
- \i 6. Iterate through the child objects of the item and draw all child items.
- \i 7. Unset the appropriate parameters and states.
- \endlist
+ After drawing has finished the drawLightingCleanup() function should be called to restore previous settings.
- \sa drawItem()
+ \sa drawLightingCleanup(), draw()
*/
-
-void QDeclarativeItem3D::draw(QGLPainter *painter)
+void QDeclarativeItem3D::drawLightingSetup(QGLPainter *painter, const QGLLightParameters *currentLight, QMatrix4x4 &currentLightTransform)
{
- // Bail out if this item and its children have been disabled.
- if (!d->isEnabled)
- return;
- if (!d->isInitialized)
- initialize(painter);
-
- int prevId = painter->objectPickId();
- painter->setObjectPickId(d->objectPickId);
-
//Lighting
- const QGLLightParameters *currentLight = 0;
- QMatrix4x4 currentLightTransform;
if (d->light) {
currentLight = painter->mainLight();
currentLightTransform = painter->mainLightTransform();
painter->setMainLight(d->light);
}
+}
+
+/*!
+ \internal
+ Restores the lighting conditions for \a painter to the \a currentLight and \a currentLightTransform. These values are usually
+ provided by an earlier call to drawLightingSetup().
+
+ \sa drawLightingSetup(), draw()
+*/
+void QDeclarativeItem3D::drawLightingCleanup(QGLPainter *painter, const QGLLightParameters *currentLight, QMatrix4x4 &currentLightTransform)
+{
+ if (d->light)
+ painter->setMainLight(currentLight, currentLightTransform);
+}
+
+/*!
+ \internal
+ Sets the effects for this item on the \a painter. The parameters \a viewportBlend and \a effectBlend
+ are used to store the current blending parameters so that they can be reset on cleanup.
+ After drawing has finished the drawEffectCleanup() function should be called to restore previous settings.
+
+ \sa drawLightingCleanup(), draw()
+*/
+void QDeclarativeItem3D::drawEffectSetup(QGLPainter *painter, bool &viewportBlend, bool &effectBlend)
+{
+ // Blending change for the effect.
+ viewportBlend = d->viewport ? d->viewport->blending() : false;
+ effectBlend = d->effect ? d->effect->blending() : viewportBlend;
+ if (viewportBlend != effectBlend) {
+ if (effectBlend)
+ glEnable(GL_BLEND);
+ else
+ glDisable(GL_BLEND);
+ }
+
+ //Effects
+ if (d->effect)
+ d->effect->enableEffect(painter);
+}
+
+/*!
+ \internal
+ Restores the blending settings for \a painter to the \a viewportBlend and \a effectBlend. These values are usually
+ provided by an earlier call to drawEffectSetup().
+
+ \sa drawEffectSetup(), draw()
+*/
+void QDeclarativeItem3D::drawEffectCleanup(QGLPainter *painter, bool &viewportBlend, bool &effectBlend)
+{
+ if (d->effect)
+ d->effect->disableEffect(painter);
+ if (viewportBlend != effectBlend) {
+ if (effectBlend)
+ glDisable(GL_BLEND);
+ else
+ glEnable(GL_BLEND);
+ }
+}
+
+/*!
+ \internal
+ Sets the culling settings for this item.
+
+ After drawing has finished the drawCullCleanup() function should be called to restore previous settings.
+
+ \sa drawCullCleanup(), draw()
+*/
+void QDeclarativeItem3D::drawCullSetup()
+{
//Culling
if ((d->cullFaces & ~CullClockwise) == CullDisabled) {
glDisable(GL_CULL_FACE);
@@ -1067,30 +1111,57 @@ void QDeclarativeItem3D::draw(QGLPainter *painter)
glCullFace(GLenum(d->cullFaces));
glEnable(GL_CULL_FACE);
}
+}
- // Blending change for the effect.
- bool viewportBlend = d->viewport ? d->viewport->blending() : false;
- bool effectBlend = d->effect ? d->effect->blending() : viewportBlend;
- if (viewportBlend != effectBlend) {
- if (effectBlend)
- glEnable(GL_BLEND);
- else
- glDisable(GL_BLEND);
- }
+/*!
+ \internal
+ Restores the culling settings after an earlier call to drawCullSetup().
- //Effects
- if (d->effect)
- d->effect->enableEffect(painter);
+ \sa drawCullSetup(), draw()
+*/
+void QDeclarativeItem3D::drawCullCleanup()
+{
+ if (d->cullFaces != CullDisabled)
+ glDisable(GL_CULL_FACE);
+}
- //Local and Global transforms
+/*!
+ \internal
+ Applies the transforms for this item on the \a painter.
+
+ After drawing has finished the drawTransformCleanup() function should be called to restore previous settings.
- //1) Item Transforms
+ \sa drawTransformCleanup(), draw()
+*/
+void QDeclarativeItem3D::drawTransformSetup(QGLPainter *painter)
+{
+ //Local and Global transforms
painter->modelViewMatrix().push();
painter->modelViewMatrix() *= d->localTransforms();
+}
- //Drawing
- drawItem(painter);
+/*!
+ \internal
+ Restores the previous model-view matrix settings for \a painter after an earlier call to drawTransformSetup().
+
+ \sa drawTransformSetup(), draw()
+*/
+void QDeclarativeItem3D::drawTransformCleanup(QGLPainter *painter)
+{
+ //Unset parameters for transforms, effects etc.
+ painter->modelViewMatrix().pop();
+}
+
+/*!
+ \internal
+ Iterate through all of the child items for the current item and call their drawing functions. Children will
+ be drawn in the order specified unless specified by sortChildren(), in which case they will be drawn in the
+ order specified (usually this will be back-to-front, to allow for transparency of objects).
+ \sa sortMode(), draw()
+*/
+void QDeclarativeItem3D::drawChildren(QGLPainter *painter)
+{
// Find all 3d children for drawing
QList<QDeclarativeItem3D *> list;;
foreach (QObject* o, children())
@@ -1122,22 +1193,66 @@ void QDeclarativeItem3D::draw(QGLPainter *painter)
}
for (int index = 0; index < list.size(); ++index)
list.at(index)->draw(painter);
+}
- //Unset parameters for transforms, effects etc.
- painter->modelViewMatrix().pop();
+/*!
+ \internal
+ Performs the actual drawing of the Item3D using \a painter.
- if (d->effect)
- d->effect->disableEffect(painter);
- if (viewportBlend != effectBlend) {
- if (effectBlend)
- glDisable(GL_BLEND);
- else
- glEnable(GL_BLEND);
- }
- if (d->cullFaces != CullDisabled)
- glDisable(GL_CULL_FACE);
- if (d->light)
- painter->setMainLight(currentLight, currentLightTransform);
+ If the item is set to object picking mode this includes all of the infrastructure needed
+ to support picking of objects.
+
+ The basic premise of the draw function should be familiar to users of OpenGL or similar
+ graphics libraries. Essentially it is a stepwise progress through the following stages:
+
+ \list
+ \i 1. Iterate through the child objects of the item and set all lighting parameters found.
+ \i 2. Set up culling mode in the painter.
+ \i 3. Set effects if they exist.
+ \i 4. Set all local model view transformations for this item.
+ \i 5. Draw this item.
+ \i 6. Iterate through the child objects of the item and draw all child items.
+ \i 7. Unset the appropriate parameters and states.
+ \endlist
+
+
+
+ \sa drawItem(), drawLightingSetup(), drawCullSetup(), drawEffectSetup(), drawChildren(), drawTransformSetup()
+*/
+void QDeclarativeItem3D::draw(QGLPainter *painter)
+{
+ // Bail out if this item and its children have been disabled.
+ if (!d->isEnabled)
+ return;
+ if (!d->isInitialized)
+ initialize(painter);
+
+ //Setup picking
+ int prevId = painter->objectPickId();
+ painter->setObjectPickId(d->objectPickId);
+
+ //Setup effect (lighting, culling, effects etc)
+ const QGLLightParameters *currentLight = 0;
+ QMatrix4x4 currentLightTransform;
+ drawLightingSetup(painter, currentLight, currentLightTransform);
+ bool viewportBlend, effectBlend;
+ drawEffectSetup(painter, viewportBlend, effectBlend);
+ drawCullSetup();
+
+ //Local and Global transforms
+ drawTransformSetup(painter);
+
+ //Drawing
+ drawItem(painter);
+ drawChildren(painter);
+
+ //Cleanup
+ drawTransformCleanup(painter);
+ drawLightingCleanup(painter, currentLight, currentLightTransform);
+ drawEffectCleanup(painter, viewportBlend, effectBlend);
+ drawCullCleanup();
+
+ //Reset pick id.
painter->setObjectPickId(prevId);
}
@@ -1204,6 +1319,17 @@ void QDeclarativeItem3D::initialize(QGLPainter *painter)
d->isInitialized = true;
}
+/*!
+ Returns true if the initialize() has been called, returns false otherwise.
+
+ \sa initialize()
+*/
+bool QDeclarativeItem3D::isInitialized() const
+{
+ return d->isInitialized;
+}
+
+
void QDeclarativeItem3D::componentComplete()
{
QDeclarativeItem::componentComplete();
@@ -1428,6 +1554,14 @@ void QDeclarativeItem3D::setEnabled(bool value)
}
/*!
+ Returns the unique pick ID for this item.
+*/
+int QDeclarativeItem3D::objectPickId() const
+{
+ return d->objectPickId;
+}
+
+/*!
\qmlsignal Item3D::onClicked()
This signal is emitted when the item is clicked. Picking must be enabled for this to have any effect.
diff --git a/src/quick3d/qdeclarativeitem3d.h b/src/quick3d/qdeclarativeitem3d.h
index 5a490530..edd228e6 100644
--- a/src/quick3d/qdeclarativeitem3d.h
+++ b/src/quick3d/qdeclarativeitem3d.h
@@ -155,17 +155,34 @@ public:
virtual void draw(QGLPainter *painter);
virtual void initialize(QGLPainter *painter);
+ bool isInitialized() const;
Q_INVOKABLE QVector3D localToWorld(const QVector3D &point = QVector3D()) const;
Q_INVOKABLE QVector3D worldToLocal(const QVector3D &point = QVector3D()) const;
void componentComplete();
+ int objectPickId() const;
+
public Q_SLOTS:
void update();
protected:
+ virtual void drawLightingSetup(QGLPainter *painter, const QGLLightParameters *currentLight, QMatrix4x4 &currentLightTransform);
+ virtual void drawLightingCleanup(QGLPainter *painter, const QGLLightParameters *currentLight, QMatrix4x4 &currentLightTransform);
+
+ virtual void drawCullSetup();
+ virtual void drawCullCleanup();
+
+ virtual void drawEffectSetup(QGLPainter *painter, bool &viewportBlend, bool &effectBlend);
+ virtual void drawEffectCleanup(QGLPainter *painter, bool &viewportBlend, bool &effectBlend);
+
+ virtual void drawChildren(QGLPainter *painter);
virtual void drawItem(QGLPainter *painter);
+
+ virtual void drawTransformSetup(QGLPainter *painter);
+ virtual void drawTransformCleanup(QGLPainter *painter);
+
bool event(QEvent *e);
private Q_SLOTS: