summaryrefslogtreecommitdiffstats
path: root/src/extras
diff options
context:
space:
mode:
Diffstat (limited to 'src/extras')
-rw-r--r--src/extras/defaults/defaults.pri39
-rw-r--r--src/extras/defaults/qdiffusemapmaterial.cpp316
-rw-r--r--src/extras/defaults/qdiffusemapmaterial.h100
-rw-r--r--src/extras/defaults/qdiffusemapmaterial_p.h111
-rw-r--r--src/extras/defaults/qdiffusespecularmapmaterial.cpp330
-rw-r--r--src/extras/defaults/qdiffusespecularmapmaterial.h99
-rw-r--r--src/extras/defaults/qdiffusespecularmapmaterial_p.h114
-rw-r--r--src/extras/defaults/qforwardrenderer.cpp197
-rw-r--r--src/extras/defaults/qforwardrenderer.h92
-rw-r--r--src/extras/defaults/qforwardrenderer_p.h92
-rw-r--r--src/extras/defaults/qgoochmaterial.cpp358
-rw-r--r--src/extras/defaults/qgoochmaterial.h102
-rw-r--r--src/extras/defaults/qgoochmaterial_p.h107
-rw-r--r--src/extras/defaults/qnormaldiffusemapalphamaterial.cpp173
-rw-r--r--src/extras/defaults/qnormaldiffusemapalphamaterial.h67
-rw-r--r--src/extras/defaults/qnormaldiffusemapalphamaterial_p.h87
-rw-r--r--src/extras/defaults/qnormaldiffusemapmaterial.cpp363
-rw-r--r--src/extras/defaults/qnormaldiffusemapmaterial.h107
-rw-r--r--src/extras/defaults/qnormaldiffusemapmaterial_p.h115
-rw-r--r--src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp379
-rw-r--r--src/extras/defaults/qnormaldiffusespecularmapmaterial.h101
-rw-r--r--src/extras/defaults/qnormaldiffusespecularmapmaterial_p.h116
-rw-r--r--src/extras/defaults/qpervertexcolormaterial.cpp163
-rw-r--r--src/extras/defaults/qpervertexcolormaterial.h69
-rw-r--r--src/extras/defaults/qpervertexcolormaterial_p.h99
-rw-r--r--src/extras/defaults/qphongalphamaterial.cpp327
-rw-r--r--src/extras/defaults/qphongalphamaterial.h94
-rw-r--r--src/extras/defaults/qphongalphamaterial_p.h116
-rw-r--r--src/extras/defaults/qphongmaterial.cpp275
-rw-r--r--src/extras/defaults/qphongmaterial.h90
-rw-r--r--src/extras/defaults/qphongmaterial_p.h108
-rw-r--r--src/extras/defaults/qskyboxentity.cpp293
-rw-r--r--src/extras/defaults/qskyboxentity.h81
-rw-r--r--src/extras/defaults/qskyboxentity_p.h122
-rw-r--r--src/extras/extras.pro16
-rw-r--r--src/extras/extras.qrc43
-rw-r--r--src/extras/geometries/geometries.pri35
-rw-r--r--src/extras/geometries/qconegeometry.cpp589
-rw-r--r--src/extras/geometries/qconegeometry.h120
-rw-r--r--src/extras/geometries/qconegeometry_p.h97
-rw-r--r--src/extras/geometries/qconemesh.cpp148
-rw-r--r--src/extras/geometries/qconemesh.h108
-rw-r--r--src/extras/geometries/qcuboidgeometry.cpp827
-rw-r--r--src/extras/geometries/qcuboidgeometry.h122
-rw-r--r--src/extras/geometries/qcuboidgeometry_p.h100
-rw-r--r--src/extras/geometries/qcuboidmesh.cpp215
-rw-r--r--src/extras/geometries/qcuboidmesh.h108
-rw-r--r--src/extras/geometries/qcylindergeometry.cpp585
-rw-r--r--src/extras/geometries/qcylindergeometry.h109
-rw-r--r--src/extras/geometries/qcylindergeometry_p.h93
-rw-r--r--src/extras/geometries/qcylindermesh.cpp184
-rw-r--r--src/extras/geometries/qcylindermesh.h97
-rw-r--r--src/extras/geometries/qplanegeometry.cpp529
-rw-r--r--src/extras/geometries/qplanegeometry.h109
-rw-r--r--src/extras/geometries/qplanegeometry_p.h93
-rw-r--r--src/extras/geometries/qplanemesh.cpp149
-rw-r--r--src/extras/geometries/qplanemesh.h94
-rw-r--r--src/extras/geometries/qspheregeometry.cpp584
-rw-r--r--src/extras/geometries/qspheregeometry.h112
-rw-r--r--src/extras/geometries/qspheregeometry_p.h93
-rw-r--r--src/extras/geometries/qspheremesh.cpp172
-rw-r--r--src/extras/geometries/qspheremesh.h98
-rw-r--r--src/extras/geometries/qtorusgeometry.cpp511
-rw-r--r--src/extras/geometries/qtorusgeometry.h111
-rw-r--r--src/extras/geometries/qtorusgeometry_p.h93
-rw-r--r--src/extras/geometries/qtorusmesh.cpp177
-rw-r--r--src/extras/geometries/qtorusmesh.h96
-rw-r--r--src/extras/qt3dextras_global.h59
-rw-r--r--src/extras/shaders/es2/diffusemap.frag25
-rw-r--r--src/extras/shaders/es2/diffusemap.vert22
-rw-r--r--src/extras/shaders/es2/diffusespecularmap.frag27
-rw-r--r--src/extras/shaders/es2/gooch.frag56
-rw-r--r--src/extras/shaders/es2/gooch.vert17
-rw-r--r--src/extras/shaders/es2/light.inc.frag131
-rw-r--r--src/extras/shaders/es2/light.inc.frag100218
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.frag31
-rw-r--r--src/extras/shaders/es2/normaldiffusemap.vert38
-rw-r--r--src/extras/shaders/es2/normaldiffusemapalpha.frag32
-rw-r--r--src/extras/shaders/es2/normaldiffusespecularmap.frag32
-rw-r--r--src/extras/shaders/es2/pervertexcolor.frag14
-rw-r--r--src/extras/shaders/es2/pervertexcolor.vert20
-rw-r--r--src/extras/shaders/es2/phong.frag20
-rw-r--r--src/extras/shaders/es2/phong.vert17
-rw-r--r--src/extras/shaders/es2/phongalpha.frag22
-rw-r--r--src/extras/shaders/es2/skybox.frag8
-rw-r--r--src/extras/shaders/es2/skybox.vert12
-rw-r--r--src/extras/shaders/es2/unlittexture.frag11
-rw-r--r--src/extras/shaders/es2/unlittexture.vert17
-rw-r--r--src/extras/shaders/gl3/diffusemap.frag27
-rw-r--r--src/extras/shaders/gl3/diffusemap.vert24
-rw-r--r--src/extras/shaders/gl3/diffusespecularmap.frag29
-rw-r--r--src/extras/shaders/gl3/gooch.frag64
-rw-r--r--src/extras/shaders/gl3/gooch.vert19
-rw-r--r--src/extras/shaders/gl3/light.inc.frag131
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.frag33
-rw-r--r--src/extras/shaders/gl3/normaldiffusemap.vert39
-rw-r--r--src/extras/shaders/gl3/normaldiffusemapalpha.frag34
-rw-r--r--src/extras/shaders/gl3/normaldiffusespecularmap.frag34
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.frag16
-rw-r--r--src/extras/shaders/gl3/pervertexcolor.vert22
-rw-r--r--src/extras/shaders/gl3/phong.frag22
-rw-r--r--src/extras/shaders/gl3/phong.vert19
-rw-r--r--src/extras/shaders/gl3/phongalpha.frag24
-rw-r--r--src/extras/shaders/gl3/skybox.frag10
-rw-r--r--src/extras/shaders/gl3/skybox.vert14
-rw-r--r--src/extras/shaders/gl3/unlittexture.frag13
-rw-r--r--src/extras/shaders/gl3/unlittexture.vert19
107 files changed, 13441 insertions, 0 deletions
diff --git a/src/extras/defaults/defaults.pri b/src/extras/defaults/defaults.pri
new file mode 100644
index 000000000..1560f55ec
--- /dev/null
+++ b/src/extras/defaults/defaults.pri
@@ -0,0 +1,39 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qphongmaterial.h \
+ $$PWD/qphongmaterial_p.h \
+ $$PWD/qdiffusemapmaterial_p.h \
+ $$PWD/qdiffusemapmaterial.h \
+ $$PWD/qnormaldiffusespecularmapmaterial.h \
+ $$PWD/qnormaldiffusespecularmapmaterial_p.h \
+ $$PWD/qnormaldiffusemapmaterial.h \
+ $$PWD/qnormaldiffusemapmaterial_p.h \
+ $$PWD/qnormaldiffusemapalphamaterial.h \
+ $$PWD/qnormaldiffusemapalphamaterial_p.h \
+ $$PWD/qdiffusespecularmapmaterial.h \
+ $$PWD/qdiffusespecularmapmaterial_p.h \
+ $$PWD/qforwardrenderer.h \
+ $$PWD/qforwardrenderer_p.h \
+ $$PWD/qpervertexcolormaterial.h \
+ $$PWD/qpervertexcolormaterial_p.h \
+ $$PWD/qskyboxentity.h \
+ $$PWD/qskyboxentity_p.h \
+ $$PWD/qgoochmaterial.h \
+ $$PWD/qgoochmaterial_p.h \
+ $$PWD/qphongalphamaterial.h \
+ $$PWD/qphongalphamaterial_p.h
+
+SOURCES += \
+ $$PWD/qphongmaterial.cpp \
+ $$PWD/qdiffusemapmaterial.cpp \
+ $$PWD/qnormaldiffusespecularmapmaterial.cpp \
+ $$PWD/qnormaldiffusemapmaterial.cpp \
+ $$PWD/qnormaldiffusemapalphamaterial.cpp \
+ $$PWD/qdiffusespecularmapmaterial.cpp \
+ $$PWD/qforwardrenderer.cpp \
+ $$PWD/qpervertexcolormaterial.cpp \
+ $$PWD/qskyboxentity.cpp \
+ $$PWD/qgoochmaterial.cpp \
+ $$PWD/qphongalphamaterial.cpp
+
diff --git a/src/extras/defaults/qdiffusemapmaterial.cpp b/src/extras/defaults/qdiffusemapmaterial.cpp
new file mode 100644
index 000000000..854d0a809
--- /dev/null
+++ b/src/extras/defaults/qdiffusemapmaterial.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdiffusemapmaterial.h"
+#include "qdiffusemapmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QDiffuseMapMaterialPrivate::QDiffuseMapMaterialPrivate()
+ : QMaterialPrivate()
+ , m_diffuseMapEffect(new QEffect())
+ , m_diffuseTexture(new QTexture2D())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("diffuseTexture"), m_diffuseTexture))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
+ , m_diffuseMapGL3Technique(new QTechnique())
+ , m_diffuseMapGL2Technique(new QTechnique())
+ , m_diffuseMapES2Technique(new QTechnique())
+ , m_diffuseMapGL3RenderPass(new QRenderPass())
+ , m_diffuseMapGL2RenderPass(new QRenderPass())
+ , m_diffuseMapES2RenderPass(new QRenderPass())
+ , m_diffuseMapGL3Shader(new QShaderProgram())
+ , m_diffuseMapGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+ m_diffuseTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_diffuseTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_diffuseTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_diffuseTexture->setGenerateMipMaps(true);
+ m_diffuseTexture->setMaximumAnisotropy(16.0f);
+}
+
+void QDiffuseMapMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseMapMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseMapMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseMapMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseMapMaterialPrivate::handleShininessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseMapMaterialPrivate::handleTextureScaleChanged);
+
+ m_diffuseMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.frag"))));
+ m_diffuseMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.frag"))));
+
+ m_diffuseMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_diffuseMapGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_diffuseMapGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_diffuseMapGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_diffuseMapGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_diffuseMapGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_diffuseMapGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_diffuseMapGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_diffuseMapES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_diffuseMapES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_diffuseMapES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_diffuseMapES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QDiffuseMapMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_diffuseMapGL3Technique->addFilterKey(m_filterKey);
+ m_diffuseMapGL2Technique->addFilterKey(m_filterKey);
+ m_diffuseMapES2Technique->addFilterKey(m_filterKey);
+
+ m_diffuseMapGL3RenderPass->setShaderProgram(m_diffuseMapGL3Shader);
+ m_diffuseMapGL2RenderPass->setShaderProgram(m_diffuseMapGL2ES2Shader);
+ m_diffuseMapES2RenderPass->setShaderProgram(m_diffuseMapGL2ES2Shader);
+
+ m_diffuseMapGL3Technique->addRenderPass(m_diffuseMapGL3RenderPass);
+ m_diffuseMapGL2Technique->addRenderPass(m_diffuseMapGL2RenderPass);
+ m_diffuseMapES2Technique->addRenderPass(m_diffuseMapES2RenderPass);
+
+ m_diffuseMapEffect->addTechnique(m_diffuseMapGL3Technique);
+ m_diffuseMapEffect->addTechnique(m_diffuseMapGL2Technique);
+ m_diffuseMapEffect->addTechnique(m_diffuseMapES2Technique);
+
+ m_diffuseMapEffect->addParameter(m_ambientParameter);
+ m_diffuseMapEffect->addParameter(m_diffuseParameter);
+ m_diffuseMapEffect->addParameter(m_specularParameter);
+ m_diffuseMapEffect->addParameter(m_shininessParameter);
+ m_diffuseMapEffect->addParameter(m_textureScaleParameter);
+
+ q->setEffect(m_diffuseMapEffect);
+}
+
+void QDiffuseMapMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseMapMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QDiffuseMapMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseMapMaterial);
+ emit q->diffuseChanged(var.value<QAbstractTexture *>());
+}
+
+void QDiffuseMapMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseMapMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QDiffuseMapMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseMapMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QDiffuseMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseMapMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QDiffuseMapMaterial
+ \brief The QDiffuseMapMaterial provides a default implementation of the phong lighting effect where the diffuse light component
+ is read from a texture map.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new Qt3DRender::QDiffuseMapMaterial instance with parent object \a parent.
+ */
+QDiffuseMapMaterial::QDiffuseMapMaterial(QNode *parent)
+ : QMaterial(*new QDiffuseMapMaterialPrivate, parent)
+{
+ Q_D(QDiffuseMapMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QDiffuseMapMaterial instance.
+*/
+QDiffuseMapMaterial::~QDiffuseMapMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QDiffuseMapMaterial::ambient
+
+ Holds the current ambient color.
+*/
+
+QColor QDiffuseMapMaterial::ambient() const
+{
+ Q_D(const QDiffuseMapMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseMapMaterial::specular
+
+ Holds the current specular color.
+*/
+QColor QDiffuseMapMaterial::specular() const
+{
+ Q_D(const QDiffuseMapMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseMapMaterial::shininess
+
+ Holds the current shininess as a float value.
+*/
+float QDiffuseMapMaterial::shininess() const
+{
+ Q_D(const QDiffuseMapMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseMapMaterial::diffuse
+
+ Holds the current QTexture used as the diffuse map.
+
+ By default, the diffuse texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QDiffuseMapMaterial::diffuse() const
+{
+ Q_D(const QDiffuseMapMaterial);
+ return d->m_diffuseParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseMapMaterial::textureScale
+
+ Holds the current texture scale as a float value.
+
+*/
+float QDiffuseMapMaterial::textureScale() const
+{
+ Q_D(const QDiffuseMapMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
+void QDiffuseMapMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(const QDiffuseMapMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QDiffuseMapMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QDiffuseMapMaterial);
+ d->m_specularParameter->setValue(specular);
+}
+
+void QDiffuseMapMaterial::setShininess(float shininess)
+{
+ Q_D(QDiffuseMapMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QDiffuseMapMaterial::setDiffuse(QAbstractTexture *diffuseMap)
+{
+ Q_D(QDiffuseMapMaterial);
+ d->m_diffuseParameter->setValue(QVariant::fromValue(diffuseMap));
+}
+
+void QDiffuseMapMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QDiffuseMapMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qdiffusemapmaterial.h b/src/extras/defaults/qdiffusemapmaterial.h
new file mode 100644
index 000000000..a0e6a88cf
--- /dev/null
+++ b/src/extras/defaults/qdiffusemapmaterial.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QDIFFUSEMAPMATERIAL_H
+#define QT3DEXTRAS_QDIFFUSEMAPMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAbstractTexture;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QDiffuseMapMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QDiffuseMapMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged)
+
+public:
+ explicit QDiffuseMapMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QDiffuseMapMaterial();
+
+ QColor ambient() const;
+ QColor specular() const;
+ float shininess() const;
+ Qt3DRender::QAbstractTexture *diffuse() const;
+ float textureScale() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &color);
+ void setSpecular(const QColor &specular);
+ void setShininess(float shininess);
+ void setDiffuse(Qt3DRender::QAbstractTexture *diffuse);
+ void setTextureScale(float textureScale);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(Qt3DRender::QAbstractTexture *diffuse);
+ void specularChanged(const QColor &specular);
+ void shininessChanged(float shininess);
+ void textureScaleChanged(float textureScale);
+
+private:
+ Q_DECLARE_PRIVATE(QDiffuseMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRASQDIFFUSEMAPMATERIAL_H
diff --git a/src/extras/defaults/qdiffusemapmaterial_p.h b/src/extras/defaults/qdiffusemapmaterial_p.h
new file mode 100644
index 000000000..c0bcc01eb
--- /dev/null
+++ b/src/extras/defaults/qdiffusemapmaterial_p.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QDIFFUSEMAPMATERIAL_P_H
+#define QT3DEXTRAS_QDIFFUSEMAPMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QAbstractTexture;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QDiffuseMapMaterial;
+
+class QDiffuseMapMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+ QDiffuseMapMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleTextureScaleChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_diffuseMapEffect;
+ Qt3DRender::QAbstractTexture *m_diffuseTexture;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
+ Qt3DRender::QTechnique *m_diffuseMapGL3Technique;
+ Qt3DRender::QTechnique *m_diffuseMapGL2Technique;
+ Qt3DRender::QTechnique *m_diffuseMapES2Technique;
+ Qt3DRender::QRenderPass *m_diffuseMapGL3RenderPass;
+ Qt3DRender::QRenderPass *m_diffuseMapGL2RenderPass;
+ Qt3DRender::QRenderPass *m_diffuseMapES2RenderPass;
+ Qt3DRender::QShaderProgram *m_diffuseMapGL3Shader;
+ Qt3DRender::QShaderProgram *m_diffuseMapGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QDiffuseMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QDIFFUSEAPMATERIAL_P_H
+
diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.cpp b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
new file mode 100644
index 000000000..a4ccb6121
--- /dev/null
+++ b/src/extras/defaults/qdiffusespecularmapmaterial.cpp
@@ -0,0 +1,330 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdiffusespecularmapmaterial.h"
+#include "qdiffusespecularmapmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QDiffuseSpecularMapMaterialPrivate::QDiffuseSpecularMapMaterialPrivate()
+ : QMaterialPrivate()
+ , m_diffuseSpecularMapEffect(new QEffect())
+ , m_diffuseTexture(new QTexture2D())
+ , m_specularTexture(new QTexture2D())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("diffuseTexture"), m_diffuseTexture))
+ , m_specularParameter(new QParameter(QStringLiteral("specularTexture"), m_specularTexture))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
+ , m_diffuseSpecularMapGL3Technique(new QTechnique())
+ , m_diffuseSpecularMapGL2Technique(new QTechnique())
+ , m_diffuseSpecularMapES2Technique(new QTechnique())
+ , m_diffuseSpecularMapGL3RenderPass(new QRenderPass())
+ , m_diffuseSpecularMapGL2RenderPass(new QRenderPass())
+ , m_diffuseSpecularMapES2RenderPass(new QRenderPass())
+ , m_diffuseSpecularMapGL3Shader(new QShaderProgram())
+ , m_diffuseSpecularMapGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+ m_diffuseTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_diffuseTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_diffuseTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_diffuseTexture->setGenerateMipMaps(true);
+ m_diffuseTexture->setMaximumAnisotropy(16.0f);
+
+ m_specularTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_specularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_specularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_specularTexture->setGenerateMipMaps(true);
+ m_specularTexture->setMaximumAnisotropy(16.0f);
+}
+
+void QDiffuseSpecularMapMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseSpecularMapMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseSpecularMapMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseSpecularMapMaterialPrivate::handleShininessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
+
+ m_diffuseSpecularMapGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusemap.vert"))));
+ m_diffuseSpecularMapGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/diffusespecularmap.frag"))));
+ m_diffuseSpecularMapGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusemap.vert"))));
+ m_diffuseSpecularMapGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/diffusespecularmap.frag"))));
+
+ m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_diffuseSpecularMapGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_diffuseSpecularMapGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_diffuseSpecularMapGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_diffuseSpecularMapGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_diffuseSpecularMapGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_diffuseSpecularMapES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_diffuseSpecularMapES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_diffuseSpecularMapES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_diffuseSpecularMapES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QDiffuseSpecularMapMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_diffuseSpecularMapGL3Technique->addFilterKey(m_filterKey);
+ m_diffuseSpecularMapGL2Technique->addFilterKey(m_filterKey);
+ m_diffuseSpecularMapES2Technique->addFilterKey(m_filterKey);
+
+ m_diffuseSpecularMapGL3RenderPass->setShaderProgram(m_diffuseSpecularMapGL3Shader);
+ m_diffuseSpecularMapGL2RenderPass->setShaderProgram(m_diffuseSpecularMapGL2ES2Shader);
+ m_diffuseSpecularMapES2RenderPass->setShaderProgram(m_diffuseSpecularMapGL2ES2Shader);
+
+ m_diffuseSpecularMapGL3Technique->addRenderPass(m_diffuseSpecularMapGL3RenderPass);
+ m_diffuseSpecularMapGL2Technique->addRenderPass(m_diffuseSpecularMapGL2RenderPass);
+ m_diffuseSpecularMapES2Technique->addRenderPass(m_diffuseSpecularMapES2RenderPass);
+
+ m_diffuseSpecularMapEffect->addTechnique(m_diffuseSpecularMapGL3Technique);
+ m_diffuseSpecularMapEffect->addTechnique(m_diffuseSpecularMapGL2Technique);
+ m_diffuseSpecularMapEffect->addTechnique(m_diffuseSpecularMapES2Technique);
+
+ m_diffuseSpecularMapEffect->addParameter(m_ambientParameter);
+ m_diffuseSpecularMapEffect->addParameter(m_diffuseParameter);
+ m_diffuseSpecularMapEffect->addParameter(m_specularParameter);
+ m_diffuseSpecularMapEffect->addParameter(m_shininessParameter);
+ m_diffuseSpecularMapEffect->addParameter(m_textureScaleParameter);
+
+ q->setEffect(m_diffuseSpecularMapEffect);
+}
+
+void QDiffuseSpecularMapMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseSpecularMapMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseSpecularMapMaterial);
+ emit q->diffuseChanged(var.value<QAbstractTexture *>());
+}
+
+void QDiffuseSpecularMapMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseSpecularMapMaterial);
+ emit q->specularChanged(var.value<QAbstractTexture *>());
+}
+
+void QDiffuseSpecularMapMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseSpecularMapMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QDiffuseSpecularMapMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QDiffuseSpecularMapMaterial
+ \brief The QDiffuseSpecularMapMaterial provides a default implementation of the phong lighting and bump effect where the diffuse and specular light components
+ are read from texture maps.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new Qt3DRender::QDiffuseSpecularMapMaterial instance with parent object \a parent.
+*/
+QDiffuseSpecularMapMaterial::QDiffuseSpecularMapMaterial(QNode *parent)
+ : QMaterial(*new QDiffuseSpecularMapMaterialPrivate, parent)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QDiffuseSpecularMapMaterial instance.
+*/
+QDiffuseSpecularMapMaterial::~QDiffuseSpecularMapMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QDiffuseSpecularMapMaterial::ambient
+
+ Holds the current ambient color.
+*/
+QColor QDiffuseSpecularMapMaterial::ambient() const
+{
+ Q_D(const QDiffuseSpecularMapMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseSpecularMapMaterial::diffuse
+
+ Holds the current diffuse map texture.
+
+ By default, the diffuse texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QDiffuseSpecularMapMaterial::diffuse() const
+{
+ Q_D(const QDiffuseSpecularMapMaterial);
+ return d->m_diffuseParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseSpecularMapMaterial::specular
+
+ Holds the current specular map texture.
+
+ By default, the specular texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QDiffuseSpecularMapMaterial::specular() const
+{
+ Q_D(const QDiffuseSpecularMapMaterial);
+ return d->m_specularParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseSpecularMapMaterial::shininess
+
+ Holds the current shininess as a float value.
+*/
+float QDiffuseSpecularMapMaterial::shininess() const
+{
+ Q_D(const QDiffuseSpecularMapMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QDiffuseSpecularMapMaterial::textureScale
+
+ Holds the current texture scale as a float value.
+*/
+float QDiffuseSpecularMapMaterial::textureScale() const
+{
+ Q_D(const QDiffuseSpecularMapMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
+void QDiffuseSpecularMapMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QDiffuseSpecularMapMaterial::setDiffuse(QAbstractTexture *diffuse)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->m_diffuseParameter->setValue(QVariant::fromValue(diffuse));
+}
+
+void QDiffuseSpecularMapMaterial::setSpecular(QAbstractTexture *specular)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->m_specularParameter->setValue(QVariant::fromValue(specular));
+}
+
+void QDiffuseSpecularMapMaterial::setShininess(float shininess)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QDiffuseSpecularMapMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QDiffuseSpecularMapMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qdiffusespecularmapmaterial.h b/src/extras/defaults/qdiffusespecularmapmaterial.h
new file mode 100644
index 000000000..43e84bf90
--- /dev/null
+++ b/src/extras/defaults/qdiffusespecularmapmaterial.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_H
+#define QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAbstractTexture;
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QDiffuseSpecularMapMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QDiffuseSpecularMapMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged)
+
+public:
+ explicit QDiffuseSpecularMapMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QDiffuseSpecularMapMaterial();
+
+ QColor ambient() const;
+ Qt3DRender::QAbstractTexture *diffuse() const;
+ Qt3DRender::QAbstractTexture *specular() const;
+ float shininess() const;
+ float textureScale() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setDiffuse(Qt3DRender::QAbstractTexture *diffuse);
+ void setSpecular(Qt3DRender::QAbstractTexture *specular);
+ void setShininess(float shininess);
+ void setTextureScale(float textureScale);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(Qt3DRender::QAbstractTexture *diffuse);
+ void specularChanged(Qt3DRender::QAbstractTexture *specular);
+ void shininessChanged(float shininess);
+ void textureScaleChanged(float textureScale);
+
+private:
+ Q_DECLARE_PRIVATE(QDiffuseSpecularMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_H
diff --git a/src/extras/defaults/qdiffusespecularmapmaterial_p.h b/src/extras/defaults/qdiffusespecularmapmaterial_p.h
new file mode 100644
index 000000000..b358e088a
--- /dev/null
+++ b/src/extras/defaults/qdiffusespecularmapmaterial_p.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_P_H
+#define QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QAbstractTexture;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QDiffuseSpecularMapMaterial;
+
+class QDiffuseSpecularMapMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QDiffuseSpecularMapMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleTextureScaleChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_diffuseSpecularMapEffect;
+ Qt3DRender::QAbstractTexture *m_diffuseTexture;
+ Qt3DRender::QAbstractTexture *m_specularTexture;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
+ Qt3DRender::QTechnique *m_diffuseSpecularMapGL3Technique;
+ Qt3DRender::QTechnique *m_diffuseSpecularMapGL2Technique;
+ Qt3DRender::QTechnique *m_diffuseSpecularMapES2Technique;
+ Qt3DRender::QRenderPass *m_diffuseSpecularMapGL3RenderPass;
+ Qt3DRender::QRenderPass *m_diffuseSpecularMapGL2RenderPass;
+ Qt3DRender::QRenderPass *m_diffuseSpecularMapES2RenderPass;
+ Qt3DRender::QShaderProgram *m_diffuseSpecularMapGL3Shader;
+ Qt3DRender::QShaderProgram *m_diffuseSpecularMapGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QDiffuseSpecularMapMaterial)
+};
+
+} // Qt3DExtras
+
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QDIFFUSESPECULARMAPMATERIAL_P_H
+
diff --git a/src/extras/defaults/qforwardrenderer.cpp b/src/extras/defaults/qforwardrenderer.cpp
new file mode 100644
index 000000000..8e6dc9425
--- /dev/null
+++ b/src/extras/defaults/qforwardrenderer.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qforwardrenderer.h"
+#include "qforwardrenderer_p.h"
+
+#include <Qt3DRender/qviewport.h>
+#include <Qt3DRender/qcameraselector.h>
+#include <Qt3DRender/qclearbuffers.h>
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qfrustumculling.h>
+#include <Qt3DRender/qrendersurfaceselector.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QForwardRendererPrivate::QForwardRendererPrivate()
+ : QTechniqueFilterPrivate()
+ , m_surfaceSelector(new QRenderSurfaceSelector)
+ , m_viewport(new QViewport())
+ , m_cameraSelector(new QCameraSelector())
+ , m_clearBuffer(new QClearBuffers())
+ , m_frustumCulling(new QFrustumCulling())
+{
+}
+
+void QForwardRendererPrivate::init()
+{
+ Q_Q(QForwardRenderer);
+
+ m_frustumCulling->setParent(m_clearBuffer);
+ m_clearBuffer->setParent(m_cameraSelector);
+ m_cameraSelector->setParent(m_viewport);
+ m_viewport->setParent(m_surfaceSelector);
+ m_surfaceSelector->setParent(q);
+
+ m_viewport->setNormalizedRect(QRectF(0.0f, 0.0f, 1.0f, 1.0f));
+ m_clearBuffer->setClearColor(Qt::white);
+ m_clearBuffer->setBuffers(QClearBuffers::ColorDepthBuffer);
+
+ QFilterKey *forwardRenderingStyle = new QFilterKey(q);
+ forwardRenderingStyle->setName(QStringLiteral("renderingStyle"));
+ forwardRenderingStyle->setValue(QStringLiteral("forward"));
+ q->addMatch(forwardRenderingStyle);
+}
+
+/*!
+ \class Qt3DRender::QForwardRenderer
+ \brief The Qt3DRender::QForwardRenderer provides a default \l {QFrameGraph}{FrameGraph} implementation of a forward renderer.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ Forward rendering is how OpenGL is traditionally. It renders directly to the backbuffer
+ one object at a time shading each one as it goes.
+
+ Internally the Qt3DRender::QForwardRenderer is a subclass of Qt3DRender::QTechniqueFilter.
+ This a is a single leaf Framegraph tree which contains a Qt3DRender::QViewport, a Qt3DRender::QCameraSelector
+ and a Qt3DRender::QClearBuffers.
+ The Qt3DRender::QForwardRenderer has a default requirement annotation whose name is "renderingStyle" and value "forward".
+ If you need to filter out your techniques, you should do so based on that annotation.
+
+ By default the viewport occupies the whole screen and the clear color is white. Frustum culling is also enabled.
+*/
+
+/*!
+ Constructs a new Qt3DRender::QForwardRenderer instance with parent object \a parent.
+ */
+QForwardRenderer::QForwardRenderer(QNode *parent)
+ : QTechniqueFilter(*new QForwardRendererPrivate, parent)
+{
+ Q_D(QForwardRenderer);
+ QObject::connect(d->m_clearBuffer, SIGNAL(clearColorChanged(const QColor &)), this, SIGNAL(clearColorChanged(const QColor &)));
+ QObject::connect(d->m_viewport, SIGNAL(normalizedRectChanged(const QRectF &)), this, SIGNAL(viewportRectChanged(const QRectF &)));
+ QObject::connect(d->m_cameraSelector, SIGNAL(cameraChanged(Qt3DCore::QEntity *)), this, SIGNAL(cameraChanged(Qt3DCore::QEntity *)));
+ QObject::connect(d->m_surfaceSelector, SIGNAL(surfaceChanged(QObject *)), this, SIGNAL(surfaceChanged(QObject *)));
+ d->init();
+}
+
+/*!
+ Destroys the QForwardRenderer instance.
+*/
+QForwardRenderer::~QForwardRenderer()
+{
+}
+
+void QForwardRenderer::setViewportRect(const QRectF &viewportRect)
+{
+ Q_D(QForwardRenderer);
+ d->m_viewport->setNormalizedRect(viewportRect);
+}
+
+void QForwardRenderer::setClearColor(const QColor &clearColor)
+{
+ Q_D(QForwardRenderer);
+ d->m_clearBuffer->setClearColor(clearColor);
+}
+
+/*!
+ Sets the camera which should be used to render the scene to \a camera.
+
+ \note A camera is a QEntity having a QCameraLens as one of its components.
+*/
+void QForwardRenderer::setCamera(Qt3DCore::QEntity *camera)
+{
+ Q_D(QForwardRenderer);
+ d->m_cameraSelector->setCamera(camera);
+}
+
+void QForwardRenderer::setSurface(QObject *surface)
+{
+ Q_D(QForwardRenderer);
+ d->m_surfaceSelector->setSurface(surface);
+}
+
+/*!
+ \property Qt3DRender::QForwardRenderer::viewportRect
+
+ Holds the current viewport normalizedRect.
+ */
+QRectF QForwardRenderer::viewportRect() const
+{
+ Q_D(const QForwardRenderer);
+ return d->m_viewport->normalizedRect();
+}
+
+/*!
+ \property Qt3DRender::QForwardRenderer::clearColor
+
+ Holds the current clearColor.
+*/
+QColor QForwardRenderer::clearColor() const
+{
+ Q_D(const QForwardRenderer);
+ return d->m_clearBuffer->clearColor();
+}
+
+/*!
+ \property Qt3DRender::QForwardRenderer::camera
+
+ Holds the current QEntity camera used to render the scene.
+
+ \note A camera is a QEntity that has a QCameraLens as one of its components.
+*/
+Qt3DCore::QEntity *QForwardRenderer::camera() const
+{
+ Q_D(const QForwardRenderer);
+ return d->m_cameraSelector->camera();
+}
+
+QObject *QForwardRenderer::surface() const
+{
+ Q_D(const QForwardRenderer);
+ return d->m_surfaceSelector->surface();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qforwardrenderer.h b/src/extras/defaults/qforwardrenderer.h
new file mode 100644
index 000000000..34ea9055b
--- /dev/null
+++ b/src/extras/defaults/qforwardrenderer.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QFORWARDRENDERER_H
+#define QT3DEXTRAS_QFORWARDRENDERER_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qtechniquefilter.h>
+#include <QRectF>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+class QSurface;
+
+namespace Qt3DExtras {
+
+class QForwardRendererPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QForwardRenderer : public Qt3DRender::QTechniqueFilter
+{
+ Q_OBJECT
+ Q_PROPERTY(QObject *surface READ surface WRITE setSurface NOTIFY surfaceChanged)
+ Q_PROPERTY(QRectF viewportRect READ viewportRect WRITE setViewportRect NOTIFY viewportRectChanged)
+ Q_PROPERTY(QColor clearColor READ clearColor WRITE setClearColor NOTIFY clearColorChanged)
+ Q_PROPERTY(Qt3DCore::QEntity *camera READ camera WRITE setCamera NOTIFY cameraChanged)
+public:
+ explicit QForwardRenderer(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QForwardRenderer();
+
+ QRectF viewportRect() const;
+ QColor clearColor() const;
+ Qt3DCore::QEntity *camera() const;
+ QObject *surface() const;
+
+public Q_SLOTS:
+ void setViewportRect(const QRectF &viewportRect);
+ void setClearColor(const QColor &clearColor);
+ void setCamera(Qt3DCore::QEntity *camera);
+ void setSurface(QObject * surface);
+
+Q_SIGNALS:
+ void viewportRectChanged(const QRectF &viewportRect);
+ void clearColorChanged(const QColor &clearColor);
+ void cameraChanged(Qt3DCore::QEntity *camera);
+ void surfaceChanged(QObject *surface);
+
+private:
+ Q_DECLARE_PRIVATE(QForwardRenderer)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QFORWARDRENDERER_H
diff --git a/src/extras/defaults/qforwardrenderer_p.h b/src/extras/defaults/qforwardrenderer_p.h
new file mode 100644
index 000000000..56d66a542
--- /dev/null
+++ b/src/extras/defaults/qforwardrenderer_p.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QFORWARDRENDERER_P_H
+#define QT3DEXTRAS_QFORWARDRENDERER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qtechniquefilter_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QForwardRenderer;
+class QViewport;
+class QClearBuffers;
+class QCameraSelector;
+class QFrustumCulling;
+class QRenderSurfaceSelector;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QForwardRendererPrivate: public Qt3DRender::QTechniqueFilterPrivate
+{
+public:
+ QForwardRendererPrivate();
+
+ Qt3DRender::QRenderSurfaceSelector *m_surfaceSelector;
+ Qt3DRender::QViewport *m_viewport;
+ Qt3DRender::QCameraSelector *m_cameraSelector;
+ Qt3DRender::QClearBuffers *m_clearBuffer;
+ Qt3DRender::QFrustumCulling *m_frustumCulling;
+
+ void init();
+
+ Q_DECLARE_PUBLIC(QForwardRenderer)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QFORWARDRENDERER_P_H
+
diff --git a/src/extras/defaults/qgoochmaterial.cpp b/src/extras/defaults/qgoochmaterial.cpp
new file mode 100644
index 000000000..7b4865734
--- /dev/null
+++ b/src/extras/defaults/qgoochmaterial.cpp
@@ -0,0 +1,358 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgoochmaterial.h"
+#include "qgoochmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qtechnique.h>
+
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+QGoochMaterialPrivate::QGoochMaterialPrivate()
+ : QMaterialPrivate()
+ , m_effect(new QEffect)
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.0f, 0.0f, 0.0f)))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.0f, 0.0f, 0.0f)))
+ , m_coolParameter(new QParameter(QStringLiteral("kblue"), QColor::fromRgbF(0.0f, 0.0f, 0.4f)))
+ , m_warmParameter(new QParameter(QStringLiteral("kyellow"), QColor::fromRgbF(0.4f, 0.4f, 0.0f)))
+ , m_alphaParameter(new QParameter(QStringLiteral("alpha"), 0.25f))
+ , m_betaParameter(new QParameter(QStringLiteral("beta"), 0.5f))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 100.0f))
+ , m_gl3Technique(new QTechnique)
+ , m_gl2Technique(new QTechnique)
+ , m_es2Technique(new QTechnique)
+ , m_gl3RenderPass(new QRenderPass)
+ , m_gl2RenderPass(new QRenderPass)
+ , m_es2RenderPass(new QRenderPass)
+ , m_gl3Shader(new QShaderProgram)
+ , m_gl2ES2Shader(new QShaderProgram)
+ , m_filterKey(new QFilterKey)
+{
+}
+
+void QGoochMaterialPrivate::init()
+{
+ Q_Q(QGoochMaterial);
+
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleSpecularChanged);
+ connect(m_coolParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleCoolChanged);
+ connect(m_warmParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleWarmChanged);
+ connect(m_alphaParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleAlphaChanged);
+ connect(m_betaParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleBetaChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QGoochMaterialPrivate::handleShininessChanged);
+
+ m_gl3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/gooch.vert"))));
+ m_gl3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/gooch.frag"))));
+ m_gl2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/gooch.vert"))));
+ m_gl2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/gooch.frag"))));
+
+ m_gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_gl3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_gl3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_gl2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_gl2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_gl2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_gl2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_es2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_es2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_es2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_es2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_gl3Technique->addFilterKey(m_filterKey);
+ m_gl2Technique->addFilterKey(m_filterKey);
+ m_es2Technique->addFilterKey(m_filterKey);
+
+ m_gl3RenderPass->setShaderProgram(m_gl3Shader);
+ m_gl2RenderPass->setShaderProgram(m_gl2ES2Shader);
+ m_es2RenderPass->setShaderProgram(m_gl2ES2Shader);
+
+ m_gl3Technique->addRenderPass(m_gl3RenderPass);
+ m_gl2Technique->addRenderPass(m_gl2RenderPass);
+ m_es2Technique->addRenderPass(m_es2RenderPass);
+
+ m_effect->addTechnique(m_gl3Technique);
+ m_effect->addTechnique(m_gl2Technique);
+ m_effect->addTechnique(m_es2Technique);
+
+ m_effect->addParameter(m_diffuseParameter);
+ m_effect->addParameter(m_specularParameter);
+ m_effect->addParameter(m_coolParameter);
+ m_effect->addParameter(m_warmParameter);
+ m_effect->addParameter(m_alphaParameter);
+ m_effect->addParameter(m_betaParameter);
+ m_effect->addParameter(m_shininessParameter);
+
+ q->setEffect(m_effect);
+}
+
+void QGoochMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->diffuseChanged(var.value<QColor>());
+}
+
+void QGoochMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QGoochMaterialPrivate::handleCoolChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->coolChanged(var.value<QColor>());
+}
+
+void QGoochMaterialPrivate::handleWarmChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->warmChanged(var.value<QColor>());
+}
+
+void QGoochMaterialPrivate::handleAlphaChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->alphaChanged(var.toFloat());
+}
+
+void QGoochMaterialPrivate::handleBetaChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->betaChanged(var.toFloat());
+}
+
+void QGoochMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QGoochMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QGoochMaterial
+ \brief The QGoochMaterial provides a material that implements the Gooch
+ shading model, popular in CAD and CAM applications.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The Gooch lighting model uses both color and brightness to help show the
+ curvature of 3D surfaces. This is often better than models such as Phong
+ that rely purely upon changes in brightness. In situations such as in CAD
+ and CAM applications where photorealism is not a goal, the Gooch shading
+ model in conjunction with some kind of silhouette edge inking is a popular
+ solution.
+
+ The Gooch lighting model is explained fully in the \l{original Gooch
+ paper}. The Gooch model mixes a diffuse objetc color with a user-provided
+ cool color and warm color to produce the end points of a color ramp that is
+ used to shade the object based upon the cosine of the angle between the
+ vector from the fragment to the light source and the fragment's normal
+ vector. Optionally, a specular highlight can be added on top. The relative
+ contributions to the cool and warm colors by the diffuse color are
+ controlled by the alpha and beta properties respecitvely.
+
+ This material uses an effect with a single render pass approach and
+ performs per fragment lighting. Techniques are provided for OpenGL 2,
+ OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new Qt3DCore::QGoochMaterial instance with parent object \a parent.
+*/
+QGoochMaterial::QGoochMaterial(QNode *parent)
+ : QMaterial(*new QGoochMaterialPrivate, parent)
+{
+ Q_D(QGoochMaterial);
+ d->init();
+}
+
+QGoochMaterial::QGoochMaterial(QGoochMaterialPrivate &dd, QNode *parent)
+ : QMaterial(dd, parent)
+{
+ Q_D(QGoochMaterial);
+ d->init();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::diffuse
+
+ Holds the current diffuse color.
+*/
+QColor QGoochMaterial::diffuse() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_diffuseParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::specular
+
+ Holds the current specular color.
+*/
+QColor QGoochMaterial::specular() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::cool
+
+ Holds the current cool color.
+*/
+QColor QGoochMaterial::cool() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_coolParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::warm
+
+ Holds the current warm color.
+*/
+QColor QGoochMaterial::warm() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_warmParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::alpha
+
+ Holds the current alpha value. The start point of the color ramp
+ used by the Gooch shader is calculated as {c = cool + alpha * diffuse}.
+*/
+float QGoochMaterial::alpha() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_alphaParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::beta
+
+ Holds the current beta value. The start point of the color ramp
+ used by the Gooch shader is calculated as {c = warm + beta * diffuse}.
+*/
+float QGoochMaterial::beta() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_betaParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QGoochMaterial::shininess
+
+ Holds the current shininess value. Higher values of shininess result in
+ a smaller and brighter highlight.
+*/
+float QGoochMaterial::shininess() const
+{
+ Q_D(const QGoochMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+void QGoochMaterial::setDiffuse(const QColor &diffuse)
+{
+ Q_D(QGoochMaterial);
+ return d->m_diffuseParameter->setValue(diffuse);
+}
+
+void QGoochMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QGoochMaterial);
+ return d->m_specularParameter->setValue(specular);
+}
+
+void QGoochMaterial::setCool(const QColor &cool)
+{
+ Q_D(QGoochMaterial);
+ return d->m_coolParameter->setValue(cool);
+}
+
+void QGoochMaterial::setWarm(const QColor &warm)
+{
+ Q_D(QGoochMaterial);
+ return d->m_warmParameter->setValue(warm);
+}
+
+void QGoochMaterial::setAlpha(float alpha)
+{
+ Q_D(QGoochMaterial);
+ return d->m_alphaParameter->setValue(alpha);
+}
+
+void QGoochMaterial::setBeta(float beta)
+{
+ Q_D(QGoochMaterial);
+ return d->m_betaParameter->setValue(beta);
+}
+
+void QGoochMaterial::setShininess(float shininess)
+{
+ Q_D(QGoochMaterial);
+ return d->m_shininessParameter->setValue(shininess);
+}
+
+}
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qgoochmaterial.h b/src/extras/defaults/qgoochmaterial.h
new file mode 100644
index 000000000..cf2c1c5fc
--- /dev/null
+++ b/src/extras/defaults/qgoochmaterial.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QGOOCHMATERIAL_H
+#define QT3DEXTRAS_QGOOCHMATERIAL_H
+
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QGoochMaterialPrivate;
+
+class QGoochMaterial : public QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(QColor cool READ cool WRITE setCool NOTIFY coolChanged)
+ Q_PROPERTY(QColor warm READ warm WRITE setWarm NOTIFY warmChanged)
+ Q_PROPERTY(float alpha READ alpha WRITE setAlpha NOTIFY alphaChanged)
+ Q_PROPERTY(float beta READ beta WRITE setBeta NOTIFY betaChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+
+public:
+ explicit QGoochMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ QColor diffuse() const;
+ QColor specular() const;
+ QColor cool() const;
+ QColor warm() const;
+ float alpha() const;
+ float beta() const;
+ float shininess() const;
+
+public Q_SLOTS:
+ void setDiffuse(const QColor &diffuse);
+ void setSpecular(const QColor &specular);
+ void setCool(const QColor &cool);
+ void setWarm(const QColor &warm);
+ void setAlpha(float alpha);
+ void setBeta(float beta);
+ void setShininess(float shininess);
+
+Q_SIGNALS:
+ void diffuseChanged(const QColor &diffuse);
+ void specularChanged(const QColor &specular);
+ void coolChanged(const QColor &cool);
+ void warmChanged(const QColor &warm);
+ void alphaChanged(float alpha);
+ void betaChanged(float beta);
+ void shininessChanged(float shininess);
+
+protected:
+ QGoochMaterial(QGoochMaterialPrivate &dd, Qt3DCore::QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QGoochMaterial)
+};
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QGOOCHMATERIAL_H
diff --git a/src/extras/defaults/qgoochmaterial_p.h b/src/extras/defaults/qgoochmaterial_p.h
new file mode 100644
index 000000000..0a6f67aea
--- /dev/null
+++ b/src/extras/defaults/qgoochmaterial_p.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QGOOCHMATERIAL_P_H
+#define QT3DEXTRAS_QGOOCHMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QRenderPass;
+class QShaderProgram;
+class QTechnique;
+
+class QGoochMaterialPrivate : public QMaterialPrivate
+{
+public:
+ QGoochMaterialPrivate();
+
+ void init();
+
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleCoolChanged(const QVariant &var);
+ void handleWarmChanged(const QVariant &var);
+ void handleAlphaChanged(const QVariant &var);
+ void handleBetaChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+
+ QEffect *m_effect;
+ QParameter *m_diffuseParameter;
+ QParameter *m_specularParameter;
+ QParameter *m_coolParameter;
+ QParameter *m_warmParameter;
+ QParameter *m_alphaParameter;
+ QParameter *m_betaParameter;
+ QParameter *m_shininessParameter;
+ QTechnique *m_gl3Technique;
+ QTechnique *m_gl2Technique;
+ QTechnique *m_es2Technique;
+ QRenderPass *m_gl3RenderPass;
+ QRenderPass *m_gl2RenderPass;
+ QRenderPass *m_es2RenderPass;
+ QShaderProgram *m_gl3Shader;
+ QShaderProgram *m_gl2ES2Shader;
+ QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QGoochMaterial)
+};
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QGOOCHMATERIAL_P_H
+
diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
new file mode 100644
index 000000000..df61eafdf
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.cpp
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnormaldiffusemapalphamaterial.h"
+#include "qnormaldiffusemapalphamaterial_p.h"
+
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/qalphacoverage.h>
+#include <Qt3DRender/qdepthtest.h>
+
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+
+QNormalDiffuseMapAlphaMaterialPrivate::QNormalDiffuseMapAlphaMaterialPrivate()
+ : QNormalDiffuseMapMaterialPrivate()
+ , m_alphaCoverage(new QAlphaCoverage())
+ , m_depthTest(new QDepthTest())
+{
+}
+
+void QNormalDiffuseMapAlphaMaterialPrivate::init()
+{
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemapalpha.frag"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemapalpha.frag"))));
+
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QNormalDiffuseMapMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_normalDiffuseGL3Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseGL2Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseES2Technique->addFilterKey(m_filterKey);
+
+ m_depthTest->setDepthFunction(QDepthTest::Less);
+
+ m_normalDiffuseGL3RenderPass->setShaderProgram(m_normalDiffuseGL3Shader);
+ m_normalDiffuseGL3RenderPass->addRenderState(m_alphaCoverage);
+ m_normalDiffuseGL3RenderPass->addRenderState(m_depthTest);
+
+ m_normalDiffuseGL2RenderPass->setShaderProgram(m_normalDiffuseGL2ES2Shader);
+ m_normalDiffuseGL2RenderPass->addRenderState(m_alphaCoverage);
+ m_normalDiffuseGL2RenderPass->addRenderState(m_depthTest);
+
+ m_normalDiffuseES2RenderPass->setShaderProgram(m_normalDiffuseGL2ES2Shader);
+ m_normalDiffuseES2RenderPass->addRenderState(m_alphaCoverage);
+ m_normalDiffuseES2RenderPass->addRenderState(m_depthTest);
+
+ m_normalDiffuseGL3Technique->addRenderPass(m_normalDiffuseGL3RenderPass);
+ m_normalDiffuseGL2Technique->addRenderPass(m_normalDiffuseGL2RenderPass);
+ m_normalDiffuseES2Technique->addRenderPass(m_normalDiffuseES2RenderPass);
+
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseGL3Technique);
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseGL2Technique);
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseES2Technique);
+
+ m_normalDiffuseEffect->addParameter(m_ambientParameter);
+ m_normalDiffuseEffect->addParameter(m_diffuseParameter);
+ m_normalDiffuseEffect->addParameter(m_normalParameter);
+ m_normalDiffuseEffect->addParameter(m_specularParameter);
+ m_normalDiffuseEffect->addParameter(m_shininessParameter);
+ m_normalDiffuseEffect->addParameter(m_textureScaleParameter);
+
+ q->setEffect(m_normalDiffuseEffect);
+}
+
+
+/*!
+ \class Qt3DRender::QNormalDiffuseMapAlphaMaterial
+ \brief The QNormalDiffuseMapAlphaMaterial provides a default implementation of the phong lighting and bump effect where the diffuse light component
+ is read from a texture map and the normals of the mesh being rendered from a normal texture map. In addition, it defines an alpha to coverage and
+ a depth test to be performed in the rendering pass.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+/*!
+ Constructs a new Qt3DRender::QNormalDiffuseMapAlphaMaterial instance with parent object \a parent.
+*/
+QNormalDiffuseMapAlphaMaterial::QNormalDiffuseMapAlphaMaterial(QNode *parent)
+ : QNormalDiffuseMapMaterial(*new QNormalDiffuseMapAlphaMaterialPrivate, parent)
+{
+}
+
+/*!
+ Destroys the QNormalDiffuseMapAlphaMaterial instance.
+*/
+QNormalDiffuseMapAlphaMaterial::~QNormalDiffuseMapAlphaMaterial()
+{
+}
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial.h b/src/extras/defaults/qnormaldiffusemapalphamaterial.h
new file mode 100644
index 000000000..ad4dd6c53
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapalphamaterial.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_H
+#define QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DExtras/qnormaldiffusemapmaterial.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseMapAlphaMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QNormalDiffuseMapAlphaMaterial : public QNormalDiffuseMapMaterial
+{
+ Q_OBJECT
+public:
+ explicit QNormalDiffuseMapAlphaMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QNormalDiffuseMapAlphaMaterial();
+
+private:
+ Q_DECLARE_PRIVATE(QNormalDiffuseMapAlphaMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_H
diff --git a/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h b/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h
new file mode 100644
index 000000000..91b0961f1
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapalphamaterial_p.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_P_H
+#define QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <qnormaldiffusemapmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+
+namespace Qt3DRender {
+
+class QAlphaCoverage;
+class QDepthTest;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseMapAlphaMaterial;
+class QNormalDiffuseMapAlphaMaterialPrivate: public QNormalDiffuseMapMaterialPrivate
+{
+public:
+ QNormalDiffuseMapAlphaMaterialPrivate();
+
+ void init() Q_DECL_OVERRIDE;
+
+ Qt3DRender::QAlphaCoverage *m_alphaCoverage;
+ Qt3DRender::QDepthTest *m_depthTest;
+
+ Q_DECLARE_PUBLIC(QNormalDiffuseMapAlphaMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSEMAPALPHAMATERIAL_P_H
+
diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.cpp b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
new file mode 100644
index 000000000..01d67a477
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapmaterial.cpp
@@ -0,0 +1,363 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnormaldiffusemapmaterial.h"
+#include "qnormaldiffusemapmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QNormalDiffuseMapMaterialPrivate::QNormalDiffuseMapMaterialPrivate()
+ : QMaterialPrivate()
+ , m_normalDiffuseEffect(new QEffect())
+ , m_diffuseTexture(new QTexture2D())
+ , m_normalTexture(new QTexture2D())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.1f, 0.1f, 0.1f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("diffuseTexture"), m_diffuseTexture))
+ , m_normalParameter(new QParameter(QStringLiteral("normalTexture"), m_normalTexture))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
+ , m_normalDiffuseGL3Technique(new QTechnique())
+ , m_normalDiffuseGL2Technique(new QTechnique())
+ , m_normalDiffuseES2Technique(new QTechnique())
+ , m_normalDiffuseGL3RenderPass(new QRenderPass())
+ , m_normalDiffuseGL2RenderPass(new QRenderPass())
+ , m_normalDiffuseES2RenderPass(new QRenderPass())
+ , m_normalDiffuseGL3Shader(new QShaderProgram())
+ , m_normalDiffuseGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+ m_diffuseTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_diffuseTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_diffuseTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_diffuseTexture->setGenerateMipMaps(true);
+ m_diffuseTexture->setMaximumAnisotropy(16.0f);
+
+ m_normalTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_normalTexture->setMinificationFilter(QAbstractTexture::Linear);
+ m_normalTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_normalTexture->setMaximumAnisotropy(16.0f);
+}
+
+void QNormalDiffuseMapMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleDiffuseChanged);
+ connect(m_normalParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleNormalChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleShininessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged);
+
+ m_normalDiffuseGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.frag"))));
+ m_normalDiffuseGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.frag"))));
+
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_normalDiffuseGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QNormalDiffuseMapMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_normalDiffuseGL3Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseGL2Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseES2Technique->addFilterKey(m_filterKey);
+
+ m_normalDiffuseGL3RenderPass->setShaderProgram(m_normalDiffuseGL3Shader);
+ m_normalDiffuseGL2RenderPass->setShaderProgram(m_normalDiffuseGL2ES2Shader);
+ m_normalDiffuseES2RenderPass->setShaderProgram(m_normalDiffuseGL2ES2Shader);
+
+ m_normalDiffuseGL3Technique->addRenderPass(m_normalDiffuseGL3RenderPass);
+ m_normalDiffuseGL2Technique->addRenderPass(m_normalDiffuseGL2RenderPass);
+ m_normalDiffuseES2Technique->addRenderPass(m_normalDiffuseES2RenderPass);
+
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseGL3Technique);
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseGL2Technique);
+ m_normalDiffuseEffect->addTechnique(m_normalDiffuseES2Technique);
+
+ m_normalDiffuseEffect->addParameter(m_ambientParameter);
+ m_normalDiffuseEffect->addParameter(m_diffuseParameter);
+ m_normalDiffuseEffect->addParameter(m_normalParameter);
+ m_normalDiffuseEffect->addParameter(m_specularParameter);
+ m_normalDiffuseEffect->addParameter(m_shininessParameter);
+ m_normalDiffuseEffect->addParameter(m_textureScaleParameter);
+
+ q->setEffect(m_normalDiffuseEffect);
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->diffuseChanged(var.value<QAbstractTexture *>());
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleNormalChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->normalChanged(var.value<QAbstractTexture *>());
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QNormalDiffuseMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseMapMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QNormalDiffuseMapMaterial
+ \brief The QNormalDiffuseMapMaterial provides a default implementation of the phong lighting and bump effect where the diffuse light component
+ is read from a texture map and the normals of the mesh being rendered from a normal texture map.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new Qt3DRender::QNormalDiffuseMapMaterial instance with parent object \a parent.
+*/
+QNormalDiffuseMapMaterial::QNormalDiffuseMapMaterial(QNode *parent)
+ : QMaterial(*new QNormalDiffuseMapMaterialPrivate, parent)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->init();
+}
+
+/*! \internal */
+QNormalDiffuseMapMaterial::QNormalDiffuseMapMaterial(QNormalDiffuseMapMaterialPrivate &dd, QNode *parent)
+ : QMaterial(dd, parent)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QNormalDiffuseMapMaterial instance.
+*/
+QNormalDiffuseMapMaterial::~QNormalDiffuseMapMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::ambient
+
+ Holds the current ambient color.
+*/
+QColor QNormalDiffuseMapMaterial::ambient() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::specular
+
+ Holds the current specular color.
+*/
+QColor QNormalDiffuseMapMaterial::specular() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::diffuse
+
+ Holds the current diffuse map texture.
+
+ By default, the diffuse texture has these properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap modeM
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QNormalDiffuseMapMaterial::diffuse() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_diffuseParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::normal
+
+ Holds the current normal map texture.
+
+ By default, the normal texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QNormalDiffuseMapMaterial::normal() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_normalParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::shininess
+
+ Holds the current shininess as a float value.
+*/
+float QNormalDiffuseMapMaterial::shininess() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseMapMaterial::textureScale
+
+ Holds the current texture scale as a float value.
+*/
+float QNormalDiffuseMapMaterial::textureScale() const
+{
+ Q_D(const QNormalDiffuseMapMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
+void QNormalDiffuseMapMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QNormalDiffuseMapMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_specularParameter->setValue(specular);
+}
+
+void QNormalDiffuseMapMaterial::setDiffuse(QAbstractTexture *diffuse)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_diffuseParameter->setValue(QVariant::fromValue(diffuse));
+}
+
+void QNormalDiffuseMapMaterial::setNormal(QAbstractTexture *normal)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_normalParameter->setValue(QVariant::fromValue(normal));
+}
+
+void QNormalDiffuseMapMaterial::setShininess(float shininess)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QNormalDiffuseMapMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QNormalDiffuseMapMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qnormaldiffusemapmaterial.h b/src/extras/defaults/qnormaldiffusemapmaterial.h
new file mode 100644
index 000000000..7152d64d5
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapmaterial.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_H
+#define QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAbstractTexture;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseMapMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QNormalDiffuseMapMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *normal READ normal WRITE setNormal NOTIFY normalChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged)
+
+public:
+ explicit QNormalDiffuseMapMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QNormalDiffuseMapMaterial();
+
+ QColor ambient() const;
+ QColor specular() const;
+ Qt3DRender::QAbstractTexture *diffuse() const;
+ Qt3DRender::QAbstractTexture *normal() const;
+ float shininess() const;
+ float textureScale() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setSpecular(const QColor &specular);
+ void setDiffuse(Qt3DRender::QAbstractTexture *diffuse);
+ void setNormal(Qt3DRender::QAbstractTexture *normal);
+ void setShininess(float shininess);
+ void setTextureScale(float textureScale);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(Qt3DRender::QAbstractTexture *diffuse);
+ void normalChanged(Qt3DRender::QAbstractTexture *normal);
+ void specularChanged(const QColor &specular);
+ void shininessChanged(float shininess);
+ void textureScaleChanged(float textureScale);
+
+protected:
+ QNormalDiffuseMapMaterial(QNormalDiffuseMapMaterialPrivate &dd, Qt3DCore::QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QNormalDiffuseMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_H
diff --git a/src/extras/defaults/qnormaldiffusemapmaterial_p.h b/src/extras/defaults/qnormaldiffusemapmaterial_p.h
new file mode 100644
index 000000000..8dff59218
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusemapmaterial_p.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_P_H
+#define QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QAbstractTexture;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseMapMaterial;
+
+class QNormalDiffuseMapMaterialPrivate: public Qt3DRender::QMaterialPrivate
+{
+public:
+ QNormalDiffuseMapMaterialPrivate();
+
+ virtual void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleNormalChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleTextureScaleChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_normalDiffuseEffect;
+ Qt3DRender::QAbstractTexture *m_diffuseTexture;
+ Qt3DRender::QAbstractTexture *m_normalTexture;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_normalParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
+ Qt3DRender::QTechnique *m_normalDiffuseGL3Technique;
+ Qt3DRender::QTechnique *m_normalDiffuseGL2Technique;
+ Qt3DRender::QTechnique *m_normalDiffuseES2Technique;
+ Qt3DRender::QRenderPass *m_normalDiffuseGL3RenderPass;
+ Qt3DRender::QRenderPass *m_normalDiffuseGL2RenderPass;
+ Qt3DRender::QRenderPass *m_normalDiffuseES2RenderPass;
+ Qt3DRender::QShaderProgram *m_normalDiffuseGL3Shader;
+ Qt3DRender::QShaderProgram *m_normalDiffuseGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QNormalDiffuseMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSEMAPMATERIAL_P_H
+
diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
new file mode 100644
index 000000000..6d54b9535
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.cpp
@@ -0,0 +1,379 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnormaldiffusespecularmapmaterial.h"
+#include "qnormaldiffusespecularmapmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QNormalDiffuseSpecularMapMaterialPrivate::QNormalDiffuseSpecularMapMaterialPrivate()
+ : QMaterialPrivate()
+ , m_normalDiffuseSpecularEffect(new QEffect())
+ , m_diffuseTexture(new QTexture2D())
+ , m_normalTexture(new QTexture2D())
+ , m_specularTexture(new QTexture2D())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("diffuseTexture"), m_diffuseTexture))
+ , m_normalParameter(new QParameter(QStringLiteral("normalTexture"), m_normalTexture))
+ , m_specularParameter(new QParameter(QStringLiteral("specularTexture"), m_specularTexture))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_textureScaleParameter(new QParameter(QStringLiteral("texCoordScale"), 1.0f))
+ , m_normalDiffuseSpecularGL3Technique(new QTechnique())
+ , m_normalDiffuseSpecularGL2Technique(new QTechnique())
+ , m_normalDiffuseSpecularES2Technique(new QTechnique())
+ , m_normalDiffuseSpecularGL3RenderPass(new QRenderPass())
+ , m_normalDiffuseSpecularGL2RenderPass(new QRenderPass())
+ , m_normalDiffuseSpecularES2RenderPass(new QRenderPass())
+ , m_normalDiffuseSpecularGL3Shader(new QShaderProgram())
+ , m_normalDiffuseSpecularGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+ m_diffuseTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_diffuseTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_diffuseTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_diffuseTexture->setGenerateMipMaps(true);
+ m_diffuseTexture->setMaximumAnisotropy(16.0f);
+
+ m_normalTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_normalTexture->setMinificationFilter(QAbstractTexture::Linear);
+ m_normalTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_normalTexture->setMaximumAnisotropy(16.0f);
+
+ m_specularTexture->setMagnificationFilter(QAbstractTexture::Linear);
+ m_specularTexture->setMinificationFilter(QAbstractTexture::LinearMipMapLinear);
+ m_specularTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::Repeat));
+ m_specularTexture->setGenerateMipMaps(true);
+ m_specularTexture->setMaximumAnisotropy(16.0f);
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged);
+ connect(m_normalParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleNormalChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleShininessChanged);
+ connect(m_textureScaleParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged);
+
+ m_normalDiffuseSpecularGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/normaldiffusespecularmap.frag"))));
+ m_normalDiffuseSpecularGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusemap.vert"))));
+ m_normalDiffuseSpecularGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/normaldiffusespecularmap.frag"))));
+
+ m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_normalDiffuseSpecularGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseSpecularGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_normalDiffuseSpecularES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_normalDiffuseSpecularGL3Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseSpecularGL2Technique->addFilterKey(m_filterKey);
+ m_normalDiffuseSpecularES2Technique->addFilterKey(m_filterKey);
+
+ m_normalDiffuseSpecularGL3RenderPass->setShaderProgram(m_normalDiffuseSpecularGL3Shader);
+ m_normalDiffuseSpecularGL2RenderPass->setShaderProgram(m_normalDiffuseSpecularGL2ES2Shader);
+ m_normalDiffuseSpecularES2RenderPass->setShaderProgram(m_normalDiffuseSpecularGL2ES2Shader);
+
+ m_normalDiffuseSpecularGL3Technique->addRenderPass(m_normalDiffuseSpecularGL3RenderPass);
+ m_normalDiffuseSpecularGL2Technique->addRenderPass(m_normalDiffuseSpecularGL2RenderPass);
+ m_normalDiffuseSpecularES2Technique->addRenderPass(m_normalDiffuseSpecularES2RenderPass);
+
+ m_normalDiffuseSpecularEffect->addTechnique(m_normalDiffuseSpecularGL3Technique);
+ m_normalDiffuseSpecularEffect->addTechnique(m_normalDiffuseSpecularGL2Technique);
+ m_normalDiffuseSpecularEffect->addTechnique(m_normalDiffuseSpecularES2Technique);
+
+ m_normalDiffuseSpecularEffect->addParameter(m_ambientParameter);
+ m_normalDiffuseSpecularEffect->addParameter(m_diffuseParameter);
+ m_normalDiffuseSpecularEffect->addParameter(m_normalParameter);
+ m_normalDiffuseSpecularEffect->addParameter(m_specularParameter);
+ m_normalDiffuseSpecularEffect->addParameter(m_shininessParameter);
+ m_normalDiffuseSpecularEffect->addParameter(m_textureScaleParameter);
+
+ q->setEffect(m_normalDiffuseSpecularEffect);
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->diffuseChanged(var.value<QAbstractTexture *>());
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleNormalChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->normalChanged(var.value<QAbstractTexture *>());
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->specularChanged(var.value<QAbstractTexture *>());
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QNormalDiffuseSpecularMapMaterialPrivate::handleTextureScaleChanged(const QVariant &var)
+{
+ Q_Q(QNormalDiffuseSpecularMapMaterial);
+ emit q->textureScaleChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QNormalDiffuseSpecularMapMaterial
+ \brief The QNormalDiffuseSpecularMapMaterial provides a default implementation of the phong lighting and bump effect where the diffuse and specular light components
+ are read from texture maps and the normals of the mesh being rendered from a normal texture map.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The specular lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ Constructs a new Qt3DRender::QNormalDiffuseSpecularMapMaterial instance with parent object \a parent.
+*/
+QNormalDiffuseSpecularMapMaterial::QNormalDiffuseSpecularMapMaterial(QNode *parent)
+ : QMaterial(*new QNormalDiffuseSpecularMapMaterialPrivate, parent)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->init();
+}
+
+/*! \internal */
+QNormalDiffuseSpecularMapMaterial::QNormalDiffuseSpecularMapMaterial(QNormalDiffuseSpecularMapMaterialPrivate &dd, QNode *parent)
+ : QMaterial(dd, parent)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the Qt3DRender::QNormalDiffuseSpecularMapMaterial instance.
+*/
+QNormalDiffuseSpecularMapMaterial::~QNormalDiffuseSpecularMapMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::ambient
+
+ Holds the current ambient color.
+*/
+QColor QNormalDiffuseSpecularMapMaterial::ambient() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::diffuse
+
+ Holds the current diffuse map texture.
+
+ By default, the diffuse texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QNormalDiffuseSpecularMapMaterial::diffuse() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_diffuseParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::normal
+
+ Holds the current normal map texture.
+
+ By default, the normal texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QNormalDiffuseSpecularMapMaterial::normal() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_normalParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::specular
+
+ Holds the current specular map texture.
+
+ By default, the specular texture has the following properties:
+
+ \list
+ \li Linear minification and magnification filters
+ \li Linear mipmap with mipmapping enabled
+ \li Repeat wrap mode
+ \li Maximum anisotropy of 16.0
+ \endlist
+*/
+QAbstractTexture *QNormalDiffuseSpecularMapMaterial::specular() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_specularParameter->value().value<QAbstractTexture *>();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::shininess
+
+ Holds the current shininess as a float value.
+*/
+float QNormalDiffuseSpecularMapMaterial::shininess() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QNormalDiffuseSpecularMapMaterial::textureScale
+
+ Holds the current texture scale as a float value.
+*/
+float QNormalDiffuseSpecularMapMaterial::textureScale() const
+{
+ Q_D(const QNormalDiffuseSpecularMapMaterial);
+ return d->m_textureScaleParameter->value().toFloat();
+}
+
+void QNormalDiffuseSpecularMapMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QNormalDiffuseSpecularMapMaterial::setDiffuse(QAbstractTexture *diffuse)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_diffuseParameter->setValue(QVariant::fromValue(diffuse));
+}
+
+void QNormalDiffuseSpecularMapMaterial::setNormal(QAbstractTexture *normal)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_normalParameter->setValue(QVariant::fromValue(normal));
+}
+
+void QNormalDiffuseSpecularMapMaterial::setSpecular(QAbstractTexture *specular)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_specularParameter->setValue(QVariant::fromValue(specular));
+}
+
+void QNormalDiffuseSpecularMapMaterial::setShininess(float shininess)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QNormalDiffuseSpecularMapMaterial::setTextureScale(float textureScale)
+{
+ Q_D(QNormalDiffuseSpecularMapMaterial);
+ d->m_textureScaleParameter->setValue(textureScale);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial.h b/src/extras/defaults/qnormaldiffusespecularmapmaterial.h
new file mode 100644
index 000000000..a2f32d2ae
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_H
+#define QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseSpecularMapMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QNormalDiffuseSpecularMapMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *normal READ normal WRITE setNormal NOTIFY normalChanged)
+ Q_PROPERTY(Qt3DRender::QAbstractTexture *specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(float textureScale READ textureScale WRITE setTextureScale NOTIFY textureScaleChanged)
+
+public:
+ explicit QNormalDiffuseSpecularMapMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QNormalDiffuseSpecularMapMaterial();
+
+ QColor ambient() const;
+ Qt3DRender::QAbstractTexture *diffuse() const;
+ Qt3DRender::QAbstractTexture *normal() const;
+ Qt3DRender::QAbstractTexture *specular() const;
+ float shininess() const;
+ float textureScale() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setDiffuse(Qt3DRender::QAbstractTexture *diffuse);
+ void setNormal(Qt3DRender::QAbstractTexture *normal);
+ void setSpecular(Qt3DRender::QAbstractTexture *specular);
+ void setShininess(float shininess);
+ void setTextureScale(float textureScale);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(Qt3DRender::QAbstractTexture *diffuse);
+ void normalChanged(Qt3DRender::QAbstractTexture *normal);
+ void specularChanged(Qt3DRender::QAbstractTexture *specular);
+ void shininessChanged(float shininess);
+ void textureScaleChanged(float textureScale);
+
+protected:
+ QNormalDiffuseSpecularMapMaterial(QNormalDiffuseSpecularMapMaterialPrivate &dd, Qt3DCore::QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QNormalDiffuseSpecularMapMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_H
diff --git a/src/extras/defaults/qnormaldiffusespecularmapmaterial_p.h b/src/extras/defaults/qnormaldiffusespecularmapmaterial_p.h
new file mode 100644
index 000000000..3316044ff
--- /dev/null
+++ b/src/extras/defaults/qnormaldiffusespecularmapmaterial_p.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_P_H
+#define QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QAbstractTexture;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QNormalDiffuseSpecularMapMaterial;
+
+class QNormalDiffuseSpecularMapMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QNormalDiffuseSpecularMapMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleNormalChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleTextureScaleChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_normalDiffuseSpecularEffect;
+ Qt3DRender::QAbstractTexture *m_diffuseTexture;
+ Qt3DRender::QAbstractTexture *m_normalTexture;
+ Qt3DRender::QAbstractTexture *m_specularTexture;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_normalParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_textureScaleParameter;
+ Qt3DRender::QTechnique *m_normalDiffuseSpecularGL3Technique;
+ Qt3DRender::QTechnique *m_normalDiffuseSpecularGL2Technique;
+ Qt3DRender::QTechnique *m_normalDiffuseSpecularES2Technique;
+ Qt3DRender::QRenderPass *m_normalDiffuseSpecularGL3RenderPass;
+ Qt3DRender::QRenderPass *m_normalDiffuseSpecularGL2RenderPass;
+ Qt3DRender::QRenderPass *m_normalDiffuseSpecularES2RenderPass;
+ Qt3DRender::QShaderProgram *m_normalDiffuseSpecularGL3Shader;
+ Qt3DRender::QShaderProgram *m_normalDiffuseSpecularGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QNormalDiffuseSpecularMapMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QNORMALDIFFUSESPECULARMAPMATERIAL_P_H
+
diff --git a/src/extras/defaults/qpervertexcolormaterial.cpp b/src/extras/defaults/qpervertexcolormaterial.cpp
new file mode 100644
index 000000000..2a301cd3f
--- /dev/null
+++ b/src/extras/defaults/qpervertexcolormaterial.cpp
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Lorenz Esch (TU Ilmenau).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpervertexcolormaterial.h"
+#include "qpervertexcolormaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QPerVertexColorMaterialPrivate::QPerVertexColorMaterialPrivate()
+ : QMaterialPrivate()
+ , m_vertexEffect(new QEffect())
+ , m_vertexGL3Technique(new QTechnique())
+ , m_vertexGL2Technique(new QTechnique())
+ , m_vertexES2Technique(new QTechnique())
+ , m_vertexGL3RenderPass(new QRenderPass())
+ , m_vertexGL2RenderPass(new QRenderPass())
+ , m_vertexES2RenderPass(new QRenderPass())
+ , m_vertexGL3Shader(new QShaderProgram())
+ , m_vertexGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+}
+
+/*!
+ \class Qt3DRender::QPerVertexColorMaterial
+ \brief The QPerVertexColorMaterial class provides a default implementation for rendering the color properties set for each vertex.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ This lighting effect is based on the combination of 2 lighting components ambient and diffuse. Ambient is set by the vertex color.
+ Diffuse takes in account the normal distribution of each vertex.
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rough surface reflections with the lights
+ \endlist
+
+ This material uses an effect with a single render pass approach and forms fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ \fn Qt3DRender::QPerVertexColorMaterial::QPerVertexColorMaterial(Qt3DCore::QNode *parent)
+
+ Constructs a new QPerVertexColorMaterial instance with parent object \a parent.
+*/
+QPerVertexColorMaterial::QPerVertexColorMaterial(QNode *parent)
+ : QMaterial(*new QPerVertexColorMaterialPrivate, parent)
+{
+ Q_D(QPerVertexColorMaterial);
+ d->init();
+}
+
+/*!
+ \fn Qt3DRender::QPerVertexColorMaterial::~QPerVertexColorMaterial()
+
+ Destroys the QPerVertexColorMaterial
+*/
+QPerVertexColorMaterial::~QPerVertexColorMaterial()
+{
+}
+
+// TODO: Define how lights are proties are set in the shaders. Ideally using a QShaderData
+void QPerVertexColorMaterialPrivate::init()
+{
+ m_vertexGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/pervertexcolor.vert"))));
+ m_vertexGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/pervertexcolor.frag"))));
+ m_vertexGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/pervertexcolor.vert"))));
+ m_vertexGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/pervertexcolor.frag"))));
+
+ m_vertexGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_vertexGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_vertexGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_vertexGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_vertexGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_vertexGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_vertexGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_vertexGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_vertexES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_vertexES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_vertexES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_vertexES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QPerVertexColorMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_vertexGL3Technique->addFilterKey(m_filterKey);
+ m_vertexGL2Technique->addFilterKey(m_filterKey);
+ m_vertexES2Technique->addFilterKey(m_filterKey);
+
+ m_vertexGL3RenderPass->setShaderProgram(m_vertexGL3Shader);
+ m_vertexGL2RenderPass->setShaderProgram(m_vertexGL2ES2Shader);
+ m_vertexES2RenderPass->setShaderProgram(m_vertexGL2ES2Shader);
+
+ m_vertexGL3Technique->addRenderPass(m_vertexGL3RenderPass);
+ m_vertexGL2Technique->addRenderPass(m_vertexGL2RenderPass);
+ m_vertexES2Technique->addRenderPass(m_vertexES2RenderPass);
+
+ m_vertexEffect->addTechnique(m_vertexGL3Technique);
+ m_vertexEffect->addTechnique(m_vertexGL2Technique);
+ m_vertexEffect->addTechnique(m_vertexES2Technique);
+
+ q->setEffect(m_vertexEffect);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qpervertexcolormaterial.h b/src/extras/defaults/qpervertexcolormaterial.h
new file mode 100644
index 000000000..86d169715
--- /dev/null
+++ b/src/extras/defaults/qpervertexcolormaterial.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Lorenz Esch (TU Ilmenau).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_H
+#define QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QPerVertexColorMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QPerVertexColorMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+
+public:
+ explicit QPerVertexColorMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QPerVertexColorMaterial();
+
+private:
+ Q_DECLARE_PRIVATE(QPerVertexColorMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_H
diff --git a/src/extras/defaults/qpervertexcolormaterial_p.h b/src/extras/defaults/qpervertexcolormaterial_p.h
new file mode 100644
index 000000000..678353525
--- /dev/null
+++ b/src/extras/defaults/qpervertexcolormaterial_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Lorenz Esch (TU Ilmenau).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_P_H
+#define QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QPerVertexColorMaterial;
+
+class QPerVertexColorMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QPerVertexColorMaterialPrivate();
+
+ void init();
+
+ Qt3DRender::QEffect *m_vertexEffect;
+ Qt3DRender::QTechnique *m_vertexGL3Technique;
+ Qt3DRender::QTechnique *m_vertexGL2Technique;
+ Qt3DRender::QTechnique *m_vertexES2Technique;
+ Qt3DRender::QRenderPass *m_vertexGL3RenderPass;
+ Qt3DRender::QRenderPass *m_vertexGL2RenderPass;
+ Qt3DRender::QRenderPass *m_vertexES2RenderPass;
+ Qt3DRender::QShaderProgram *m_vertexGL3Shader;
+ Qt3DRender::QShaderProgram *m_vertexGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QPerVertexColorMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPERVERTEXCOLORMATERIAL_P_H
+
diff --git a/src/extras/defaults/qphongalphamaterial.cpp b/src/extras/defaults/qphongalphamaterial.cpp
new file mode 100644
index 000000000..9d80751c5
--- /dev/null
+++ b/src/extras/defaults/qphongalphamaterial.cpp
@@ -0,0 +1,327 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qphongalphamaterial.h"
+#include "qphongalphamaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/qblendequation.h>
+#include <Qt3DRender/qblendequationarguments.h>
+#include <Qt3DRender/qnodepthmask.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QPhongAlphaMaterialPrivate::QPhongAlphaMaterialPrivate()
+ : QMaterialPrivate()
+ , m_phongEffect(new QEffect())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_alphaParameter(new QParameter(QStringLiteral("alpha"), 0.5f))
+ , m_phongAlphaGL3Technique(new QTechnique())
+ , m_phongAlphaGL2Technique(new QTechnique())
+ , m_phongAlphaES2Technique(new QTechnique())
+ , m_phongAlphaGL3RenderPass(new QRenderPass())
+ , m_phongAlphaGL2RenderPass(new QRenderPass())
+ , m_phongAlphaES2RenderPass(new QRenderPass())
+ , m_phongAlphaGL3Shader(new QShaderProgram())
+ , m_phongAlphaGL2ES2Shader(new QShaderProgram())
+ , m_noDepthMask(new QNoDepthMask())
+ , m_blendState(new QBlendEquationArguments())
+ , m_blendEquation(new QBlendEquation())
+ , m_filterKey(new QFilterKey)
+{
+}
+
+// TODO: Define how lights are properties are set in the shaders. Ideally using a QShaderData
+void QPhongAlphaMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongAlphaMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongAlphaMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongAlphaMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongAlphaMaterialPrivate::handleShininessChanged);
+ connect(m_alphaParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongAlphaMaterialPrivate::handleAlphaChanged);
+
+ m_phongAlphaGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
+ m_phongAlphaGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phongalpha.frag"))));
+ m_phongAlphaGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
+ m_phongAlphaGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phongalpha.frag"))));
+
+ m_phongAlphaGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongAlphaGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_phongAlphaGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_phongAlphaGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_phongAlphaGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongAlphaGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongAlphaGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongAlphaGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_phongAlphaES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_phongAlphaES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongAlphaES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongAlphaES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ Q_Q(QPhongAlphaMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_phongAlphaGL3Technique->addFilterKey(m_filterKey);
+ m_phongAlphaGL2Technique->addFilterKey(m_filterKey);
+ m_phongAlphaES2Technique->addFilterKey(m_filterKey);
+
+ m_blendState->setSourceRgb(QBlendEquationArguments::SourceAlpha);
+ m_blendState->setDestinationRgb(QBlendEquationArguments::OneMinusSourceAlpha);
+ m_blendEquation->setBlendFunction(QBlendEquation::Add);
+
+ m_phongAlphaGL3RenderPass->setShaderProgram(m_phongAlphaGL3Shader);
+ m_phongAlphaGL2RenderPass->setShaderProgram(m_phongAlphaGL2ES2Shader);
+ m_phongAlphaES2RenderPass->setShaderProgram(m_phongAlphaGL2ES2Shader);
+
+ m_phongAlphaGL3RenderPass->addRenderState(m_noDepthMask);
+ m_phongAlphaGL3RenderPass->addRenderState(m_blendState);
+ m_phongAlphaGL3RenderPass->addRenderState(m_blendEquation);
+
+ m_phongAlphaGL2RenderPass->addRenderState(m_noDepthMask);
+ m_phongAlphaGL2RenderPass->addRenderState(m_blendState);
+ m_phongAlphaGL2RenderPass->addRenderState(m_blendEquation);
+
+ m_phongAlphaES2RenderPass->addRenderState(m_noDepthMask);
+ m_phongAlphaES2RenderPass->addRenderState(m_blendState);
+ m_phongAlphaES2RenderPass->addRenderState(m_blendEquation);
+
+ m_phongAlphaGL3Technique->addRenderPass(m_phongAlphaGL3RenderPass);
+ m_phongAlphaGL2Technique->addRenderPass(m_phongAlphaGL2RenderPass);
+ m_phongAlphaES2Technique->addRenderPass(m_phongAlphaES2RenderPass);
+
+ m_phongEffect->addTechnique(m_phongAlphaGL3Technique);
+ m_phongEffect->addTechnique(m_phongAlphaGL2Technique);
+ m_phongEffect->addTechnique(m_phongAlphaES2Technique);
+
+ m_phongEffect->addParameter(m_ambientParameter);
+ m_phongEffect->addParameter(m_diffuseParameter);
+ m_phongEffect->addParameter(m_specularParameter);
+ m_phongEffect->addParameter(m_shininessParameter);
+ m_phongEffect->addParameter(m_alphaParameter);
+
+ q->setEffect(m_phongEffect);
+}
+
+void QPhongAlphaMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QPhongAlphaMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QPhongAlphaMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QPhongAlphaMaterial);
+ emit q->diffuseChanged(var.value<QColor>());
+}
+
+void QPhongAlphaMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QPhongAlphaMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QPhongAlphaMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QPhongAlphaMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+void QPhongAlphaMaterialPrivate::handleAlphaChanged(const QVariant &var)
+{
+ Q_Q(QPhongAlphaMaterial);
+ emit q->alphaChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QPhongAlphaMaterial
+
+ \brief The QPhongAlphaMaterial class provides a default implementation of
+ the phong lighting effect with alpha.
+ \inmodule Qt3DRenderer
+ \since 5.5
+
+ The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \li Alpha is the transparency of the surface between 0 (fully transparent) and 1 (opaque).
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ \fn Qt3DRender::QPhongAlphaMaterial::QPhongAlphaMaterial(Qt3DCore::QNode *parent)
+
+ Constructs a new QPhongAlphaMaterial instance with parent object \a parent.
+*/
+QPhongAlphaMaterial::QPhongAlphaMaterial(QNode *parent)
+ : QMaterial(*new QPhongAlphaMaterialPrivate, parent)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->init();
+}
+
+/*!
+ Destroys the QPhongAlphaMaterial.
+*/
+QPhongAlphaMaterial::~QPhongAlphaMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QPhongAlphaMaterial::ambient
+
+ Holds the ambient color.
+*/
+QColor QPhongAlphaMaterial::ambient() const
+{
+ Q_D(const QPhongAlphaMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongAlphaMaterial::diffuse
+
+ Holds the diffuse color.
+*/
+QColor QPhongAlphaMaterial::diffuse() const
+{
+ Q_D(const QPhongAlphaMaterial);
+ return d->m_diffuseParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongAlphaMaterial::specular
+
+ Holds the specular color.
+*/
+QColor QPhongAlphaMaterial::specular() const
+{
+ Q_D(const QPhongAlphaMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongAlphaMaterial::shininess
+
+ Holds the shininess exponent.
+*/
+float QPhongAlphaMaterial::shininess() const
+{
+ Q_D(const QPhongAlphaMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+/*!
+ \property Qt3DRender::QPhongAlphaMaterial::alpha
+
+ Holds the alpha component of the object which varies between 0 and 1.
+
+ \note: default value is 0.5f
+*/
+float QPhongAlphaMaterial::alpha() const
+{
+ Q_D(const QPhongAlphaMaterial);
+ return d->m_alphaParameter->value().toFloat();
+}
+
+void QPhongAlphaMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QPhongAlphaMaterial::setDiffuse(const QColor &diffuse)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->m_diffuseParameter->setValue(diffuse);
+}
+
+void QPhongAlphaMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->m_specularParameter->setValue(specular);
+}
+
+void QPhongAlphaMaterial::setShininess(float shininess)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+void QPhongAlphaMaterial::setAlpha(float alpha)
+{
+ Q_D(QPhongAlphaMaterial);
+ d->m_alphaParameter->setValue(alpha);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qphongalphamaterial.h b/src/extras/defaults/qphongalphamaterial.h
new file mode 100644
index 000000000..d4d46f756
--- /dev/null
+++ b/src/extras/defaults/qphongalphamaterial.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPHONGALPHAMATERIAL_H
+#define QT3DEXTRAS_QPHONGALPHAMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QPhongAlphaMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QPhongAlphaMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(float alpha READ alpha WRITE setAlpha NOTIFY alphaChanged)
+
+public:
+ explicit QPhongAlphaMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QPhongAlphaMaterial();
+
+ QColor ambient() const;
+ QColor diffuse() const;
+ QColor specular() const;
+ float shininess() const;
+ float alpha() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setDiffuse(const QColor &diffuse);
+ void setSpecular(const QColor &specular);
+ void setShininess(float shininess);
+ void setAlpha(float alpha);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(const QColor &diffuse);
+ void specularChanged(const QColor &specular);
+ void shininessChanged(float shininess);
+ void alphaChanged(float alpha);
+
+private:
+ Q_DECLARE_PRIVATE(QPhongAlphaMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPHONGALPHAMATERIAL_H
diff --git a/src/extras/defaults/qphongalphamaterial_p.h b/src/extras/defaults/qphongalphamaterial_p.h
new file mode 100644
index 000000000..623eca0ea
--- /dev/null
+++ b/src/extras/defaults/qphongalphamaterial_p.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPHONGALPHAMATERIAL_P_H
+#define QT3DEXTRAS_QPHONGALPHAMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+class QNoDepthMask;
+class QBlendEquationArguments;
+class QBlendEquation;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QPhongAlphaMaterial;
+
+class QPhongAlphaMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QPhongAlphaMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+ void handleAlphaChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_phongEffect;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QParameter *m_alphaParameter;
+ Qt3DRender::QTechnique *m_phongAlphaGL3Technique;
+ Qt3DRender::QTechnique *m_phongAlphaGL2Technique;
+ Qt3DRender::QTechnique *m_phongAlphaES2Technique;
+ Qt3DRender::QRenderPass *m_phongAlphaGL3RenderPass;
+ Qt3DRender::QRenderPass *m_phongAlphaGL2RenderPass;
+ Qt3DRender::QRenderPass *m_phongAlphaES2RenderPass;
+ Qt3DRender::QShaderProgram *m_phongAlphaGL3Shader;
+ Qt3DRender::QShaderProgram *m_phongAlphaGL2ES2Shader;
+ Qt3DRender::QNoDepthMask *m_noDepthMask;
+ Qt3DRender::QBlendEquationArguments *m_blendState;
+ Qt3DRender::QBlendEquation *m_blendEquation;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QPhongAlphaMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPHONGALPHAMATERIAL_P_H
+
diff --git a/src/extras/defaults/qphongmaterial.cpp b/src/extras/defaults/qphongmaterial.cpp
new file mode 100644
index 000000000..f9c51bae8
--- /dev/null
+++ b/src/extras/defaults/qphongmaterial.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qphongmaterial.h"
+#include "qphongmaterial_p.h"
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DRender/qshaderprogram.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <QUrl>
+#include <QVector3D>
+#include <QVector4D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QPhongMaterialPrivate::QPhongMaterialPrivate()
+ : QMaterialPrivate()
+ , m_phongEffect(new QEffect())
+ , m_ambientParameter(new QParameter(QStringLiteral("ka"), QColor::fromRgbF(0.05f, 0.05f, 0.05f, 1.0f)))
+ , m_diffuseParameter(new QParameter(QStringLiteral("kd"), QColor::fromRgbF(0.7f, 0.7f, 0.7f, 1.0f)))
+ , m_specularParameter(new QParameter(QStringLiteral("ks"), QColor::fromRgbF(0.01f, 0.01f, 0.01f, 1.0f)))
+ , m_shininessParameter(new QParameter(QStringLiteral("shininess"), 150.0f))
+ , m_phongGL3Technique(new QTechnique())
+ , m_phongGL2Technique(new QTechnique())
+ , m_phongES2Technique(new QTechnique())
+ , m_phongGL3RenderPass(new QRenderPass())
+ , m_phongGL2RenderPass(new QRenderPass())
+ , m_phongES2RenderPass(new QRenderPass())
+ , m_phongGL3Shader(new QShaderProgram())
+ , m_phongGL2ES2Shader(new QShaderProgram())
+ , m_filterKey(new QFilterKey)
+{
+}
+
+void QPhongMaterialPrivate::init()
+{
+ connect(m_ambientParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongMaterialPrivate::handleAmbientChanged);
+ connect(m_diffuseParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongMaterialPrivate::handleDiffuseChanged);
+ connect(m_specularParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongMaterialPrivate::handleSpecularChanged);
+ connect(m_shininessParameter, &Qt3DRender::QParameter::valueChanged,
+ this, &QPhongMaterialPrivate::handleShininessChanged);
+
+
+ m_phongGL3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.vert"))));
+ m_phongGL3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/phong.frag"))));
+ m_phongGL2ES2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.vert"))));
+ m_phongGL2ES2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/phong.frag"))));
+
+ m_phongGL3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongGL3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_phongGL3Technique->graphicsApiFilter()->setMinorVersion(1);
+ m_phongGL3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_phongGL2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_phongGL2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongGL2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongGL2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_phongES2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_phongES2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_phongES2Technique->graphicsApiFilter()->setMinorVersion(0);
+ m_phongES2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_phongGL3RenderPass->setShaderProgram(m_phongGL3Shader);
+ m_phongGL2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
+ m_phongES2RenderPass->setShaderProgram(m_phongGL2ES2Shader);
+
+ m_phongGL3Technique->addRenderPass(m_phongGL3RenderPass);
+ m_phongGL2Technique->addRenderPass(m_phongGL2RenderPass);
+ m_phongES2Technique->addRenderPass(m_phongES2RenderPass);
+
+ Q_Q(QPhongMaterial);
+ m_filterKey->setParent(q);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_phongGL3Technique->addFilterKey(m_filterKey);
+ m_phongGL2Technique->addFilterKey(m_filterKey);
+ m_phongES2Technique->addFilterKey(m_filterKey);
+
+ m_phongEffect->addTechnique(m_phongGL3Technique);
+ m_phongEffect->addTechnique(m_phongGL2Technique);
+ m_phongEffect->addTechnique(m_phongES2Technique);
+
+ m_phongEffect->addParameter(m_ambientParameter);
+ m_phongEffect->addParameter(m_diffuseParameter);
+ m_phongEffect->addParameter(m_specularParameter);
+ m_phongEffect->addParameter(m_shininessParameter);
+
+ q->setEffect(m_phongEffect);
+}
+
+void QPhongMaterialPrivate::handleAmbientChanged(const QVariant &var)
+{
+ Q_Q(QPhongMaterial);
+ emit q->ambientChanged(var.value<QColor>());
+}
+
+void QPhongMaterialPrivate::handleDiffuseChanged(const QVariant &var)
+{
+ Q_Q(QPhongMaterial);
+ emit q->diffuseChanged(var.value<QColor>());
+}
+
+void QPhongMaterialPrivate::handleSpecularChanged(const QVariant &var)
+{
+ Q_Q(QPhongMaterial);
+ emit q->specularChanged(var.value<QColor>());
+}
+
+void QPhongMaterialPrivate::handleShininessChanged(const QVariant &var)
+{
+ Q_Q(QPhongMaterial);
+ emit q->shininessChanged(var.toFloat());
+}
+
+/*!
+ \class Qt3DRender::QPhongMaterial
+ \brief The QPhongMaterial class provides a default implementation of the phong lighting effect.
+ \inmodule Qt3DRender
+ \since 5.5
+
+ The phong lighting effect is based on the combination of 3 lighting components ambient, diffuse and specular.
+ The relative strengths of these components is controlled by means of their reflectivity coefficients which are modelled as RGB triplets:
+
+ \list
+ \li Ambient is the color that is emitted by an object without any other light source.
+ \li Diffuse is the color that is emitted for rought surface reflections with the lights.
+ \li Specular is the color emitted for shiny surface reflections with the lights.
+ \li The shininess of a surface is controlled by a float property.
+ \endlist
+
+ This material uses an effect with a single render pass approach and performs per fragment lighting.
+ Techniques are provided for OpenGL 2, OpenGL 3 or above as well as OpenGL ES 2.
+*/
+
+/*!
+ \fn Qt3DRender::QPhongMaterial::QPhongMaterial(Qt3DCore::QNode *parent)
+
+ Constructs a new QPhongMaterial instance with parent object \a parent.
+*/
+QPhongMaterial::QPhongMaterial(QNode *parent)
+ : QMaterial(*new QPhongMaterialPrivate, parent)
+{
+ Q_D(QPhongMaterial);
+ d->init();
+}
+
+/*!
+ \fn Qt3DRender::QPhongMaterial::~QPhongMaterial()
+
+ Destroys the QPhongMaterial.
+*/
+QPhongMaterial::~QPhongMaterial()
+{
+}
+
+/*!
+ \property Qt3DRender::QPhongMaterial::ambient
+
+ Holds the ambient color.
+*/
+QColor QPhongMaterial::ambient() const
+{
+ Q_D(const QPhongMaterial);
+ return d->m_ambientParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongMaterial::diffuse
+
+ Holds the diffuse color.
+*/
+QColor QPhongMaterial::diffuse() const
+{
+ Q_D(const QPhongMaterial);
+ return d->m_diffuseParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongMaterial::specular
+
+ Holds the specular color.
+*/
+QColor QPhongMaterial::specular() const
+{
+ Q_D(const QPhongMaterial);
+ return d->m_specularParameter->value().value<QColor>();
+}
+
+/*!
+ \property Qt3DRender::QPhongMaterial::shininess
+
+ Holds the shininess exponent.
+*/
+float QPhongMaterial::shininess() const
+{
+ Q_D(const QPhongMaterial);
+ return d->m_shininessParameter->value().toFloat();
+}
+
+void QPhongMaterial::setAmbient(const QColor &ambient)
+{
+ Q_D(QPhongMaterial);
+ d->m_ambientParameter->setValue(ambient);
+}
+
+void QPhongMaterial::setDiffuse(const QColor &diffuse)
+{
+ Q_D(QPhongMaterial);
+ d->m_diffuseParameter->setValue(diffuse);
+}
+
+void QPhongMaterial::setSpecular(const QColor &specular)
+{
+ Q_D(QPhongMaterial);
+ d->m_specularParameter->setValue(specular);
+}
+
+void QPhongMaterial::setShininess(float shininess)
+{
+ Q_D(QPhongMaterial);
+ d->m_shininessParameter->setValue(shininess);
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qphongmaterial.h b/src/extras/defaults/qphongmaterial.h
new file mode 100644
index 000000000..112482dee
--- /dev/null
+++ b/src/extras/defaults/qphongmaterial.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPHONGMATERIAL_H
+#define QT3DEXTRAS_QPHONGMATERIAL_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qmaterial.h>
+#include <QColor>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QPhongMaterialPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QPhongMaterial : public Qt3DRender::QMaterial
+{
+ Q_OBJECT
+ Q_PROPERTY(QColor ambient READ ambient WRITE setAmbient NOTIFY ambientChanged)
+ Q_PROPERTY(QColor diffuse READ diffuse WRITE setDiffuse NOTIFY diffuseChanged)
+ Q_PROPERTY(QColor specular READ specular WRITE setSpecular NOTIFY specularChanged)
+ Q_PROPERTY(float shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+
+public:
+ explicit QPhongMaterial(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QPhongMaterial();
+
+ QColor ambient() const;
+ QColor diffuse() const;
+ QColor specular() const;
+ float shininess() const;
+
+public Q_SLOTS:
+ void setAmbient(const QColor &ambient);
+ void setDiffuse(const QColor &diffuse);
+ void setSpecular(const QColor &specular);
+ void setShininess(float shininess);
+
+Q_SIGNALS:
+ void ambientChanged(const QColor &ambient);
+ void diffuseChanged(const QColor &diffuse);
+ void specularChanged(const QColor &specular);
+ void shininessChanged(float shininess);
+
+private:
+ Q_DECLARE_PRIVATE(QPhongMaterial)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPHONGMATERIAL_H
diff --git a/src/extras/defaults/qphongmaterial_p.h b/src/extras/defaults/qphongmaterial_p.h
new file mode 100644
index 000000000..bc6d0ce44
--- /dev/null
+++ b/src/extras/defaults/qphongmaterial_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPHONGMATERIAL_P_H
+#define QT3DEXTRAS_QPHONGMATERIAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qmaterial_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QEffect;
+class QTechnique;
+class QParameter;
+class QShaderProgram;
+class QRenderPass;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QPhongMaterial;
+
+class QPhongMaterialPrivate : public Qt3DRender::QMaterialPrivate
+{
+public:
+ QPhongMaterialPrivate();
+
+ void init();
+
+ void handleAmbientChanged(const QVariant &var);
+ void handleDiffuseChanged(const QVariant &var);
+ void handleSpecularChanged(const QVariant &var);
+ void handleShininessChanged(const QVariant &var);
+
+ Qt3DRender::QEffect *m_phongEffect;
+ Qt3DRender::QParameter *m_ambientParameter;
+ Qt3DRender::QParameter *m_diffuseParameter;
+ Qt3DRender::QParameter *m_specularParameter;
+ Qt3DRender::QParameter *m_shininessParameter;
+ Qt3DRender::QTechnique *m_phongGL3Technique;
+ Qt3DRender::QTechnique *m_phongGL2Technique;
+ Qt3DRender::QTechnique *m_phongES2Technique;
+ Qt3DRender::QRenderPass *m_phongGL3RenderPass;
+ Qt3DRender::QRenderPass *m_phongGL2RenderPass;
+ Qt3DRender::QRenderPass *m_phongES2RenderPass;
+ Qt3DRender::QShaderProgram *m_phongGL3Shader;
+ Qt3DRender::QShaderProgram *m_phongGL2ES2Shader;
+ Qt3DRender::QFilterKey *m_filterKey;
+
+ Q_DECLARE_PUBLIC(QPhongMaterial)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPHONGMATERIAL_P_H
+
diff --git a/src/extras/defaults/qskyboxentity.cpp b/src/extras/defaults/qskyboxentity.cpp
new file mode 100644
index 000000000..973532fff
--- /dev/null
+++ b/src/extras/defaults/qskyboxentity.cpp
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qskyboxentity.h"
+#include "qskyboxentity_p.h"
+
+#include <Qt3DCore/qtransform.h>
+#include <Qt3DRender/qfilterkey.h>
+#include <Qt3DRender/qeffect.h>
+#include <Qt3DRender/qtexture.h>
+#include <Qt3DRender/qmaterial.h>
+#include <Qt3DRender/qcullface.h>
+#include <Qt3DRender/qdepthtest.h>
+#include <Qt3DRender/qparameter.h>
+#include <Qt3DRender/qtechnique.h>
+#include <Qt3DExtras/qcuboidmesh.h>
+#include <Qt3DRender/qrenderpass.h>
+#include <Qt3DRender/qgraphicsapifilter.h>
+#include <Qt3DRender/qshaderprogram.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DCore;
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+QSkyboxEntityPrivate::QSkyboxEntityPrivate()
+ : QEntityPrivate()
+ , m_effect(new QEffect())
+ , m_material(new QMaterial())
+ , m_skyboxTexture(new QTextureCubeMap())
+ , m_gl3Shader(new QShaderProgram())
+ , m_gl2es2Shader(new QShaderProgram())
+ , m_gl2Technique(new QTechnique())
+ , m_es2Technique(new QTechnique())
+ , m_gl3Technique(new QTechnique())
+ , m_filterKey(new QFilterKey)
+ , m_gl2RenderPass(new QRenderPass())
+ , m_es2RenderPass(new QRenderPass())
+ , m_gl3RenderPass(new QRenderPass())
+ , m_mesh(new QCuboidMesh())
+ , m_transform(new Qt3DCore::QTransform())
+ , m_textureParameter(new QParameter(QStringLiteral("skyboxTexture"), m_skyboxTexture))
+ , m_posXImage(new QTextureImage())
+ , m_posYImage(new QTextureImage())
+ , m_posZImage(new QTextureImage())
+ , m_negXImage(new QTextureImage())
+ , m_negYImage(new QTextureImage())
+ , m_negZImage(new QTextureImage())
+ , m_extension(QStringLiteral(".png"))
+{
+}
+
+/*!
+ * \internal
+ */
+void QSkyboxEntityPrivate::init()
+{
+ m_gl3Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/skybox.vert"))));
+ m_gl3Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/gl3/skybox.frag"))));
+ m_gl2es2Shader->setVertexShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/skybox.vert"))));
+ m_gl2es2Shader->setFragmentShaderCode(QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/es2/skybox.frag"))));
+
+ m_gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_gl3Technique->graphicsApiFilter()->setMajorVersion(3);
+ m_gl3Technique->graphicsApiFilter()->setMajorVersion(1);
+ m_gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);
+
+ m_gl2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
+ m_gl2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_gl2Technique->graphicsApiFilter()->setMajorVersion(0);
+ m_gl2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_es2Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGLES);
+ m_es2Technique->graphicsApiFilter()->setMajorVersion(2);
+ m_es2Technique->graphicsApiFilter()->setMajorVersion(0);
+ m_es2Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::NoProfile);
+
+ m_filterKey->setParent(m_effect);
+ m_filterKey->setName(QStringLiteral("renderingStyle"));
+ m_filterKey->setValue(QStringLiteral("forward"));
+
+ m_gl3Technique->addFilterKey(m_filterKey);
+ m_gl2Technique->addFilterKey(m_filterKey);
+ m_es2Technique->addFilterKey(m_filterKey);
+
+ m_gl3RenderPass->setShaderProgram(m_gl3Shader);
+ m_gl2RenderPass->setShaderProgram(m_gl2es2Shader);
+ m_es2RenderPass->setShaderProgram(m_gl2es2Shader);
+
+ QCullFace *cullFront = new QCullFace();
+ cullFront->setMode(QCullFace::Front);
+ QDepthTest *depthTest = new QDepthTest();
+ depthTest->setDepthFunction(QDepthTest::LessOrEqual);
+
+ m_gl3RenderPass->addRenderState(cullFront);
+ m_gl3RenderPass->addRenderState(depthTest);
+ m_gl2RenderPass->addRenderState(cullFront);
+ m_gl2RenderPass->addRenderState(depthTest);
+ m_es2RenderPass->addRenderState(cullFront);
+ m_es2RenderPass->addRenderState(depthTest);
+
+ m_gl3Technique->addRenderPass(m_gl3RenderPass);
+ m_gl2Technique->addRenderPass(m_gl2RenderPass);
+ m_es2Technique->addRenderPass(m_es2RenderPass);
+
+ m_effect->addTechnique(m_gl3Technique);
+ m_effect->addTechnique(m_gl2Technique);
+ m_effect->addTechnique(m_es2Technique);
+
+ m_material->setEffect(m_effect);
+ m_material->addParameter(m_textureParameter);
+
+ m_mesh->setXYMeshResolution(QSize(2, 2));
+ m_mesh->setXZMeshResolution(QSize(2, 2));
+ m_mesh->setYZMeshResolution(QSize(2, 2));
+
+ m_posXImage->setFace(QTextureCubeMap::CubeMapPositiveX);
+ m_posYImage->setFace(QTextureCubeMap::CubeMapPositiveY);
+ m_posZImage->setFace(QTextureCubeMap::CubeMapPositiveZ);
+ m_negXImage->setFace(QTextureCubeMap::CubeMapNegativeX);
+ m_negYImage->setFace(QTextureCubeMap::CubeMapNegativeY);
+ m_negZImage->setFace(QTextureCubeMap::CubeMapNegativeZ);
+
+ m_skyboxTexture->setMagnificationFilter(QTextureCubeMap::Linear);
+ m_skyboxTexture->setMinificationFilter(QTextureCubeMap::Linear);
+ m_skyboxTexture->setGenerateMipMaps(false);
+ m_skyboxTexture->setWrapMode(QTextureWrapMode(QTextureWrapMode::ClampToEdge));
+
+ m_skyboxTexture->addTextureImage(m_posXImage);
+ m_skyboxTexture->addTextureImage(m_posYImage);
+ m_skyboxTexture->addTextureImage(m_posZImage);
+ m_skyboxTexture->addTextureImage(m_negXImage);
+ m_skyboxTexture->addTextureImage(m_negYImage);
+ m_skyboxTexture->addTextureImage(m_negZImage);
+
+ q_func()->addComponent(m_mesh);
+ q_func()->addComponent(m_material);
+ q_func()->addComponent(m_transform);
+}
+
+/*!
+ * \internal
+ */
+void QSkyboxEntityPrivate::reloadTexture()
+{
+ m_posXImage->setSource(QUrl(m_baseName + QStringLiteral("_posx") + m_extension));
+ m_posYImage->setSource(QUrl(m_baseName + QStringLiteral("_posy") + m_extension));
+ m_posZImage->setSource(QUrl(m_baseName + QStringLiteral("_posz") + m_extension));
+ m_negXImage->setSource(QUrl(m_baseName + QStringLiteral("_negx") + m_extension));
+ m_negYImage->setSource(QUrl(m_baseName + QStringLiteral("_negy") + m_extension));
+ m_negZImage->setSource(QUrl(m_baseName + QStringLiteral("_negz") + m_extension));
+}
+
+/*!
+ * \class Qt3DRender::QSkyboxEntity
+ * \inmodule Qt3DRender
+ *
+ * \brief Qt3DRender::QSkyboxEntity is a convenience Qt3DCore::QEntity subclass that can
+ * be used to insert a skybox in a 3D scene.
+ *
+ * By specifying a base name and an extension, Qt3DCore::QSkyboxEntity
+ * will take care of building a TextureCubeMap to be rendered at runtime. The
+ * images in the source directory should match the pattern:
+ * \b base name + * "_posx|_posy|_posz|_negx|_negy|_negz" + extension
+ *
+ * By default the extension defaults to .png.
+ *
+ * \note Please note that you shouldn't try to render skybox with an
+ * orthographic projection.
+ *
+ * \since 5.5
+ */
+
+/*!
+ * Constructs a new Qt3DCore::QSkyboxEntity object with \a parent as parent.
+ */
+QSkyboxEntity::QSkyboxEntity(QNode *parent)
+ : QEntity(*new QSkyboxEntityPrivate, parent)
+{
+ d_func()->init();
+}
+
+QSkyboxEntity::~QSkyboxEntity()
+{
+ QNode::cleanup();
+}
+
+/*!
+ * Sets the base name to \a baseName.
+ */
+void QSkyboxEntity::setBaseName(const QString &baseName)
+{
+ Q_D(QSkyboxEntity);
+ if (baseName != d->m_baseName) {
+ d->m_baseName = baseName;
+ emit sourceDirectoryChanged(baseName);
+ d->reloadTexture();
+ }
+}
+/*!
+ * Returns the base name.
+ */
+QString QSkyboxEntity::baseName() const
+{
+ Q_D(const QSkyboxEntity);
+ return d->m_baseName;
+}
+
+/*!
+ * Sets the extension to \a extension.
+ */
+void QSkyboxEntity::setExtension(const QString &extension)
+{
+ Q_D(QSkyboxEntity);
+ if (extension != d->m_extension) {
+ d->m_extension = extension;
+ emit extensionChanged(extension);
+ d->reloadTexture();
+ }
+}
+
+/*!
+ * Returns the extension
+ */
+QString QSkyboxEntity::extension() const
+{
+ Q_D(const QSkyboxEntity);
+ return d->m_extension;
+}
+
+/*!
+ * Sets the camera position to \a cameraPosition.
+ */
+void QSkyboxEntity::setCameraPosition(const QVector3D &cameraPosition)
+{
+ Q_D(QSkyboxEntity);
+ if (cameraPosition != d->m_position) {
+ d->m_position = cameraPosition;
+ d->m_transform->setTranslation(d->m_position);
+ emit cameraPositionChanged(cameraPosition);
+ }
+}
+
+/*!
+ * Returns the camera position.
+ */
+QVector3D QSkyboxEntity::cameraPosition() const
+{
+ Q_D(const QSkyboxEntity);
+ return d->m_position;
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/defaults/qskyboxentity.h b/src/extras/defaults/qskyboxentity.h
new file mode 100644
index 000000000..7112bff4c
--- /dev/null
+++ b/src/extras/defaults/qskyboxentity.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QSKYBOXENTITY_H
+#define QT3DEXTRAS_QSKYBOXENTITY_H
+
+#include <Qt3DCore/qentity.h>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QSkyboxEntityPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QSkyboxEntity : public Qt3DCore::QEntity
+{
+ Q_OBJECT
+public:
+ explicit QSkyboxEntity(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QSkyboxEntity();
+
+ void setBaseName(const QString &path);
+ QString baseName() const;
+
+ void setExtension(const QString &extension);
+ QString extension() const;
+
+ void setCameraPosition(const QVector3D &cameraPosition);
+ QVector3D cameraPosition() const;
+
+Q_SIGNALS:
+ void sourceDirectoryChanged(const QString &path);
+ void extensionChanged(const QString &extension);
+ void cameraPositionChanged(const QVector3D &cameraPosition);
+
+private:
+ Q_DECLARE_PRIVATE(QSkyboxEntity)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QSKYBOXENTITY_H
diff --git a/src/extras/defaults/qskyboxentity_p.h b/src/extras/defaults/qskyboxentity_p.h
new file mode 100644
index 000000000..565caa66d
--- /dev/null
+++ b/src/extras/defaults/qskyboxentity_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QSKYBOXENTITY_P_H
+#define QT3DEXTRAS_QSKYBOXENTITY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DCore/private/qentity_p.h>
+#include <QVector3D>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DCore {
+class QTransform;
+}
+
+namespace Qt3DRender {
+
+class QFilterKey;
+class QTextureCubeMap;
+class QShaderProgram;
+class QSkyboxEntity;
+class QTextureImage;
+class QRenderPass;
+class QTechnique;
+class QParameter;
+class QMaterial;
+class QEffect;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QCuboidMesh;
+
+class QSkyboxEntityPrivate : public Qt3DCore::QEntityPrivate
+{
+ QSkyboxEntityPrivate();
+
+ void init();
+ void reloadTexture();
+
+ Q_DECLARE_PUBLIC(QSkyboxEntity)
+
+ Qt3DRender::QEffect *m_effect;
+ Qt3DRender::QMaterial *m_material;
+ Qt3DRender::QTextureCubeMap *m_skyboxTexture;
+ Qt3DRender::QShaderProgram *m_gl3Shader;
+ Qt3DRender::QShaderProgram *m_gl2es2Shader;
+ Qt3DRender::QTechnique *m_gl2Technique;
+ Qt3DRender::QTechnique *m_es2Technique;
+ Qt3DRender::QTechnique *m_gl3Technique;
+ Qt3DRender::QFilterKey *m_filterKey;
+ Qt3DRender::QRenderPass *m_gl2RenderPass;
+ Qt3DRender::QRenderPass *m_es2RenderPass;
+ Qt3DRender::QRenderPass *m_gl3RenderPass;
+ QCuboidMesh *m_mesh;
+ Qt3DCore::QTransform *m_transform;
+ Qt3DRender::QParameter *m_textureParameter;
+ Qt3DRender::QTextureImage *m_posXImage;
+ Qt3DRender:: QTextureImage *m_posYImage;
+ Qt3DRender::QTextureImage *m_posZImage;
+ Qt3DRender::QTextureImage *m_negXImage;
+ Qt3DRender::QTextureImage *m_negYImage;
+ Qt3DRender::QTextureImage *m_negZImage;
+ QString m_extension;
+ QString m_baseName;
+ QVector3D m_position;
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QSKYBOXENTITY_P_H
+
diff --git a/src/extras/extras.pro b/src/extras/extras.pro
new file mode 100644
index 000000000..3b7758007
--- /dev/null
+++ b/src/extras/extras.pro
@@ -0,0 +1,16 @@
+TARGET = Qt3DExtras
+MODULE = 3dextras
+QT += core-private 3dcore 3dcore-private 3drender 3drender-private
+
+DEFINES += QT3DEXTRAS_LIBRARY
+
+load(qt_module)
+
+include (geometries/geometries.pri)
+include (defaults/defaults.pri)
+
+HEADERS += \
+ qt3dextras_global.h
+
+RESOURCES += $$PWD/extras.qrc
+
diff --git a/src/extras/extras.qrc b/src/extras/extras.qrc
new file mode 100644
index 000000000..e7b1c1d9a
--- /dev/null
+++ b/src/extras/extras.qrc
@@ -0,0 +1,43 @@
+<RCC>
+ <qresource prefix="/">
+ <file>shaders/gl3/light.inc.frag</file>
+ <file>shaders/es2/light.inc.frag</file>
+ <file>shaders/es2/light.inc.frag100</file>
+ <file>shaders/gl3/phong.vert</file>
+ <file>shaders/gl3/phong.frag</file>
+ <file>shaders/es2/phong.vert</file>
+ <file>shaders/es2/phong.frag</file>
+ <file>shaders/gl3/normaldiffusespecularmap.frag</file>
+ <file>shaders/gl3/diffusemap.vert</file>
+ <file>shaders/gl3/diffusemap.frag</file>
+ <file>shaders/es2/normaldiffusespecularmap.frag</file>
+ <file>shaders/es2/diffusemap.vert</file>
+ <file>shaders/es2/diffusemap.frag</file>
+ <file>shaders/es2/normaldiffusemap.vert</file>
+ <file>shaders/es2/normaldiffusemap.frag</file>
+ <file>shaders/es2/normaldiffusemapalpha.frag</file>
+ <file>shaders/gl3/normaldiffusemap.frag</file>
+ <file>shaders/gl3/normaldiffusemap.vert</file>
+ <file>shaders/gl3/normaldiffusemapalpha.frag</file>
+ <file>shaders/es2/diffusespecularmap.frag</file>
+ <file>shaders/gl3/diffusespecularmap.frag</file>
+ <file>shaders/gl3/pervertexcolor.frag</file>
+ <file>shaders/gl3/pervertexcolor.vert</file>
+ <file>shaders/es2/pervertexcolor.frag</file>
+ <file>shaders/es2/pervertexcolor.vert</file>
+ <file>shaders/es2/skybox.frag</file>
+ <file>shaders/es2/skybox.vert</file>
+ <file>shaders/gl3/skybox.frag</file>
+ <file>shaders/gl3/skybox.vert</file>
+ <file>shaders/gl3/gooch.vert</file>
+ <file>shaders/gl3/gooch.frag</file>
+ <file>shaders/es2/gooch.frag</file>
+ <file>shaders/es2/gooch.vert</file>
+ <file>shaders/gl3/phongalpha.frag</file>
+ <file>shaders/es2/phongalpha.frag</file>
+ <file>shaders/gl3/unlittexture.vert</file>
+ <file>shaders/gl3/unlittexture.frag</file>
+ <file>shaders/es2/unlittexture.frag</file>
+ <file>shaders/es2/unlittexture.vert</file>
+ </qresource>
+</RCC>
diff --git a/src/extras/geometries/geometries.pri b/src/extras/geometries/geometries.pri
new file mode 100644
index 000000000..7a2932cb7
--- /dev/null
+++ b/src/extras/geometries/geometries.pri
@@ -0,0 +1,35 @@
+HEADERS += \
+ $$PWD/qconegeometry.h \
+ $$PWD/qconegeometry_p.h \
+ $$PWD/qconemesh.h \
+ $$PWD/qcuboidmesh.h \
+ $$PWD/qcylindergeometry.h \
+ $$PWD/qcylindergeometry_p.h \
+ $$PWD/qcylindermesh.h \
+ $$PWD/qplanemesh.h \
+ $$PWD/qspheremesh.h \
+ $$PWD/qtorusmesh.h \
+ $$PWD/qtorusgeometry.h \
+ $$PWD/qtorusgeometry_p.h \
+ $$PWD/qspheregeometry.h \
+ $$PWD/qspheregeometry_p.h \
+ $$PWD/qcuboidgeometry.h \
+ $$PWD/qcuboidgeometry_p.h \
+ $$PWD/qplanegeometry.h \
+ $$PWD/qplanegeometry_p.h
+
+SOURCES += \
+ $$PWD/qconegeometry.cpp \
+ $$PWD/qconemesh.cpp \
+ $$PWD/qcuboidmesh.cpp \
+ $$PWD/qcylindergeometry.cpp \
+ $$PWD/qcylindermesh.cpp \
+ $$PWD/qplanemesh.cpp \
+ $$PWD/qspheremesh.cpp \
+ $$PWD/qtorusmesh.cpp \
+ $$PWD/qtorusgeometry.cpp \
+ $$PWD/qspheregeometry.cpp \
+ $$PWD/qcuboidgeometry.cpp \
+ $$PWD/qplanegeometry.cpp
+
+INCLUDEPATH += $$PWD
diff --git a/src/extras/geometries/qconegeometry.cpp b/src/extras/geometries/qconegeometry.cpp
new file mode 100644
index 000000000..4d1c4ce17
--- /dev/null
+++ b/src/extras/geometries/qconegeometry.cpp
@@ -0,0 +1,589 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include "qconegeometry.h"
+#include "qconegeometry_p.h"
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qattribute.h>
+#include <QVector3D>
+#include <cmath>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+void createSidesVertices(float *&verticesPtr,
+ int rings,
+ int slices,
+ double topRadius,
+ double bottomRadius,
+ double length)
+{
+ const float dY = length / static_cast<float>(rings - 1);
+ const float dTheta = (M_PI * 2) / static_cast<float>(slices);
+
+ for (int ring = 0; ring < rings; ++ring) {
+ const float y = -length / 2.0f + static_cast<float>(ring) * dY;
+
+ const float t = (y + length / 2) / length;
+ const float radius = (bottomRadius * (1 - t)) + (t * topRadius);
+
+ for (int slice = 0; slice <= slices; ++slice) {
+ const float theta = static_cast<float>(slice) * dTheta;
+ const float ta = std::tan((M_PI/2) - std::atan(length / (bottomRadius - topRadius)));
+ const float ct = std::cos(theta);
+ const float st = std::sin(theta);
+
+ *verticesPtr++ = radius * ct;
+ *verticesPtr++ = y;
+ *verticesPtr++ = radius * st;
+
+ *verticesPtr++ = (y + length / 2.0) / length;
+ *verticesPtr++ = theta / (M_PI * 2);
+
+ QVector3D n(ct, ta, st);
+ n.normalize();
+ *verticesPtr++ = n.x();
+ *verticesPtr++ = n.y();
+ *verticesPtr++ = n.z();
+ }
+ }
+}
+
+void createSidesIndices(quint16 *&indicesPtr, int rings, int slices)
+{
+ for (int ring = 0; ring < rings-1; ++ring) {
+ const int ringIndexStart = ring * (slices + 1);
+ const int nextRingIndexStart = (ring + 1) * (slices + 1);
+
+ for (int slice = 0; slice <= slices; ++slice) {
+ if (slice == slices)
+ continue;
+
+ const int nextSlice = slice + 1;
+
+ *indicesPtr++ = (ringIndexStart + slice);
+ *indicesPtr++ = (nextRingIndexStart + slice);
+ *indicesPtr++ = (ringIndexStart + nextSlice);
+ *indicesPtr++ = (ringIndexStart + nextSlice);
+ *indicesPtr++ = (nextRingIndexStart + slice);
+ *indicesPtr++ = (nextRingIndexStart + nextSlice);
+ }
+ }
+}
+
+void createDiscVertices(float *&verticesPtr,
+ int slices,
+ double topRadius,
+ double bottomRadius,
+ double length,
+ double yPosition)
+{
+ const float dTheta = (M_PI * 2) / static_cast<float>(slices);
+ const double yNormal = (yPosition < 0.0f) ? -1.0f : 1.0f;
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yPosition;
+ *verticesPtr++ = 0.0f;
+
+ *verticesPtr++ = 1.0f;
+ *verticesPtr++ = 0.0f;
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yNormal;
+ *verticesPtr++ = 0.0f;
+
+
+ for (int slice = 0; slice <= slices; ++slice)
+ {
+ const float theta = static_cast<float>(slice) * dTheta;
+ const float ct = std::cos(theta);
+ const float st = std::sin(theta);
+
+ const float t = (yPosition + length / 2) / length;
+ const float radius = (bottomRadius * (1 - t)) + (t * topRadius);
+
+ *verticesPtr++ = radius * ct;
+ *verticesPtr++ = yPosition;
+ *verticesPtr++ = radius * st;
+
+ *verticesPtr++ = 1.0f;
+ *verticesPtr++ = theta / (M_PI * 2);
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yNormal;
+ *verticesPtr++ = 0.0f;
+ }
+}
+
+void createDiscIndices(quint16 *&indicesPtr,
+ int discCenterIndex,
+ int slices,
+ bool isTopCap)
+{
+ if ( !isTopCap ) {
+ for ( int i = slices - 1 ; i >= 0 ; --i )
+ {
+ if ( i != 0 ) {
+ *indicesPtr++ = discCenterIndex;
+ *indicesPtr++ = discCenterIndex + i + 1;
+ *indicesPtr++ = discCenterIndex + i;
+ } else {
+ *indicesPtr++ = discCenterIndex;
+ *indicesPtr++ = discCenterIndex + i + 1;
+ *indicesPtr++ = discCenterIndex + slices;
+ }
+ }
+ } else {
+ for ( int i = 0 ; i < slices; ++i )
+ {
+ if ( i != slices - 1 ) {
+ *indicesPtr++ = discCenterIndex;
+ *indicesPtr++ = discCenterIndex + i + 1;
+ *indicesPtr++ = discCenterIndex + i + 2;
+ } else {
+ *indicesPtr++ = discCenterIndex;
+ *indicesPtr++ = discCenterIndex + i + 1;
+ *indicesPtr++ = discCenterIndex + 1;
+ }
+ }
+ }
+}
+
+} // anonymous
+
+
+class ConeVertexDataFunctor : public QBufferDataGenerator
+{
+public:
+ ConeVertexDataFunctor(bool hasTopEndcap, bool hasBottomEndcap, int rings, int slices,
+ float topRadius, float bottomRadius, float length)
+ : m_hasTopEndcap(hasTopEndcap)
+ , m_hasBottomEndcap(hasBottomEndcap)
+ , m_rings(rings)
+ , m_slices(slices)
+ , m_topRadius(topRadius)
+ , m_bottomRadius(bottomRadius)
+ , m_length(length)
+ {}
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ int verticesCount = 0;
+
+ verticesCount = ( m_slices + 1 ) * m_rings // Sides
+ + (m_hasTopEndcap + m_hasBottomEndcap) * (m_slices + 1) + 2; // endcaps
+
+ // vec3 pos, vec2 texCoord, vec3 normal
+ const quint32 vertexSize = (3 + 2 + 3) * sizeof(float);
+
+ QByteArray verticesData;
+ verticesData.resize(vertexSize * verticesCount);
+ float *verticesPtr = reinterpret_cast<float*>(verticesData.data());
+
+ createSidesVertices(verticesPtr, m_rings, m_slices, m_topRadius, m_bottomRadius, m_length);
+ if ( m_hasTopEndcap )
+ createDiscVertices(verticesPtr, m_slices, m_topRadius, m_bottomRadius, m_length, m_length * 0.5f);
+ if ( m_hasBottomEndcap )
+ createDiscVertices(verticesPtr, m_slices, m_topRadius, m_bottomRadius, m_length, -m_length * 0.5f);
+
+ return verticesData;
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const ConeVertexDataFunctor *otherFunctor = functor_cast<ConeVertexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_hasTopEndcap == m_hasTopEndcap &&
+ otherFunctor->m_hasBottomEndcap == m_hasBottomEndcap &&
+ otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices &&
+ otherFunctor->m_topRadius == m_topRadius &&
+ otherFunctor->m_bottomRadius == m_bottomRadius &&
+ otherFunctor->m_length == m_length);
+ return false;
+ }
+
+ QT3D_FUNCTOR(ConeVertexDataFunctor)
+
+private:
+ bool m_hasTopEndcap;
+ bool m_hasBottomEndcap;
+ int m_rings;
+ int m_slices;
+ float m_topRadius;
+ float m_bottomRadius;
+ float m_length;
+};
+
+class ConeIndexDataFunctor : public QBufferDataGenerator
+{
+public:
+ ConeIndexDataFunctor(bool hasTopEndcap, bool hasBottomEndcap, int rings, int slices,
+ float length)
+ : m_hasTopEndcap(hasTopEndcap)
+ , m_hasBottomEndcap(hasBottomEndcap)
+ , m_rings(rings)
+ , m_slices(slices)
+ , m_length(length)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ int facesCount = 0;
+
+ facesCount = (m_slices * 2) * m_rings // 2 x tris per side, for all rings
+ + m_slices * (m_hasTopEndcap + m_hasBottomEndcap); // endcaps
+
+ const int indicesCount = facesCount * 3;
+ const int indexSize = sizeof(quint16);
+ Q_ASSERT(indicesCount < 65536);
+
+ QByteArray indicesBytes;
+ indicesBytes.resize(indicesCount * indexSize);
+ quint16 *indicesPtr = reinterpret_cast<quint16*>(indicesBytes.data());
+
+ createSidesIndices(indicesPtr, m_rings, m_slices);
+ if ( m_hasTopEndcap )
+ createDiscIndices(indicesPtr, m_rings * (m_slices + 1) + m_slices + 2, m_slices, true);
+ if ( m_hasBottomEndcap )
+ createDiscIndices(indicesPtr, m_rings * (m_slices + 1), m_slices, false);
+
+ return indicesBytes;
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const ConeIndexDataFunctor *otherFunctor = functor_cast<ConeIndexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_hasTopEndcap == m_hasTopEndcap &&
+ otherFunctor->m_hasBottomEndcap == m_hasBottomEndcap &&
+ otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices &&
+ otherFunctor->m_length == m_length);
+ return false;
+ }
+
+ QT3D_FUNCTOR(ConeIndexDataFunctor)
+
+private:
+ bool m_hasTopEndcap;
+ bool m_hasBottomEndcap;
+ int m_rings;
+ int m_slices;
+ float m_length;
+};
+
+
+QConeGeometryPrivate::QConeGeometryPrivate()
+ : QGeometryPrivate()
+ , m_hasTopEndcap(true)
+ , m_hasBottomEndcap(true)
+ , m_rings(16)
+ , m_slices(16)
+ , m_topRadius(0.0f)
+ , m_bottomRadius(1.0f)
+ , m_length(1.0f)
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QConeGeometryPrivate::init()
+{
+ Q_Q(QConeGeometry);
+ m_positionAttribute = new QAttribute(q);
+ m_normalAttribute = new QAttribute(q);
+ m_texCoordAttribute = new QAttribute(q);
+ m_indexAttribute = new QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+
+ // vec3 pos, vec2 tex, vec3 normal
+ const quint32 elementSize = 3 + 2 + 3;
+ const quint32 stride = elementSize * sizeof(float);
+ const int faces = (m_slices + 1) * (m_rings + 1);
+ int nVerts = 0;
+
+ nVerts = (m_slices * 2) * m_rings // Sides
+ + m_slices * (m_hasTopEndcap + m_hasBottomEndcap); // endcaps
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ m_indexAttribute->setCount(faces * 3);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new ConeVertexDataFunctor(m_hasTopEndcap, m_hasBottomEndcap, m_rings, m_slices,
+ m_topRadius, m_bottomRadius, m_length)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new ConeIndexDataFunctor(m_hasTopEndcap, m_hasBottomEndcap, m_rings, m_slices,
+ m_length)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+QConeGeometry::QConeGeometry(QNode *parent)
+ : QGeometry(*new QConeGeometryPrivate, parent)
+{
+ Q_D(QConeGeometry);
+ d->init();
+}
+
+QConeGeometry::QConeGeometry(QConeGeometryPrivate &dd, QNode *parent)
+ :QGeometry(dd, parent)
+{
+ Q_D(QConeGeometry);
+ d->init();
+}
+
+QConeGeometry::~QConeGeometry()
+{
+ QGeometry::cleanup();
+}
+
+void QConeGeometry::updateVertices()
+{
+ Q_D(QConeGeometry);
+ const int nVerts = (d->m_slices + 1) * (d->m_rings + 1);
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new ConeVertexDataFunctor(d->m_hasTopEndcap, d->m_hasBottomEndcap, d->m_rings, d->m_slices,
+ d->m_topRadius, d->m_bottomRadius, d->m_length)));
+}
+
+void QConeGeometry::updateIndices()
+{
+ Q_D(QConeGeometry);
+ int faces = 0;
+
+ faces = (d->m_slices * 2) * d->m_rings // 2 x tris per side, for all rings
+ + d->m_slices * (d->m_hasTopEndcap + d->m_hasBottomEndcap); // 2 x endcaps
+
+ d->m_indexAttribute->setCount(faces * 3);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new ConeIndexDataFunctor(d->m_hasTopEndcap, d->m_hasBottomEndcap, d->m_rings, d->m_slices,
+ d->m_length)));
+}
+
+void QConeGeometry::setHasTopEndcap(bool hasTopEndcap)
+{
+ Q_D(QConeGeometry);
+ if (hasTopEndcap != d->m_hasTopEndcap) {
+ d->m_hasTopEndcap = hasTopEndcap;
+ updateVertices();
+ emit hasTopEndcapChanged(hasTopEndcap);
+ }
+}
+
+
+void QConeGeometry::setHasBottomEndcap(bool hasBottomEndcap)
+{
+ Q_D(QConeGeometry);
+ if (hasBottomEndcap != d->m_hasBottomEndcap) {
+ d->m_hasBottomEndcap = hasBottomEndcap;
+ updateVertices();
+ emit hasBottomEndcapChanged(hasBottomEndcap);
+ }
+}
+
+void QConeGeometry::setRings(int rings)
+{
+ Q_D(QConeGeometry);
+ if (rings != d->m_rings) {
+ d->m_rings = rings;
+ updateVertices();
+ updateIndices();
+ emit ringsChanged(rings);
+ }
+}
+
+void QConeGeometry::setSlices(int slices)
+{
+ Q_D(QConeGeometry);
+ if (slices != d->m_slices) {
+ d->m_slices = slices;
+ updateVertices();
+ updateIndices();
+ emit slicesChanged(slices);
+ }
+}
+
+void QConeGeometry::setTopRadius(float topRadius)
+{
+ Q_D(QConeGeometry);
+ if (topRadius != d->m_topRadius) {
+ d->m_topRadius = topRadius;
+ updateVertices();
+ emit topRadiusChanged(topRadius);
+ }
+}
+
+void QConeGeometry::setBottomRadius(float bottomRadius)
+{
+ Q_D(QConeGeometry);
+ if (bottomRadius != d->m_bottomRadius) {
+ d->m_bottomRadius = bottomRadius;
+ updateVertices();
+ emit bottomRadiusChanged(bottomRadius);
+ }
+}
+
+void QConeGeometry::setLength(float length)
+{
+ Q_D(QConeGeometry);
+ if (length != d->m_length) {
+ d->m_length = length;
+ updateVertices();
+ updateIndices();
+ emit lengthChanged(length);
+ }
+}
+
+bool QConeGeometry::hasTopEndcap() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_hasTopEndcap;
+}
+
+bool QConeGeometry::hasBottomEndcap() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_hasBottomEndcap;
+}
+
+float QConeGeometry::topRadius() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_topRadius;
+}
+
+float QConeGeometry::bottomRadius() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_bottomRadius;
+}
+
+int QConeGeometry::rings() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_rings;
+}
+
+int QConeGeometry::slices() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_slices;
+}
+
+float QConeGeometry::length() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_length;
+}
+
+QAttribute *QConeGeometry::positionAttribute() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_positionAttribute;
+}
+
+QAttribute *QConeGeometry::normalAttribute() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_normalAttribute;
+}
+
+QAttribute *QConeGeometry::texCoordAttribute() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_texCoordAttribute;
+}
+
+QAttribute *QConeGeometry::indexAttribute() const
+{
+ Q_D(const QConeGeometry);
+ return d->m_indexAttribute;
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qconegeometry.h b/src/extras/geometries/qconegeometry.h
new file mode 100644
index 000000000..4f1dc944a
--- /dev/null
+++ b/src/extras/geometries/qconegeometry.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCONEGEOMETRY_H
+#define QT3DEXTRAS_QCONEGEOMETRY_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometry.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+class QAttribute;
+} // Render
+
+namespace Qt3DExtras {
+
+class QConeGeometryPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QConeGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY( bool hasTopEndcap READ hasTopEndcap WRITE setHasTopEndcap NOTIFY hasTopEndcapChanged )
+ Q_PROPERTY( bool hasBottomEndcap READ hasBottomEndcap WRITE setHasBottomEndcap NOTIFY hasBottomEndcapChanged )
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY( float topRadius READ topRadius WRITE setTopRadius NOTIFY topRadiusChanged )
+ Q_PROPERTY( float bottomRadius READ bottomRadius WRITE setBottomRadius NOTIFY bottomRadiusChanged )
+ Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QConeGeometry(QNode *parent = nullptr);
+ ~QConeGeometry();
+
+ void updateVertices();
+ void updateIndices();
+
+ bool hasTopEndcap() const;
+ bool hasBottomEndcap() const;
+ float topRadius() const;
+ float bottomRadius() const;
+ int rings() const;
+ int slices() const;
+ float length() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setHasTopEndcap( bool hasTopEndcap );
+ void setHasBottomEndcap( bool hasBottomEndcap );
+ void setTopRadius( float topRadius );
+ void setBottomRadius( float bottomRadius );
+ void setRings( int rings );
+ void setSlices( int slices );
+ void setLength( float length );
+
+Q_SIGNALS:
+ void hasTopEndcapChanged( bool hasTopEndcap );
+ void hasBottomEndcapChanged( bool hasBottomEndcap );
+ void topRadiusChanged( float topRadius );
+ void bottomRadiusChanged( float bottomRadius );
+ void ringsChanged( int rings );
+ void slicesChanged( int slices );
+ void lengthChanged( float length );
+
+protected:
+ QConeGeometry(QConeGeometryPrivate &dd, QNode *parent = nullptr);
+
+private:
+ Q_DECLARE_PRIVATE(QConeGeometry)
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCONEGEOMETRY_H
diff --git a/src/extras/geometries/qconegeometry_p.h b/src/extras/geometries/qconegeometry_p.h
new file mode 100644
index 000000000..3987b4315
--- /dev/null
+++ b/src/extras/geometries/qconegeometry_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCONEGEOMETRY_P_H
+#define QT3DEXTRAS_QCONEGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QConeGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QConeGeometryPrivate();
+
+ void init();
+
+ Q_DECLARE_PUBLIC(QConeGeometry)
+
+ bool m_hasTopEndcap;
+ bool m_hasBottomEndcap;
+ int m_rings;
+ int m_slices;
+ float m_topRadius;
+ float m_bottomRadius;
+ float m_length;
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_positionBuffer;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCONEGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qconemesh.cpp b/src/extras/geometries/qconemesh.cpp
new file mode 100644
index 000000000..621e06046
--- /dev/null
+++ b/src/extras/geometries/qconemesh.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include "qconemesh.h"
+#include "qconegeometry.h"
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qattribute.h>
+#include <qmath.h>
+#include <QVector3D>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+QConeMesh::QConeMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QConeGeometry *geometry = new QConeGeometry(this);
+ QObject::connect(geometry, &QConeGeometry::hasTopEndcapChanged, this, &QConeMesh::hasTopEndcapChanged);
+ QObject::connect(geometry, &QConeGeometry::hasBottomEndcapChanged, this, &QConeMesh::hasBottomEndcapChanged);
+ QObject::connect(geometry, &QConeGeometry::topRadiusChanged, this, &QConeMesh::topRadiusChanged);
+ QObject::connect(geometry, &QConeGeometry::bottomRadiusChanged, this, &QConeMesh::bottomRadiusChanged);
+ QObject::connect(geometry, &QConeGeometry::ringsChanged, this, &QConeMesh::ringsChanged);
+ QObject::connect(geometry, &QConeGeometry::slicesChanged, this, &QConeMesh::slicesChanged);
+ QObject::connect(geometry, &QConeGeometry::lengthChanged, this, &QConeMesh::lengthChanged);
+
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+QConeMesh::~QConeMesh()
+{
+ QNode::cleanup();
+}
+
+void QConeMesh::setHasTopEndcap(bool hasTopEndcap)
+{
+ static_cast<QConeGeometry *>(geometry())->setHasTopEndcap(hasTopEndcap);
+}
+
+void QConeMesh::setHasBottomEndcap(bool hasBottomEndcap)
+{
+ static_cast<QConeGeometry *>(geometry())->setHasBottomEndcap(hasBottomEndcap);
+}
+
+void QConeMesh::setTopRadius(float topRadius)
+{
+ static_cast<QConeGeometry *>(geometry())->setTopRadius(topRadius);
+}
+
+void QConeMesh::setBottomRadius(float bottomRadius)
+{
+ static_cast<QConeGeometry *>(geometry())->setBottomRadius(bottomRadius);
+}
+
+void QConeMesh::setRings(int rings)
+{
+ static_cast<QConeGeometry *>(geometry())->setRings(rings);
+}
+
+void QConeMesh::setSlices(int slices)
+{
+ static_cast<QConeGeometry *>(geometry())->setSlices(slices);
+}
+
+void QConeMesh::setLength(float length)
+{
+ static_cast<QConeGeometry *>(geometry())->setLength(length);
+}
+
+bool QConeMesh::hasTopEndcap() const
+{
+ return static_cast<QConeGeometry *>(geometry())->hasTopEndcap();
+}
+
+bool QConeMesh::hasBottomEndcap() const
+{
+ return static_cast<QConeGeometry *>(geometry())->hasBottomEndcap();
+}
+
+float QConeMesh::topRadius() const
+{
+ return static_cast<QConeGeometry *>(geometry())->topRadius();
+}
+
+float QConeMesh::bottomRadius() const
+{
+ return static_cast<QConeGeometry *>(geometry())->bottomRadius();
+}
+
+int QConeMesh::rings() const
+{
+ return static_cast<QConeGeometry *>(geometry())->rings();
+}
+
+int QConeMesh::slices() const
+{
+ return static_cast<QConeGeometry *>(geometry())->slices();
+}
+
+float QConeMesh::length() const
+{
+ return static_cast<QConeGeometry *>(geometry())->length();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qconemesh.h b/src/extras/geometries/qconemesh.h
new file mode 100644
index 000000000..c32070e5c
--- /dev/null
+++ b/src/extras/geometries/qconemesh.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCONEMESH_H
+#define QT3DEXTRAS_QCONEMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QT3DEXTRASSHARED_EXPORT QConeMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY( bool hasTopEndcap READ hasTopEndcap WRITE setHasTopEndcap NOTIFY hasTopEndcapChanged )
+ Q_PROPERTY( bool hasBottomEndcap READ hasBottomEndcap WRITE setHasBottomEndcap NOTIFY hasBottomEndcapChanged )
+ Q_PROPERTY( float topRadius READ topRadius WRITE setTopRadius NOTIFY topRadiusChanged )
+ Q_PROPERTY( float bottomRadius READ bottomRadius WRITE setBottomRadius NOTIFY bottomRadiusChanged )
+ Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged)
+public:
+ explicit QConeMesh(Qt3DCore::QNode *parent = nullptr);
+ ~QConeMesh();
+
+ int rings() const;
+ int slices() const;
+ bool hasTopEndcap() const;
+ bool hasBottomEndcap() const;
+ float topRadius() const;
+ float bottomRadius() const;
+ float length() const;
+
+public Q_SLOTS:
+ void setHasTopEndcap( bool hasTopEndcap );
+ void setHasBottomEndcap( bool hasBottomEndcap );
+ void setTopRadius( float topRadius );
+ void setBottomRadius( float bottomRadius );
+ void setRings( int rings );
+ void setSlices( int slices );
+ void setLength( float length );
+
+Q_SIGNALS:
+ void hasTopEndcapChanged( bool hasTopEndcap );
+ void hasBottomEndcapChanged( bool hasBottomEndcap );
+ void topRadiusChanged( float topRadius );
+ void bottomRadiusChanged( float bottomRadius );
+ void ringsChanged( int rings );
+ void slicesChanged( int slices );
+ void lengthChanged( float length );
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setInstanceCount(int instanceCount);
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCONEMESH_H
diff --git a/src/extras/geometries/qcuboidgeometry.cpp b/src/extras/geometries/qcuboidgeometry.cpp
new file mode 100644
index 000000000..b62ae0022
--- /dev/null
+++ b/src/extras/geometries/qcuboidgeometry.cpp
@@ -0,0 +1,827 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcuboidgeometry.h"
+#include "qcuboidgeometry_p.h"
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/private/renderlogging_p.h>
+#include <limits>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+enum PlaneNormal {
+ PositiveX,
+ NegativeX,
+ PositiveY,
+ NegativeY,
+ PositiveZ,
+ NegativeZ
+};
+
+void createPlaneVertexData(float w, float h, const QSize &resolution,
+ PlaneNormal normal, float planeDistance,
+ float *vertices)
+{
+ const float a0 = -w / 2.0f;
+ const float b0 = -h / 2.0f;
+ const float da = w / (resolution.width() - 1);
+ const float db = h / (resolution.height() - 1);
+ const float du = 1.0 / (resolution.width() - 1);
+ const float dv = 1.0 / (resolution.height() - 1);
+ float n = 1.0f;
+
+ switch (normal) {
+ case NegativeX:
+ n = -1.0f; // fall through
+ case PositiveX: {
+ // Iterate over z
+ for (int j = 0; j < resolution.height(); ++j) {
+ const float b = b0 + static_cast<float>(j) * db;
+ const float v = static_cast<float>(j) * dv;
+
+ // Iterate over y
+ for (int i = 0; i < resolution.width(); ++i) {
+ const float a = a0 + static_cast<float>(i) * da;
+ const float u = static_cast<float>(i) * du;
+
+ // position
+ *vertices++ = planeDistance;
+ *vertices++ = a;
+ *vertices++ = b;
+
+ // texture coordinates
+ *vertices++ = u;
+ *vertices++ = v;
+
+ // normal
+ *vertices++ = n;
+ *vertices++ = 0.0f;
+ *vertices++ = 0.0f;
+
+ // tangent
+ *vertices++ = 0.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = 1.0f;
+ *vertices++ = 1.0f;
+ }
+ }
+ break;
+ }
+
+ case NegativeY:
+ n = -1.0f;
+ case PositiveY: {
+ // Iterate over z
+ for (int j = 0; j < resolution.height(); ++j) {
+ const float b = b0 + static_cast<float>(j) * db;
+ const float v = static_cast<float>(j) * dv;
+
+ // Iterate over x
+ // This iterates in the opposite sense to the other directions
+ // so that the winding order is correct
+ for (int i = resolution.width() - 1; i >= 0; --i) {
+ const float a = a0 + static_cast<float>(i) * da;
+ const float u = static_cast<float>(i) * du;
+
+ // position
+ *vertices++ = a;
+ *vertices++ = planeDistance;
+ *vertices++ = b;
+
+ // texture coordinates
+ *vertices++ = u;
+ *vertices++ = v;
+
+ // normal
+ *vertices++ = 0.0f;
+ *vertices++ = n;
+ *vertices++ = 0.0f;
+
+ // tangent
+ *vertices++ = 1.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = 1.0f;
+ }
+ }
+ break;
+ }
+
+ case NegativeZ:
+ n = -1.0f;
+ case PositiveZ: {
+ // Iterate over y
+ for (int j = 0; j < resolution.height(); ++j) {
+ const float b = b0 + static_cast<float>(j) * db;
+ const float v = static_cast<float>(j) * dv;
+
+ // Iterate over x
+ for (int i = 0; i < resolution.width(); ++i) {
+ const float a = a0 + static_cast<float>(i) * da;
+ const float u = static_cast<float>(i) * du;
+
+ // position
+ *vertices++ = a;
+ *vertices++ = b;
+ *vertices++ = planeDistance;
+
+ // texture coordinates
+ *vertices++ = u;
+ *vertices++ = v;
+
+ // normal
+ *vertices++ = 0.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = n;
+
+ // tangent
+ *vertices++ = 1.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = 0.0f;
+ *vertices++ = 1.0f;
+ }
+ }
+ break;
+ }
+ } // switch (normal)
+}
+
+void createPlaneIndexData(PlaneNormal normal, const QSize &resolution, quint16 *indices, quint16 &baseVertex)
+{
+ float n = 1.0f;
+
+ switch (normal) {
+ case NegativeX:
+ case NegativeY:
+ case NegativeZ:
+ n = -1.0f;
+ break;
+ default:
+ break;
+ }
+
+ // Populate indices taking care to get correct CCW winding on all faces
+ if (n > 0.0f) {
+ for (int j = 0; j < resolution.height() - 1; ++j) {
+ const int rowStartIndex = j * resolution.width() + baseVertex;
+ const int nextRowStartIndex = (j + 1) * resolution.width() + baseVertex;
+
+ // Iterate over x
+ for (int i = 0; i < resolution.width() - 1; ++i) {
+ // Split quad into two triangles
+ *indices++ = rowStartIndex + i;
+ *indices++ = rowStartIndex + i + 1;
+ *indices++ = nextRowStartIndex + i;
+
+ *indices++ = nextRowStartIndex + i;
+ *indices++ = rowStartIndex + i + 1;
+ *indices++ = nextRowStartIndex + i + 1;
+ }
+ }
+ } else {
+ for (int j = 0; j < resolution.height() - 1; ++j) {
+ const int rowStartIndex = j * resolution.width() + baseVertex;
+ const int nextRowStartIndex = (j + 1) * resolution.width() + baseVertex;
+
+ // Iterate over x
+ for (int i = 0; i < resolution.width() - 1; ++i) {
+ // Split quad into two triangles
+ *indices++ = rowStartIndex + i;
+ *indices++ = nextRowStartIndex + i;
+ *indices++ = rowStartIndex + i + 1;
+
+ *indices++ = nextRowStartIndex + i;
+ *indices++ = nextRowStartIndex + i + 1;
+ *indices++ = rowStartIndex + i + 1;
+ }
+ }
+ }
+ baseVertex += resolution.width() * resolution.height();
+}
+
+QByteArray createCuboidVertexData(float xExtent,
+ float yExtent,
+ float zExtent,
+ const QSize &yzResolution,
+ const QSize &xzResolution,
+ const QSize &xyResolution)
+{
+ Q_ASSERT(xExtent > 0.0f && yExtent > 0.0f && zExtent > 0.0);
+ Q_ASSERT(yzResolution.width() >= 2 && yzResolution.height() >=2);
+ Q_ASSERT(xzResolution.width() >= 2 && xzResolution.height() >=2);
+ Q_ASSERT(xyResolution.width() >= 2 && xyResolution.height() >=2);
+
+ const int yzVerts = yzResolution.width() * yzResolution.height();
+ const int xzVerts = xzResolution.width() * xzResolution.height();
+ const int xyVerts = xyResolution.width() * xyResolution.height();
+ const int nVerts = 2 * (yzVerts + xzVerts + xyVerts);
+
+ const quint32 elementSize = 3 + 3 + 2 + 4;
+ const quint32 stride = elementSize * sizeof(float);
+ QByteArray vertexBytes;
+ vertexBytes.resize(stride * nVerts);
+ float* vertices = reinterpret_cast<float*>(vertexBytes.data());
+
+ createPlaneVertexData(yExtent, zExtent, yzResolution, PositiveX, xExtent * 0.5f, vertices);
+ vertices += yzVerts * elementSize;
+ createPlaneVertexData(yExtent, zExtent, yzResolution, NegativeX, -xExtent * 0.5f, vertices);
+ vertices += yzVerts * elementSize;
+ createPlaneVertexData(xExtent, zExtent, xzResolution, PositiveY, yExtent * 0.5f, vertices);
+ vertices += xzVerts * elementSize;
+ createPlaneVertexData(xExtent, zExtent, xzResolution, NegativeY, -yExtent * 0.5f, vertices);
+ vertices += xzVerts * elementSize;
+ createPlaneVertexData(xExtent, yExtent, xyResolution, PositiveZ, zExtent * 0.5f, vertices);
+ vertices += xyVerts * elementSize;
+ createPlaneVertexData(xExtent, yExtent, xyResolution, NegativeZ, -zExtent * 0.5f, vertices);
+
+ return vertexBytes;
+}
+
+QByteArray createCuboidIndexData(const QSize &yzResolution,
+ const QSize &xzResolution,
+ const QSize &xyResolution)
+{
+ Q_ASSERT(yzResolution.width() >= 2 && yzResolution.height() >= 2);
+ Q_ASSERT(xzResolution.width() >= 2 && xzResolution.height() >= 2);
+ Q_ASSERT(xyResolution.width() >= 2 && xyResolution.height() >= 2);
+
+ const int yzIndices = 2 * 3 * (yzResolution.width() - 1) * (yzResolution.height() - 1);
+ const int xzIndices = 2 * 3 * (xzResolution.width() - 1) * (xzResolution.height() - 1);
+ const int xyIndices = 2 * 3 * (xyResolution.width() - 1) * (xyResolution.height() - 1);
+ const int indexCount = 2 * (yzIndices + xzIndices + xyIndices);
+
+ QByteArray indexData;
+ indexData.resize(indexCount * sizeof(quint16));
+ quint16 *indices = reinterpret_cast<quint16 *>(indexData.data());
+ quint16 baseIndex = 0;
+
+ createPlaneIndexData(PositiveX, yzResolution, indices, baseIndex);
+ indices += yzIndices;
+ createPlaneIndexData(NegativeX, yzResolution, indices, baseIndex);
+ indices += yzIndices;
+ createPlaneIndexData(PositiveY, xzResolution, indices, baseIndex);
+ indices += xzIndices;
+ createPlaneIndexData(NegativeY, xzResolution, indices, baseIndex);
+ indices += xzIndices;
+ createPlaneIndexData(PositiveZ, xyResolution, indices, baseIndex);
+ indices += xyIndices;
+ createPlaneIndexData(NegativeZ, xyResolution, indices, baseIndex);
+
+ return indexData;
+}
+
+} // anonymous
+
+class CuboidVertexBufferFunctor : public QBufferDataGenerator
+{
+public:
+ explicit CuboidVertexBufferFunctor(float xExtent,
+ float yExtent,
+ float zExtent,
+ const QSize &yzResolution,
+ const QSize &xzResolution,
+ const QSize &xyResolution)
+ : m_xExtent(xExtent)
+ , m_yExtent(yExtent)
+ , m_zExtent(zExtent)
+ , m_yzFaceResolution(yzResolution)
+ , m_xzFaceResolution(xzResolution)
+ , m_xyFaceResolution(xyResolution)
+ {}
+
+ ~CuboidVertexBufferFunctor() {}
+
+ QByteArray operator()() Q_DECL_FINAL
+ {
+ return createCuboidVertexData(m_xExtent, m_yExtent, m_zExtent,
+ m_yzFaceResolution, m_xzFaceResolution, m_xyFaceResolution);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL
+ {
+ const CuboidVertexBufferFunctor *otherFunctor = functor_cast<CuboidVertexBufferFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_xExtent == m_xExtent &&
+ otherFunctor->m_yExtent == m_yExtent &&
+ otherFunctor->m_zExtent == m_zExtent &&
+ otherFunctor->m_yzFaceResolution == m_yzFaceResolution &&
+ otherFunctor->m_xzFaceResolution == m_xzFaceResolution &&
+ otherFunctor->m_xyFaceResolution == m_xyFaceResolution);
+ return false;
+ }
+
+ QT3D_FUNCTOR(CuboidVertexBufferFunctor)
+
+private:
+ float m_xExtent;
+ float m_yExtent;
+ float m_zExtent;
+ QSize m_yzFaceResolution;
+ QSize m_xzFaceResolution;
+ QSize m_xyFaceResolution;
+};
+
+class CuboidIndexBufferFunctor : public QBufferDataGenerator
+{
+public:
+ explicit CuboidIndexBufferFunctor(const QSize &yzResolution,
+ const QSize &xzResolution,
+ const QSize &xyResolution)
+ : m_yzFaceResolution(yzResolution)
+ , m_xzFaceResolution(xzResolution)
+ , m_xyFaceResolution(xyResolution)
+ {}
+
+ ~CuboidIndexBufferFunctor() {}
+
+ QByteArray operator()() Q_DECL_FINAL
+ {
+ return createCuboidIndexData(m_yzFaceResolution, m_xzFaceResolution, m_xyFaceResolution);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL
+ {
+ const CuboidIndexBufferFunctor *otherFunctor = functor_cast<CuboidIndexBufferFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_yzFaceResolution == m_yzFaceResolution &&
+ otherFunctor->m_xzFaceResolution == m_xzFaceResolution &&
+ otherFunctor->m_xyFaceResolution == m_xyFaceResolution);
+ return false;
+ }
+
+ QT3D_FUNCTOR(CuboidIndexBufferFunctor)
+
+private:
+ QSize m_yzFaceResolution;
+ QSize m_xzFaceResolution;
+ QSize m_xyFaceResolution;
+};
+
+QCuboidGeometryPrivate::QCuboidGeometryPrivate()
+ : QGeometryPrivate()
+ , m_xExtent(1.0f)
+ , m_yExtent(1.0f)
+ , m_zExtent(1.0f)
+ , m_yzFaceResolution(2, 2)
+ , m_xzFaceResolution(2, 2)
+ , m_xyFaceResolution(2, 2)
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_tangentAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QCuboidGeometryPrivate::init()
+{
+ Q_Q(QCuboidGeometry);
+ m_positionAttribute = new Qt3DRender::QAttribute(q);
+ m_normalAttribute = new Qt3DRender::QAttribute(q);
+ m_texCoordAttribute = new Qt3DRender::QAttribute(q);
+ m_tangentAttribute = new Qt3DRender::QAttribute(q);
+ m_indexAttribute = new Qt3DRender::QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+
+ // vec3 pos vec2 tex vec3 normal vec4 tangent
+ const quint32 stride = (3 + 2 + 3 + 4) * sizeof(float);
+ const int yzIndices = 2 * 3 * (m_yzFaceResolution.width() - 1) * (m_yzFaceResolution.height() - 1);
+ const int xzIndices = 2 * 3 * (m_xzFaceResolution.width() - 1) * (m_xzFaceResolution.height() - 1);
+ const int xyIndices = 2 * 3 * (m_xyFaceResolution.width() - 1) * (m_xyFaceResolution.height() - 1);
+ const int yzVerts = m_yzFaceResolution.width() * m_yzFaceResolution.height();
+ const int xzVerts = m_xzFaceResolution.width() * m_xzFaceResolution.height();
+ const int xyVerts = m_xyFaceResolution.width() * m_xyFaceResolution.height();
+
+ const int nVerts = 2 * (yzVerts + xzVerts + xyVerts);
+ const int indexCount = 2 * (yzIndices + xzIndices + xyIndices);
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName());
+ m_tangentAttribute->setDataType(QAttribute::Float);
+ m_tangentAttribute->setDataSize(4);
+ m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_tangentAttribute->setBuffer(m_vertexBuffer);
+ m_tangentAttribute->setByteStride(stride);
+ m_tangentAttribute->setByteOffset(8 * sizeof(float));
+ m_tangentAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ m_indexAttribute->setCount(indexCount);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CuboidVertexBufferFunctor(m_xExtent, m_yExtent, m_zExtent,
+ m_yzFaceResolution, m_xzFaceResolution, m_xyFaceResolution)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CuboidIndexBufferFunctor(m_yzFaceResolution, m_xzFaceResolution, m_xyFaceResolution)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ q->addAttribute(m_tangentAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+/*!
+ * \qmltype CuboidGeometry
+ * \instantiates Qt3DRender::QCuboidGeometry
+ * \inqmlmodule Qt3D.Render
+ */
+
+/*!
+ * \qmlproperty float CuboidGeometry::xExtent
+ *
+ * Holds the x extent.
+ */
+
+/*!
+ * \qmlproperty float CuboidGeometry::yExtent
+ *
+ * Holds the y extent.
+ */
+
+/*!
+ * \qmlproperty float CuboidGeometry::zExtent
+ *
+ * Holds the z extent.
+ */
+
+/*!
+ * \qmlproperty size CuboidGeometry::yzMeshResolution
+ *
+ * Holds the y-z resolution.
+ */
+
+/*!
+ * \qmlproperty size CuboidGeometry::xzMeshResolution
+ *
+ * Holds the x-z resolution.
+ */
+
+/*!
+ * \qmlproperty size CuboidGeometry::xyMeshResolution
+ *
+ * Holds the x-y resolution.
+ */
+
+/*!
+ * \qmlproperty Attribute CuboidGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CuboidGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CuboidGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CuboidGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CuboidGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+
+/*!
+ * \class Qt3DRender::QCuboidGeometry
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometry
+ *
+ */
+
+/*!
+ * Constructs a new QCuboidGeometry with \a parent.
+ */
+QCuboidGeometry::QCuboidGeometry(QNode *parent)
+ : QGeometry(*new QCuboidGeometryPrivate(), parent)
+{
+ Q_D(QCuboidGeometry);
+ d->init();
+}
+
+/*!
+ * \internal
+ */
+QCuboidGeometry::QCuboidGeometry(QCuboidGeometryPrivate &dd, QNode *parent)
+ : QGeometry(dd, parent)
+{
+ Q_D(QCuboidGeometry);
+ d->init();
+}
+
+/*!
+ * Destroys this geometry.
+ */
+QCuboidGeometry::~QCuboidGeometry()
+{
+ QGeometry::cleanup();
+}
+
+/*!
+ * Updates indices based on mesh resolutions.
+ */
+void QCuboidGeometry::updateIndices()
+{
+ Q_D(QCuboidGeometry);
+ const int yzIndices = 2 * 3 * (d->m_yzFaceResolution.width() - 1) * (d->m_yzFaceResolution.height() - 1);
+ const int xzIndices = 2 * 3 * (d->m_xzFaceResolution.width() - 1) * (d->m_xzFaceResolution.height() - 1);
+ const int xyIndices = 2 * 3 * (d->m_xyFaceResolution.width() - 1) * (d->m_xyFaceResolution.height() - 1);
+ const int indexCount = 2 * (yzIndices + xzIndices + xyIndices);
+
+ d->m_indexAttribute->setCount(indexCount);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CuboidIndexBufferFunctor(d->m_yzFaceResolution, d->m_xzFaceResolution, d->m_xyFaceResolution)));
+
+}
+
+/*!
+ * Updates vertices based on mesh resolutions.
+ */
+void QCuboidGeometry::updateVertices()
+{
+ Q_D(QCuboidGeometry);
+ const int yzVerts = d->m_yzFaceResolution.width() * d->m_yzFaceResolution.height();
+ const int xzVerts = d->m_xzFaceResolution.width() * d->m_xzFaceResolution.height();
+ const int xyVerts = d->m_xyFaceResolution.width() * d->m_xyFaceResolution.height();
+ const int nVerts = 2 * (yzVerts + xzVerts + xyVerts);
+
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_tangentAttribute->setCount(nVerts);
+
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CuboidVertexBufferFunctor(d->m_xExtent, d->m_yExtent, d->m_zExtent,
+ d->m_yzFaceResolution, d->m_xzFaceResolution, d->m_xyFaceResolution)));
+}
+
+void QCuboidGeometry::setXExtent(float xExtent)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_xExtent != xExtent) {
+ d->m_xExtent = xExtent;
+ updateVertices();
+ emit xExtentChanged(xExtent);
+ }
+}
+
+void QCuboidGeometry::setYExtent(float yExtent)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_yExtent != yExtent) {
+ d->m_yExtent = yExtent;
+ updateVertices();
+ emit yExtentChanged(yExtent);
+ }
+}
+
+void QCuboidGeometry::setZExtent(float zExtent)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_zExtent != zExtent) {
+ d->m_zExtent = zExtent;
+ updateVertices();
+ emit zExtentChanged(zExtent);
+ }
+}
+
+void QCuboidGeometry::setYZMeshResolution(const QSize &resolution)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_yzFaceResolution != resolution) {
+ d->m_yzFaceResolution = resolution;
+ updateVertices();
+ updateIndices();
+ emit yzMeshResolutionChanged(resolution);
+ }
+}
+
+void QCuboidGeometry::setXZMeshResolution(const QSize &resolution)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_xzFaceResolution != resolution) {
+ d->m_xzFaceResolution = resolution;
+ updateVertices();
+ updateIndices();
+ emit xzMeshResolutionChanged(resolution);
+ }
+}
+
+void QCuboidGeometry::setXYMeshResolution(const QSize &resolution)
+{
+ Q_D(QCuboidGeometry);
+ if (d->m_xyFaceResolution != resolution) {
+ d->m_xyFaceResolution = resolution;
+ updateVertices();
+ updateIndices();
+ emit xyMeshResolutionChanged(resolution);
+ }
+}
+
+/*!
+ * \property QCuboidGeometry::xExtent
+ *
+ * Holds the x extent.
+ */
+float QCuboidGeometry::xExtent() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_xExtent;
+}
+
+/*!
+ * \property QCuboidGeometry::yExtent
+ *
+ * Holds the y extent.
+ */
+float QCuboidGeometry::yExtent() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_yExtent;
+}
+
+/*!
+ * \property QCuboidGeometry::zExtent
+ *
+ * Holds the z extent.
+ */
+float QCuboidGeometry::zExtent() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_zExtent;
+}
+
+/*!
+ * \property QCuboidGeometry::yzMeshResolution
+ *
+ * Holds the y-z resolution.
+ */
+QSize QCuboidGeometry::yzMeshResolution() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_yzFaceResolution;
+}
+
+/*!
+ * \property QCuboidGeometry::xzMeshResolution
+ *
+ * Holds the x-z resolution.
+ */
+QSize QCuboidGeometry::xyMeshResolution() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_xyFaceResolution;
+}
+
+/*!
+ * \property QCuboidGeometry::xyMeshResolution
+ *
+ * Holds the x-y resolution.
+ */
+QSize QCuboidGeometry::xzMeshResolution() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_xzFaceResolution;
+}
+
+/*!
+ * \property QCuboidGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+QAttribute *QCuboidGeometry::positionAttribute() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_positionAttribute;
+}
+
+/*!
+ * \property QCuboidGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+QAttribute *QCuboidGeometry::normalAttribute() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_normalAttribute;
+}
+
+/*!
+ * \property QCuboidGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+QAttribute *QCuboidGeometry::texCoordAttribute() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_texCoordAttribute;
+}
+
+/*!
+ * \property QCuboidGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+QAttribute *QCuboidGeometry::tangentAttribute() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_tangentAttribute;
+}
+
+/*!
+ * \property QCuboidGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+QAttribute *QCuboidGeometry::indexAttribute() const
+{
+ Q_D(const QCuboidGeometry);
+ return d->m_indexAttribute;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qcuboidgeometry.h b/src/extras/geometries/qcuboidgeometry.h
new file mode 100644
index 000000000..7fa5f58ff
--- /dev/null
+++ b/src/extras/geometries/qcuboidgeometry.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCUBOIDGEOMETRY_H
+#define QT3DEXTRAS_QCUBOIDGEOMETRY_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometry.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QCuboidGeometryPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QCuboidGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(float xExtent READ xExtent WRITE setXExtent NOTIFY xExtentChanged)
+ Q_PROPERTY(float yExtent READ yExtent WRITE setYExtent NOTIFY yExtentChanged)
+ Q_PROPERTY(float zExtent READ zExtent WRITE setZExtent NOTIFY zExtentChanged)
+ Q_PROPERTY(QSize xyMeshResolution READ xyMeshResolution WRITE setXYMeshResolution NOTIFY xyMeshResolutionChanged)
+ Q_PROPERTY(QSize yzMeshResolution READ yzMeshResolution WRITE setYZMeshResolution NOTIFY yzMeshResolutionChanged)
+ Q_PROPERTY(QSize xzMeshResolution READ xzMeshResolution WRITE setXZMeshResolution NOTIFY xzMeshResolutionChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *tangentAttribute READ tangentAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QCuboidGeometry(QNode *parent = Q_NULLPTR);
+ ~QCuboidGeometry();
+
+ void updateIndices();
+ void updateVertices();
+
+ float xExtent() const;
+ float yExtent() const;
+ float zExtent() const;
+ QSize yzMeshResolution() const;
+ QSize xyMeshResolution() const;
+ QSize xzMeshResolution() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *tangentAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setXExtent(float xExtent);
+ void setYExtent(float yExtent);
+ void setZExtent(float zExtent);
+ void setYZMeshResolution(const QSize &resolution);
+ void setXZMeshResolution(const QSize &resolution);
+ void setXYMeshResolution(const QSize &resolution);
+
+Q_SIGNALS:
+ void xExtentChanged(float xExtent);
+ void yExtentChanged(float yExtent);
+ void zExtentChanged(float zExtent);
+
+ void yzMeshResolutionChanged(const QSize &yzMeshResolution);
+ void xzMeshResolutionChanged(const QSize &xzMeshResolution);
+ void xyMeshResolutionChanged(const QSize &xyMeshResolution);
+
+protected:
+ QCuboidGeometry(QCuboidGeometryPrivate &dd, QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QCuboidGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCUBOIDGEOMETRY_H
diff --git a/src/extras/geometries/qcuboidgeometry_p.h b/src/extras/geometries/qcuboidgeometry_p.h
new file mode 100644
index 000000000..212be19b4
--- /dev/null
+++ b/src/extras/geometries/qcuboidgeometry_p.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCUBOIDGEOMETRY_P_H
+#define QT3DEXTRAS_QCUBOIDGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QCuboidGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QCuboidGeometryPrivate();
+ void init();
+
+ // Dimensions
+ float m_xExtent;
+ float m_yExtent;
+ float m_zExtent;
+
+ // Resolutions of faces with normal x, y, and z
+ QSize m_yzFaceResolution;
+ QSize m_xzFaceResolution;
+ QSize m_xyFaceResolution;
+
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_tangentAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+
+ Q_DECLARE_PUBLIC(QCuboidGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCUBOIDGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qcuboidmesh.cpp b/src/extras/geometries/qcuboidmesh.cpp
new file mode 100644
index 000000000..99cfa4733
--- /dev/null
+++ b/src/extras/geometries/qcuboidmesh.cpp
@@ -0,0 +1,215 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcuboidmesh.h"
+#include "qcuboidgeometry.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+/*!
+ * \qmltype QCuboidMesh
+ * \instantiates Qt3DRender::QCuboidMesh
+ * \inqmlmodule Qt3D.Render
+ * \brief A cube mesh.
+ */
+
+/*!
+ * \qmlproperty float CuboidMesh::xExtent
+ *
+ * Holds the x extent.
+ */
+
+/*!
+ * \qmlproperty float CuboidMesh::yExtent
+ *
+ * Holds the y extent.
+ */
+
+/*!
+ * \qmlproperty float CuboidMesh::zExtent
+ *
+ * Holds the z extent.
+ */
+
+/*!
+ * \qmlproperty size CuboidMesh::yzMeshResolution
+ *
+ * Holds the y-z resolution.
+ */
+
+/*!
+ * \qmlproperty size CuboidMesh::xzMeshResolution
+ *
+ * Holds the x-z resolution.
+ */
+
+/*!
+ * \qmlproperty size CuboidMesh::xyMeshResolution
+ *
+ * Holds the x-y resolution.
+ */
+
+/*!
+ * \class Qt3DRender::QCuboidMesh
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometryRenderer
+ *
+ * \brief A cube mesh.
+ */
+
+/*!
+ * Constructs a new QCuboidMedh with \a parent.
+ */
+QCuboidMesh::QCuboidMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QCuboidGeometry *geometry = new QCuboidGeometry(this);
+ QObject::connect(geometry, &QCuboidGeometry::xExtentChanged, this, &QCuboidMesh::xExtentChanged);
+ QObject::connect(geometry, &QCuboidGeometry::yExtentChanged, this, &QCuboidMesh::yExtentChanged);
+ QObject::connect(geometry, &QCuboidGeometry::zExtentChanged, this, &QCuboidMesh::zExtentChanged);
+ QObject::connect(geometry, &QCuboidGeometry::xyMeshResolutionChanged, this, &QCuboidMesh::xyMeshResolutionChanged);
+ QObject::connect(geometry, &QCuboidGeometry::xzMeshResolutionChanged, this, &QCuboidMesh::xzMeshResolutionChanged);
+ QObject::connect(geometry, &QCuboidGeometry::yzMeshResolutionChanged, this, &QCuboidMesh::yzMeshResolutionChanged);
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+/*!
+ * Destroys this cube mesh.
+ */
+QCuboidMesh::~QCuboidMesh()
+{
+ QNode::cleanup();
+}
+
+void QCuboidMesh::setXExtent(float xExtent)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setXExtent(xExtent);
+}
+
+/*!
+ * \property QCuboidMesh::xExtent
+ *
+ * Holds the x extent.
+ */
+float QCuboidMesh::xExtent() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->xExtent();
+}
+
+void QCuboidMesh::setYExtent(float yExtent)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setYExtent(yExtent);
+}
+
+/*!
+ * \property QCuboidMesh::yExtent
+ *
+ * Holds the y extent.
+ */
+float QCuboidMesh::yExtent() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->yExtent();
+}
+
+void QCuboidMesh::setZExtent(float zExtent)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setZExtent(zExtent);
+}
+
+/*!
+ * \property QCuboidMesh::zExtent
+ *
+ * Holds the z extent.
+ */
+float QCuboidMesh::zExtent() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->zExtent();
+}
+
+void QCuboidMesh::setYZMeshResolution(const QSize &resolution)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setYZMeshResolution(resolution);
+}
+
+/*!
+ * \property QCuboidMesh::yzMeshResolution
+ *
+ * Holds the y-z resolution.
+ */
+QSize QCuboidMesh::yzMeshResolution() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->yzMeshResolution();
+}
+
+void QCuboidMesh::setXZMeshResolution(const QSize &resolution)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setXZMeshResolution(resolution);
+}
+
+/*!
+ * \property QCuboidMesh::xzMeshResolution
+ *
+ * Holds the x-z resolution.
+ */
+QSize QCuboidMesh::xzMeshResolution() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->xzMeshResolution();
+}
+
+void QCuboidMesh::setXYMeshResolution(const QSize &resolution)
+{
+ static_cast<QCuboidGeometry *>(geometry())->setXYMeshResolution(resolution);
+}
+
+/*!
+ * \property QCuboidMesh::xyMeshResolution
+ *
+ * Holds the x-y resolution.
+ */
+QSize QCuboidMesh::xyMeshResolution() const
+{
+ return static_cast<QCuboidGeometry *>(geometry())->xyMeshResolution();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qcuboidmesh.h b/src/extras/geometries/qcuboidmesh.h
new file mode 100644
index 000000000..72f6a007d
--- /dev/null
+++ b/src/extras/geometries/qcuboidmesh.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_CUBOIDMESH_H
+#define QT3DEXTRAS_CUBOIDMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QT3DEXTRASSHARED_EXPORT QCuboidMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+
+ Q_PROPERTY(float xExtent READ xExtent WRITE setXExtent NOTIFY xExtentChanged)
+ Q_PROPERTY(float yExtent READ yExtent WRITE setYExtent NOTIFY yExtentChanged)
+ Q_PROPERTY(float zExtent READ zExtent WRITE setZExtent NOTIFY zExtentChanged)
+ Q_PROPERTY(QSize yzMeshResolution READ yzMeshResolution WRITE setYZMeshResolution NOTIFY yzMeshResolutionChanged)
+ Q_PROPERTY(QSize xzMeshResolution READ xzMeshResolution WRITE setXZMeshResolution NOTIFY xzMeshResolutionChanged)
+ Q_PROPERTY(QSize xyMeshResolution READ xyMeshResolution WRITE setXYMeshResolution NOTIFY xyMeshResolutionChanged)
+
+public:
+ explicit QCuboidMesh(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QCuboidMesh();
+
+ float xExtent() const;
+ float yExtent() const;
+ float zExtent() const;
+ QSize yzMeshResolution() const;
+ QSize xzMeshResolution() const;
+ QSize xyMeshResolution() const;
+
+public Q_SLOTS:
+ void setXExtent(float xExtent);
+ void setYExtent(float yExtent);
+ void setZExtent(float zExtent);
+ void setYZMeshResolution(const QSize &resolution);
+ void setXZMeshResolution(const QSize &resolution);
+ void setXYMeshResolution(const QSize &resolution);
+
+Q_SIGNALS:
+ void xExtentChanged(float xExtent);
+ void yExtentChanged(float yExtent);
+ void zExtentChanged(float zExtent);
+
+ void yzMeshResolutionChanged(const QSize &yzMeshResolution);
+ void xzMeshResolutionChanged(const QSize &xzMeshResolution);
+ void xyMeshResolutionChanged(const QSize &xyMeshResolution);
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setInstanceCount(int instanceCount);
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_CUBOIDMESH_H
diff --git a/src/extras/geometries/qcylindergeometry.cpp b/src/extras/geometries/qcylindergeometry.cpp
new file mode 100644
index 000000000..f514d0dc9
--- /dev/null
+++ b/src/extras/geometries/qcylindergeometry.cpp
@@ -0,0 +1,585 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include "qcylindergeometry.h"
+#include "qcylindergeometry_p.h"
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qattribute.h>
+#include <qmath.h>
+#include <QVector3D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+void createSidesVertices(float *&verticesPtr,
+ int rings,
+ int slices,
+ double radius,
+ double length)
+{
+ const float dY = length / static_cast<float>(rings - 1);
+ const float dTheta = (M_PI * 2) / static_cast<float>(slices);
+
+ for (int ring = 0; ring < rings; ++ring) {
+ const float y = -length / 2.0f + static_cast<float>(ring) * dY;
+
+ for (int slice = 0; slice <= slices; ++slice) {
+ const float theta = static_cast<float>(slice) * dTheta;
+ const float ct = qCos(theta);
+ const float st = qSin(theta);
+
+ *verticesPtr++ = radius * ct;
+ *verticesPtr++ = y;
+ *verticesPtr++ = radius * st;
+
+ *verticesPtr++ = (y + length / 2.0) / length;
+ *verticesPtr++ = theta / (M_PI * 2);
+
+ QVector3D n(ct, 0.0f, st);
+ n.normalize();
+ *verticesPtr++ = n.x();
+ *verticesPtr++ = n.y();
+ *verticesPtr++ = n.z();
+ }
+ }
+}
+
+void createSidesIndices(quint16 *&indicesPtr, int rings, int slices)
+{
+ for (int ring = 0; ring < rings - 1; ++ring) {
+ const int ringIndexStart = ring * (slices + 1);
+ const int nextRingIndexStart = (ring + 1) * (slices + 1);
+
+ for (int slice = 0; slice < slices; ++slice) {
+ const int nextSlice = slice + 1;
+
+ *indicesPtr++ = (ringIndexStart + slice);
+ *indicesPtr++ = (nextRingIndexStart + slice);
+ *indicesPtr++ = (ringIndexStart + nextSlice);
+ *indicesPtr++ = (ringIndexStart + nextSlice);
+ *indicesPtr++ = (nextRingIndexStart + slice);
+ *indicesPtr++ = (nextRingIndexStart + nextSlice);
+ }
+ }
+}
+
+void createDiscVertices(float *&verticesPtr,
+ int slices,
+ double radius,
+ double yPosition)
+{
+ const float dTheta = (M_PI * 2) / static_cast<float>(slices);
+ const double yNormal = (yPosition < 0.0f) ? -1.0f : 1.0f;
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yPosition;
+ *verticesPtr++ = 0.0f;
+
+ *verticesPtr++ = 1.0f;
+ *verticesPtr++ = 0.0f;
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yNormal;
+ *verticesPtr++ = 0.0f;
+
+ for (int slice = 0; slice <= slices; ++slice) {
+ const float theta = static_cast<float>(slice) * dTheta;
+ const float ct = qCos(theta);
+ const float st = qSin(theta);
+
+ *verticesPtr++ = radius * ct;
+ *verticesPtr++ = yPosition;
+ *verticesPtr++ = radius * st;
+
+ *verticesPtr++ = 1.0f;
+ *verticesPtr++ = theta / (M_PI * 2);
+
+ *verticesPtr++ = 0.0f;
+ *verticesPtr++ = yNormal;
+ *verticesPtr++ = 0.0f;
+ }
+}
+
+void createDiscIndices(quint16 *&indicesPtr,
+ int discCenterIndex,
+ int slices,
+ double yPosition)
+{
+ const double yNormal = (yPosition < 0.0f) ? -1.0f : 1.0f;
+
+ for (int slice = 0; slice < slices; ++slice) {
+ const int nextSlice = slice + 1;
+
+ *indicesPtr++ = discCenterIndex;
+ *indicesPtr++ = (discCenterIndex + 1 + nextSlice);
+ *indicesPtr++ = (discCenterIndex + 1 + slice);
+
+ if (yNormal < 0.0f)
+ qSwap(*(indicesPtr -1), *(indicesPtr - 2));
+ }
+}
+
+} // anonymous
+
+
+class CylinderVertexDataFunctor : public QBufferDataGenerator
+{
+public:
+ CylinderVertexDataFunctor(int rings, int slices, float radius, float length)
+ : m_rings(rings)
+ , m_slices(slices)
+ , m_radius(radius)
+ , m_length(length)
+ {}
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ const int verticesCount = (m_slices + 1) * m_rings + 2 * (m_slices + 1) + 2;
+ // vec3 pos, vec2 texCoord, vec3 normal
+ const quint32 vertexSize = (3 + 2 + 3) * sizeof(float);
+
+ QByteArray verticesData;
+ verticesData.resize(vertexSize * verticesCount);
+ float *verticesPtr = reinterpret_cast<float*>(verticesData.data());
+
+ createSidesVertices(verticesPtr, m_rings, m_slices, m_radius, m_length);
+ createDiscVertices(verticesPtr, m_slices, m_radius, -m_length * 0.5f);
+ createDiscVertices(verticesPtr, m_slices, m_radius, m_length * 0.5f);
+
+ return verticesData;
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const CylinderVertexDataFunctor *otherFunctor = functor_cast<CylinderVertexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices &&
+ otherFunctor->m_radius == m_radius &&
+ otherFunctor->m_length == m_length);
+ return false;
+ }
+
+ QT3D_FUNCTOR(CylinderVertexDataFunctor)
+
+private:
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ float m_length;
+};
+
+class CylinderIndexDataFunctor : public QBufferDataGenerator
+{
+public:
+ CylinderIndexDataFunctor(int rings, int slices, float length)
+ : m_rings(rings)
+ , m_slices(slices)
+ , m_length(length)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ const int facesCount = (m_slices * 2) * (m_rings - 1) // two tris per side, for each pair of adjacent rings
+ + m_slices * 2; // two caps
+ const int indicesCount = facesCount * 3;
+ const int indexSize = sizeof(quint16);
+ Q_ASSERT(indicesCount < 65536);
+
+ QByteArray indicesBytes;
+ indicesBytes.resize(indicesCount * indexSize);
+ quint16 *indicesPtr = reinterpret_cast<quint16*>(indicesBytes.data());
+
+ createSidesIndices(indicesPtr, m_rings, m_slices);
+ createDiscIndices(indicesPtr, m_rings * (m_slices + 1), m_slices, -m_length * 0.5);
+ createDiscIndices(indicesPtr, m_rings * (m_slices + 1) + m_slices + 2, m_slices, m_length * 0.5);
+
+ return indicesBytes;
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const CylinderIndexDataFunctor *otherFunctor = functor_cast<CylinderIndexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices &&
+ otherFunctor->m_length == m_length);
+ return false;
+ }
+
+ QT3D_FUNCTOR(CylinderIndexDataFunctor)
+
+private:
+ int m_rings;
+ int m_slices;
+ float m_length;
+};
+
+
+QCylinderGeometryPrivate::QCylinderGeometryPrivate()
+ : QGeometryPrivate()
+ , m_rings(16)
+ , m_slices(16)
+ , m_radius(1.0f)
+ , m_length(1.0f)
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QCylinderGeometryPrivate::init()
+{
+ Q_Q(QCylinderGeometry);
+ m_positionAttribute = new QAttribute(q);
+ m_normalAttribute = new QAttribute(q);
+ m_texCoordAttribute = new QAttribute(q);
+ m_indexAttribute = new QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+
+ // vec3 pos, vec2 tex, vec3 normal
+ const quint32 elementSize = 3 + 2 + 3;
+ const quint32 stride = elementSize * sizeof(float);
+ const int nVerts = (m_slices + 1) * m_rings + 2 * (m_slices + 1) + 2;
+ const int faces = (m_slices * 2) * (m_rings - 1) + (m_slices * 2);
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ m_indexAttribute->setCount(faces * 3);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CylinderVertexDataFunctor(m_rings, m_slices, m_radius, m_length)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CylinderIndexDataFunctor(m_rings, m_slices, m_length)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+/*!
+ * \qmltype CylinderGeometry
+ * \instantiates Qt3DRender::QCylinderGeometry
+ * \inqmlmodule Qt3D.Render
+ */
+
+/*!
+ * \qmlproperty int CylinderGeometry::rings
+ *
+ * Holds the number of rings in the cylinder.
+ */
+
+/*!
+ * \qmlproperty int CylinderGeometry::slices
+ *
+ * Holds the number of slices in the cylinder.
+ */
+
+/*!
+ * \qmlproperty float CylinderGeometry::radius
+ *
+ * Holds the radius of the cylinder.
+ */
+
+/*!
+ * \qmlproperty float CylinderGeometry::length
+ *
+ * Holds the length of the cylinder.
+ */
+
+/*!
+ * \qmlproperty Attribute CylinderGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CylinderGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CylinderGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute CylinderGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+
+/*!
+ * \class Qt3DRender::QCylinderGeometry
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometry
+ */
+
+/*!
+ * Constructs a new QCylinderMesh with \a parent.
+ */
+QCylinderGeometry::QCylinderGeometry(QNode *parent)
+ : QGeometry(*new QCylinderGeometryPrivate, parent)
+{
+ Q_D(QCylinderGeometry);
+ d->init();
+}
+
+/*!
+ * \internal
+ */
+QCylinderGeometry::QCylinderGeometry(QCylinderGeometryPrivate &dd, QNode *parent)
+ :QGeometry(dd, parent)
+{
+ Q_D(QCylinderGeometry);
+ d->init();
+}
+
+/*!
+ * Destroys the geometry.
+ */
+QCylinderGeometry::~QCylinderGeometry()
+{
+ QGeometry::cleanup();
+}
+
+/*!
+ * Updates the vertices based on rings and slices.
+ */
+void QCylinderGeometry::updateVertices()
+{
+ Q_D(QCylinderGeometry);
+ const int nVerts = (d->m_slices + 1) * (d->m_rings + 1);
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CylinderVertexDataFunctor(d->m_rings, d->m_slices, d->m_radius, d->m_length)));
+}
+
+/*!
+ * Updates the indices based on rings and slices.
+ */
+void QCylinderGeometry::updateIndices()
+{
+ Q_D(QCylinderGeometry);
+ const int faces = (d->m_slices * 2) * d->m_rings + (2 * d->m_slices);
+ d->m_indexAttribute->setCount(faces * 3);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new CylinderIndexDataFunctor(d->m_rings, d->m_slices, d->m_length)));
+}
+
+void QCylinderGeometry::setRings(int rings)
+{
+ Q_D(QCylinderGeometry);
+ if (rings != d->m_rings) {
+ d->m_rings = rings;
+ updateVertices();
+ updateIndices();
+ emit ringsChanged(rings);
+ }
+}
+
+void QCylinderGeometry::setSlices(int slices)
+{
+ Q_D(QCylinderGeometry);
+ if (slices != d->m_slices) {
+ d->m_slices = slices;
+ updateVertices();
+ updateIndices();
+ emit slicesChanged(slices);
+ }
+}
+
+void QCylinderGeometry::setRadius(float radius)
+{
+ Q_D(QCylinderGeometry);
+ if (radius != d->m_radius) {
+ d->m_radius = radius;
+ updateVertices();
+ emit radiusChanged(radius);
+ }
+}
+
+void QCylinderGeometry::setLength(float length)
+{
+ Q_D(QCylinderGeometry);
+ if (length != d->m_length) {
+ d->m_length = length;
+ updateVertices();
+ updateIndices();
+ emit lengthChanged(length);
+ }
+}
+
+/*!
+ * \property QCylinderGeometry::rings
+ *
+ * Holds the number of rings in the cylinder.
+ */
+int QCylinderGeometry::rings() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_rings;
+}
+
+/*!
+ * \property QCylinderGeometry::slices
+ *
+ * Holds the number of slices in the cylinder.
+ */
+int QCylinderGeometry::slices() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_slices;
+}
+
+/*!
+ * \property QCylinderGeometry::radius
+ *
+ * Holds the radius of the cylinder.
+ */
+float QCylinderGeometry::radius() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_radius;
+}
+
+/*!
+ * \property QCylinderGeometry::length
+ *
+ * Holds the length of the cylinder.
+ */
+float QCylinderGeometry::length() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_length;
+}
+
+/*!
+ * \property QCylinderGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+QAttribute *QCylinderGeometry::positionAttribute() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_positionAttribute;
+}
+
+/*!
+ * \property QCylinderGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+QAttribute *QCylinderGeometry::normalAttribute() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_normalAttribute;
+}
+
+/*!
+ * \property QCylinderGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+QAttribute *QCylinderGeometry::texCoordAttribute() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_texCoordAttribute;
+}
+
+/*!
+ * \property QCylinderGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+QAttribute *QCylinderGeometry::indexAttribute() const
+{
+ Q_D(const QCylinderGeometry);
+ return d->m_indexAttribute;
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qcylindergeometry.h b/src/extras/geometries/qcylindergeometry.h
new file mode 100644
index 000000000..570b2b25d
--- /dev/null
+++ b/src/extras/geometries/qcylindergeometry.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCYLINDERGEOMETRY_H
+#define QT3DEXTRAS_QCYLINDERGEOMETRY_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometry.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QCylinderGeometryPrivate;
+class QT3DEXTRASSHARED_EXPORT QCylinderGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QCylinderGeometry(QNode *parent = Q_NULLPTR);
+ ~QCylinderGeometry();
+
+ void updateVertices();
+ void updateIndices();
+
+ int rings() const;
+ int slices() const;
+ float radius() const;
+ float length() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setLength(float length);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void lengthChanged(float length);
+
+protected:
+ QCylinderGeometry(QCylinderGeometryPrivate &dd, QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QCylinderGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCYLINDERGEOMETRY_H
diff --git a/src/extras/geometries/qcylindergeometry_p.h b/src/extras/geometries/qcylindergeometry_p.h
new file mode 100644
index 000000000..50c37cb62
--- /dev/null
+++ b/src/extras/geometries/qcylindergeometry_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCYLINDERGEOMETRY_P_H
+#define QT3DEXTRAS_QCYLINDERGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of other Qt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // namespace Qt3DRender
+
+namespace Qt3DExtras {
+
+class QCylinderGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QCylinderGeometryPrivate();
+
+ void init();
+
+ Q_DECLARE_PUBLIC(QCylinderGeometry)
+
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ float m_length;
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCYLINDERGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qcylindermesh.cpp b/src/extras/geometries/qcylindermesh.cpp
new file mode 100644
index 000000000..9cbf729a6
--- /dev/null
+++ b/src/extras/geometries/qcylindermesh.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include "qcylindermesh.h"
+#include "qcylindergeometry.h"
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qattribute.h>
+#include <qmath.h>
+#include <QVector3D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+/*!
+ * \qmltype CylinderMesh
+ * \instantiates Qt3DRender::QCylinderMesh
+ * \inqmlmodule Qt3D.Render
+ * \brief A cylindrical mesh.
+ */
+
+/*!
+ * \qmlproperty int CylinderMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+
+/*!
+ * \qmlproperty int CylinderMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+
+/*!
+ * \qmlproperty float CylinderMesh::radius
+ *
+ * Holds the radius of the cylinder.
+ */
+
+/*!
+ * \qmlproperty float CylinderMesh::length
+ *
+ * Holds the length of the cylinder.
+ */
+
+/*!
+ * \class Qt3DRender::QCylinderMesh
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometryRenderer
+ *
+ * \brief A cylindrical mesh.
+ */
+
+/*!
+ * Constructs a new QCylinderMesh with \a parent.
+ */
+QCylinderMesh::QCylinderMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QCylinderGeometry *geometry = new QCylinderGeometry(this);
+ QObject::connect(geometry, &QCylinderGeometry::radiusChanged, this, &QCylinderMesh::radiusChanged);
+ QObject::connect(geometry, &QCylinderGeometry::ringsChanged, this, &QCylinderMesh::ringsChanged);
+ QObject::connect(geometry, &QCylinderGeometry::slicesChanged, this, &QCylinderMesh::slicesChanged);
+ QObject::connect(geometry, &QCylinderGeometry::lengthChanged, this, &QCylinderMesh::lengthChanged);
+
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+/*!
+ * Destroys this cylinder mesh.
+ */
+QCylinderMesh::~QCylinderMesh()
+{
+ QNode::cleanup();
+}
+
+void QCylinderMesh::setRings(int rings)
+{
+ static_cast<QCylinderGeometry *>(geometry())->setRings(rings);
+}
+
+void QCylinderMesh::setSlices(int slices)
+{
+ static_cast<QCylinderGeometry *>(geometry())->setSlices(slices);
+}
+
+void QCylinderMesh::setRadius(float radius)
+{
+ static_cast<QCylinderGeometry *>(geometry())->setRadius(radius);
+}
+
+void QCylinderMesh::setLength(float length)
+{
+ static_cast<QCylinderGeometry *>(geometry())->setLength(length);
+}
+
+/*!
+ * \property QCylinderMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+int QCylinderMesh::rings() const
+{
+ return static_cast<QCylinderGeometry *>(geometry())->rings();
+}
+
+/*!
+ * \property QCylinderMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+int QCylinderMesh::slices() const
+{
+ return static_cast<QCylinderGeometry *>(geometry())->slices();
+}
+
+/*!
+ * \property QCylinderMesh::radius
+ *
+ * Holds the radius of the cylinder.
+ */
+float QCylinderMesh::radius() const
+{
+ return static_cast<QCylinderGeometry *>(geometry())->radius();
+}
+
+/*!
+ * \property QCylinderMesh::length
+ *
+ * Holds the length of the cylinder.
+ */
+float QCylinderMesh::length() const
+{
+ return static_cast<QCylinderGeometry *>(geometry())->length();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qcylindermesh.h b/src/extras/geometries/qcylindermesh.h
new file mode 100644
index 000000000..256508576
--- /dev/null
+++ b/src/extras/geometries/qcylindermesh.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QCYLINDERMESH_H
+#define QT3DEXTRAS_QCYLINDERMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+
+QT_BEGIN_NAMESPACE
+
+
+namespace Qt3DExtras {
+
+class QT3DEXTRASSHARED_EXPORT QCylinderMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(float length READ length WRITE setLength NOTIFY lengthChanged)
+public:
+ explicit QCylinderMesh(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QCylinderMesh();
+
+ int rings() const;
+ int slices() const;
+ float radius() const;
+ float length() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setLength(float length);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void lengthChanged(float length);
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setInstanceCount(int instanceCount);
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QCYLINDERMESH_H
diff --git a/src/extras/geometries/qplanegeometry.cpp b/src/extras/geometries/qplanegeometry.cpp
new file mode 100644
index 000000000..a0c0ffbc0
--- /dev/null
+++ b/src/extras/geometries/qplanegeometry.cpp
@@ -0,0 +1,529 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplanegeometry.h"
+#include "qplanegeometry_p.h"
+#include <Qt3DRender/qattribute.h>
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <limits>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+QByteArray createPlaneVertexData(float w, float h, const QSize &resolution)
+{
+ Q_ASSERT(w > 0.0f);
+ Q_ASSERT(h > 0.0f);
+ Q_ASSERT(resolution.width() >= 2);
+ Q_ASSERT(resolution.height() >= 2);
+
+ const int nVerts = resolution.width() * resolution.height();
+
+ // Populate a buffer with the interleaved per-vertex data with
+ // vec3 pos, vec2 texCoord, vec3 normal, vec4 tangent
+ const quint32 elementSize = 3 + 2 + 3 + 4;
+ const quint32 stride = elementSize * sizeof(float);
+ QByteArray bufferBytes;
+ bufferBytes.resize(stride * nVerts);
+ float* fptr = reinterpret_cast<float*>(bufferBytes.data());
+
+ const float x0 = -w / 2.0f;
+ const float z0 = -h / 2.0f;
+ const float dx = w / (resolution.width() - 1);
+ const float dz = h / (resolution.height() - 1);
+ const float du = 1.0 / (resolution.width() - 1);
+ const float dv = 1.0 / (resolution.height() - 1);
+
+ // Iterate over z
+ for (int j = 0; j < resolution.height(); ++j) {
+ const float z = z0 + static_cast<float>(j) * dz;
+ const float v = static_cast<float>(j) * dv;
+
+ // Iterate over x
+ for (int i = 0; i < resolution.width(); ++i) {
+ const float x = x0 + static_cast<float>(i) * dx;
+ const float u = static_cast<float>(i) * du;
+
+ // position
+ *fptr++ = x;
+ *fptr++ = 0.0;
+ *fptr++ = z;
+
+ // texture coordinates
+ *fptr++ = u;
+ *fptr++ = v;
+
+ // normal
+ *fptr++ = 0.0f;
+ *fptr++ = 1.0f;
+ *fptr++ = 0.0f;
+
+ // tangent
+ *fptr++ = 1.0f;
+ *fptr++ = 0.0f;
+ *fptr++ = 0.0f;
+ *fptr++ = 1.0f;
+ }
+ }
+
+ return bufferBytes;
+}
+
+QByteArray createPlaneIndexData(const QSize &resolution)
+{
+ // Create the index data. 2 triangles per rectangular face
+ const int faces = 2 * (resolution.width() - 1) * (resolution.height() - 1);
+ const int indices = 3 * faces;
+ Q_ASSERT(indices < std::numeric_limits<quint16>::max());
+ QByteArray indexBytes;
+ indexBytes.resize(indices * sizeof(quint16));
+ quint16* indexPtr = reinterpret_cast<quint16*>(indexBytes.data());
+
+ // Iterate over z
+ for (int j = 0; j < resolution.height() - 1; ++j) {
+ const int rowStartIndex = j * resolution.width();
+ const int nextRowStartIndex = (j + 1) * resolution.width();
+
+ // Iterate over x
+ for (int i = 0; i < resolution.width() - 1; ++i) {
+ // Split quad into two triangles
+ *indexPtr++ = rowStartIndex + i;
+ *indexPtr++ = nextRowStartIndex + i;
+ *indexPtr++ = rowStartIndex + i + 1;
+
+ *indexPtr++ = nextRowStartIndex + i;
+ *indexPtr++ = nextRowStartIndex + i + 1;
+ *indexPtr++ = rowStartIndex + i + 1;
+ }
+ }
+
+ return indexBytes;
+}
+
+} // anonymous
+
+class PlaneVertexBufferFunctor : public QBufferDataGenerator
+{
+public:
+ explicit PlaneVertexBufferFunctor(float w, float h, const QSize &resolution)
+ : m_width(w)
+ , m_height(h)
+ , m_resolution(resolution)
+ {}
+
+ ~PlaneVertexBufferFunctor() {}
+
+ QByteArray operator()() Q_DECL_FINAL
+ {
+ return createPlaneVertexData(m_width, m_height, m_resolution);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL
+ {
+ const PlaneVertexBufferFunctor *otherFunctor = functor_cast<PlaneVertexBufferFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_width == m_width &&
+ otherFunctor->m_height == m_height &&
+ otherFunctor->m_resolution == m_resolution);
+ return false;
+ }
+
+ QT3D_FUNCTOR(PlaneVertexBufferFunctor)
+
+ private:
+ float m_width;
+ float m_height;
+ QSize m_resolution;
+};
+
+class PlaneIndexBufferFunctor : public QBufferDataGenerator
+{
+public:
+ explicit PlaneIndexBufferFunctor(const QSize &resolution)
+ : m_resolution(resolution)
+ {}
+
+ ~PlaneIndexBufferFunctor() {}
+
+ QByteArray operator()() Q_DECL_FINAL
+ {
+ return createPlaneIndexData(m_resolution);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_FINAL
+ {
+ const PlaneIndexBufferFunctor *otherFunctor = functor_cast<PlaneIndexBufferFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_resolution == m_resolution);
+ return false;
+ }
+
+ QT3D_FUNCTOR(PlaneIndexBufferFunctor)
+
+ private:
+ QSize m_resolution;
+};
+
+/*!
+ * \qmltype PlaneGeometry
+ * \instantiates Qt3DRender::QPlaneGeometry
+ * \inqmlmodule Qt3D.Render
+ */
+
+/*!
+ * \qmlproperty float PlaneGeometry::width
+ *
+ * Holds the plane width.
+ */
+
+/*!
+ * \qmlproperty float PlaneGeometry::height
+ *
+ * Holds the plane height.
+ */
+
+/*!
+ * \qmlproperty size PlaneGeometry::resolution
+ *
+ * Holds the plane resolution.
+ */
+
+/*!
+ * \qmlproperty Attribute PlaneGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute PlaneGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute PlaneGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute PlaneGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute PlaneGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+
+/*!
+ * \class Qt3DRender::QPlaneGeometry
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometry
+ */
+
+/*!
+ * Constructs a new QPlaneGeometry with \a parent.
+ */
+QPlaneGeometry::QPlaneGeometry(QPlaneGeometry::QNode *parent)
+ : QGeometry(*new QPlaneGeometryPrivate(), parent)
+{
+ Q_D(QPlaneGeometry);
+ d->init();
+}
+
+/*!
+ * \internal
+ */
+QPlaneGeometry::QPlaneGeometry(QPlaneGeometryPrivate &dd, QNode *parent)
+ : QGeometry(dd, parent)
+{
+ Q_D(QPlaneGeometry);
+ d->init();
+}
+
+/*!
+ * Destroys this geometry.
+ */
+QPlaneGeometry::~QPlaneGeometry()
+{
+ QGeometry::cleanup();
+}
+
+/*!
+ * Updates vertices based on resolution.
+ */
+void QPlaneGeometry::updateVertices()
+{
+ Q_D(QPlaneGeometry);
+ const int nVerts = d->m_meshResolution.width() * d->m_meshResolution.height();
+
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_tangentAttribute->setCount(nVerts);
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new PlaneVertexBufferFunctor(d->m_width, d->m_height, d->m_meshResolution)));
+}
+
+/*!
+ * Updates indices based on resolution.
+ */
+void QPlaneGeometry::updateIndices()
+{
+ Q_D(QPlaneGeometry);
+ const int faces = 2 * (d->m_meshResolution.width() - 1) * (d->m_meshResolution.height() - 1);
+ // Each primitive has 3 vertices
+ d->m_indexAttribute->setCount(faces * 3);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new PlaneIndexBufferFunctor(d->m_meshResolution)));
+
+}
+
+void QPlaneGeometry::setResolution(const QSize &resolution)
+{
+ Q_D(QPlaneGeometry);
+ if (d->m_meshResolution == resolution)
+ return;
+ d->m_meshResolution = resolution;
+ updateVertices();
+ updateIndices();
+ emit resolutionChanged(resolution);
+}
+
+void QPlaneGeometry::setWidth(float width)
+{
+ Q_D(QPlaneGeometry);
+ if (width == d->m_width)
+ return;
+ d->m_width = width;
+ updateVertices();
+ emit widthChanged(width);
+}
+
+void QPlaneGeometry::setHeight(float height)
+{
+ Q_D(QPlaneGeometry);
+ if (height == d->m_height)
+ return;
+ d->m_height = height;
+ updateVertices();
+ emit heightChanged(height);
+}
+
+/*!
+ * \property QPlaneGeometry::resolution
+ *
+ * Holds the plane resolution.
+ */
+QSize QPlaneGeometry::resolution() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_meshResolution;
+}
+
+/*!
+ * \property QPlaneGeometry::width
+ *
+ * Holds the plane width.
+ */
+float QPlaneGeometry::width() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_width;
+}
+
+/*!
+ * \property QPlaneGeometry::height
+ *
+ * Holds the plane height.
+ */
+float QPlaneGeometry::height() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_height;
+}
+
+/*!
+ * \property QPlaneGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+QAttribute *QPlaneGeometry::positionAttribute() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_positionAttribute;
+}
+
+/*!
+ * \property QPlaneGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+QAttribute *QPlaneGeometry::normalAttribute() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_normalAttribute;
+}
+
+/*!
+ * \property QPlaneGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+QAttribute *QPlaneGeometry::texCoordAttribute() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_texCoordAttribute;
+}
+
+/*!
+ * \property QPlaneGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+QAttribute *QPlaneGeometry::tangentAttribute() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_tangentAttribute;
+}
+
+/*!
+ * \property QPlaneGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+QAttribute *QPlaneGeometry::indexAttribute() const
+{
+ Q_D(const QPlaneGeometry);
+ return d->m_indexAttribute;
+}
+
+QPlaneGeometryPrivate::QPlaneGeometryPrivate()
+ : QGeometryPrivate()
+ , m_width(1.0f)
+ , m_height(1.0f)
+ , m_meshResolution(QSize(2, 2))
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_tangentAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QPlaneGeometryPrivate::init()
+{
+ Q_Q(QPlaneGeometry);
+ m_positionAttribute = new QAttribute(q);
+ m_normalAttribute = new QAttribute(q);
+ m_texCoordAttribute = new QAttribute(q);
+ m_tangentAttribute = new QAttribute(q);
+ m_indexAttribute = new QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+
+ const int nVerts = m_meshResolution.width() * m_meshResolution.height();
+ const int stride = (3 + 2 + 3 + 4) * sizeof(float);
+ const int faces = 2 * (m_meshResolution.width() - 1) * (m_meshResolution.height() - 1);
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName());
+ m_tangentAttribute->setDataType(QAttribute::Float);
+ m_tangentAttribute->setDataSize(4);
+ m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_tangentAttribute->setBuffer(m_vertexBuffer);
+ m_tangentAttribute->setByteStride(stride);
+ m_tangentAttribute->setByteOffset(8 * sizeof(float));
+ m_tangentAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ // Each primitive has 3 vertives
+ m_indexAttribute->setCount(faces * 3);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new PlaneVertexBufferFunctor(m_width, m_height, m_meshResolution)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new PlaneIndexBufferFunctor(m_meshResolution)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ q->addAttribute(m_tangentAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qplanegeometry.h b/src/extras/geometries/qplanegeometry.h
new file mode 100644
index 000000000..708ea931d
--- /dev/null
+++ b/src/extras/geometries/qplanegeometry.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPLANEGEOMETRY_H
+#define QT3DEXTRAS_QPLANEGEOMETRY_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometry.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QPlaneGeometryPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QPlaneGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged)
+ Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged)
+ Q_PROPERTY(QSize resolution READ resolution WRITE setResolution NOTIFY resolutionChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *tangentAttribute READ tangentAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QPlaneGeometry(QNode *parent = Q_NULLPTR);
+ ~QPlaneGeometry();
+
+ void updateVertices();
+ void updateIndices();
+
+ QSize resolution() const;
+ float width() const;
+ float height() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *tangentAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setResolution(const QSize &resolution);
+ void setWidth(float width);
+ void setHeight(float height);
+
+Q_SIGNALS:
+ void resolutionChanged(const QSize &resolution);
+ void widthChanged(float width);
+ void heightChanged(float height);
+
+protected:
+ QPlaneGeometry(QPlaneGeometryPrivate &dd, QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QPlaneGeometry)
+};
+
+} // Qt3DExpoerimental
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPLANEGEOMETRY_H
diff --git a/src/extras/geometries/qplanegeometry_p.h b/src/extras/geometries/qplanegeometry_p.h
new file mode 100644
index 000000000..d0a4e88e4
--- /dev/null
+++ b/src/extras/geometries/qplanegeometry_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPLANEGEOMETRY_P_H
+#define QT3DEXTRAS_QPLANEGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QPlaneGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QPlaneGeometryPrivate();
+ void init();
+
+ float m_width;
+ float m_height;
+ QSize m_meshResolution;
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_tangentAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+
+ Q_DECLARE_PUBLIC(QPlaneGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPLANEGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qplanemesh.cpp b/src/extras/geometries/qplanemesh.cpp
new file mode 100644
index 000000000..4c6cc914d
--- /dev/null
+++ b/src/extras/geometries/qplanemesh.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplanemesh.h"
+#include "qplanegeometry.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+/*!
+ * \qmltype PlaneMesh
+ * \instantiates Qt3DRender::QPlaneMesh
+ * \inqmlmodule Qt3D.Render
+ * \brief A square planar mesh.
+ */
+
+/*!
+ * \qmlproperty float PlaneMesh::width
+ *
+ * Holds the plane width.
+ */
+
+/*!
+ * \qmlproperty float PlaneMesh::height
+ *
+ * Holds the plane height.
+ */
+
+/*!
+ * \qmlproperty size PlaneMesh::meshResolution
+ *
+ * Holds the plane resolution.
+ */
+
+/*!
+ * \class Qt3DRender::QPlaneMesh
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometryRenderer
+ *
+ * \brief A square planar mesh.
+ */
+
+/*!
+ * Constructs a new QPlaneMesh with \a parent.
+ */
+QPlaneMesh::QPlaneMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QPlaneGeometry *geometry = new QPlaneGeometry(this);
+ QObject::connect(geometry, &QPlaneGeometry::widthChanged, this, &QPlaneMesh::widthChanged);
+ QObject::connect(geometry, &QPlaneGeometry::heightChanged, this, &QPlaneMesh::heightChanged);
+ QObject::connect(geometry, &QPlaneGeometry::resolutionChanged, this, &QPlaneMesh::meshResolutionChanged);
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+/*!
+ * Destroys this plane mesh.
+ */
+QPlaneMesh::~QPlaneMesh()
+{
+ QNode::cleanup();
+}
+
+void QPlaneMesh::setWidth(float width)
+{
+ static_cast<QPlaneGeometry *>(geometry())->setWidth(width);
+}
+
+/*!
+ * \property QPlaneMesh::width
+ *
+ * Holds the plane width.
+ */
+float QPlaneMesh::width() const
+{
+ return static_cast<QPlaneGeometry *>(geometry())->width();
+}
+
+void QPlaneMesh::setHeight(float height)
+{
+ static_cast<QPlaneGeometry *>(geometry())->setHeight(height);
+}
+
+/*!
+ * \property QPlaneMesh::height
+ *
+ * Holds the plane height.
+ */
+float QPlaneMesh::height() const
+{
+ return static_cast<QPlaneGeometry *>(geometry())->height();
+}
+
+void QPlaneMesh::setMeshResolution(const QSize &resolution)
+{
+ static_cast<QPlaneGeometry *>(geometry())->setResolution(resolution);
+}
+
+/*!
+ * \property QPlaneMesh::meshResolution
+ *
+ * Holds the plane resolution.
+ */
+QSize QPlaneMesh::meshResolution() const
+{
+ return static_cast<QPlaneGeometry *>(geometry())->resolution();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qplanemesh.h b/src/extras/geometries/qplanemesh.h
new file mode 100644
index 000000000..45edbdf45
--- /dev/null
+++ b/src/extras/geometries/qplanemesh.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QPLANEMESH_H
+#define QT3DEXTRAS_QPLANEMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+#include <QSize>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QT3DEXTRASSHARED_EXPORT QPlaneMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+ Q_PROPERTY(float width READ width WRITE setWidth NOTIFY widthChanged)
+ Q_PROPERTY(float height READ height WRITE setHeight NOTIFY heightChanged)
+ Q_PROPERTY(QSize meshResolution READ meshResolution WRITE setMeshResolution NOTIFY meshResolutionChanged)
+
+public:
+ explicit QPlaneMesh(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QPlaneMesh();
+
+ float width() const;
+ float height() const;
+ QSize meshResolution() const;
+
+public Q_SLOTS:
+ void setWidth(float width);
+ void setHeight(float height);
+ void setMeshResolution(const QSize &resolution);
+
+Q_SIGNALS:
+ void meshResolutionChanged(const QSize &meshResolution);
+ void widthChanged(float width);
+ void heightChanged(float height);
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setInstanceCount(int instanceCount);
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DRender
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QPLANEMESH_H
diff --git a/src/extras/geometries/qspheregeometry.cpp b/src/extras/geometries/qspheregeometry.cpp
new file mode 100644
index 000000000..0e610346c
--- /dev/null
+++ b/src/extras/geometries/qspheregeometry.cpp
@@ -0,0 +1,584 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qspheregeometry.h"
+#include "qspheregeometry_p.h"
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qattribute.h>
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include <qmath.h>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+QByteArray createSphereMeshVertexData(float radius, int rings, int slices)
+{
+ QByteArray bufferBytes;
+ // vec3 pos, vec2 texCoord, vec3 normal, vec4 tangent
+ const quint32 elementSize = 3 + 2 + 3 + 4;
+ const quint32 stride = elementSize * sizeof(float);
+ const int nVerts = (slices + 1) * (rings + 1);
+ bufferBytes.resize(stride * nVerts);
+
+ float* fptr = reinterpret_cast<float*>(bufferBytes.data());
+
+ const float dTheta = (M_PI * 2) / static_cast<float>( slices );
+ const float dPhi = M_PI / static_cast<float>( rings );
+ const float du = 1.0f / static_cast<float>( slices );
+ const float dv = 1.0f / static_cast<float>( rings );
+
+ // Iterate over latitudes (rings)
+ for ( int lat = 0; lat < rings + 1; ++lat )
+ {
+ const float phi = M_PI_2 - static_cast<float>( lat ) * dPhi;
+ const float cosPhi = qCos( phi );
+ const float sinPhi = qSin( phi );
+ const float v = 1.0f - static_cast<float>( lat ) * dv;
+
+ // Iterate over longitudes (slices)
+ for ( int lon = 0; lon < slices + 1; ++lon )
+ {
+ const float theta = static_cast<float>( lon ) * dTheta;
+ const float cosTheta = qCos( theta );
+ const float sinTheta = qSin( theta );
+ const float u = static_cast<float>( lon ) * du;
+
+ *fptr++ = radius * cosTheta * cosPhi;
+ *fptr++ = radius * sinPhi;
+ *fptr++ = radius * sinTheta * cosPhi;
+
+ *fptr++ = u;
+ *fptr++ = v;
+
+ *fptr++ = cosTheta * cosPhi;
+ *fptr++ = sinPhi;
+ *fptr++ = sinTheta * cosPhi;
+
+ *fptr++ = sinTheta;
+ *fptr++ = 0.0;
+ *fptr++ = -cosTheta;
+ *fptr++ = 1.0;
+ }
+ }
+ return bufferBytes;
+}
+
+QByteArray createSphereMeshIndexData(int rings, int slices)
+{
+ int faces = (slices * 2) * (rings - 2); // two tris per slice, for all middle rings
+ faces += 2 * slices; // tri per slice for both top and bottom
+
+ QByteArray indexBytes;
+ const int indices = faces * 3;
+ Q_ASSERT(indices < 65536);
+ indexBytes.resize(indices * sizeof(quint16));
+ quint16 *indexPtr = reinterpret_cast<quint16*>(indexBytes.data());
+
+ // top cap
+ {
+ const int nextRingStartIndex = slices + 1;
+ for ( int j = 0; j < slices; ++j )
+ {
+ *indexPtr++ = nextRingStartIndex + j;
+ *indexPtr++ = 0;
+ *indexPtr++ = nextRingStartIndex + j + 1;
+ }
+ }
+
+ for ( int i = 1; i < (rings - 1); ++i )
+ {
+ const int ringStartIndex = i * ( slices + 1 );
+ const int nextRingStartIndex = ( i + 1 ) * ( slices + 1 );
+
+ for ( int j = 0; j < slices; ++j )
+ {
+ // Split the quad into two triangles
+ *indexPtr++ = ringStartIndex + j;
+ *indexPtr++ = ringStartIndex + j + 1;
+ *indexPtr++ = nextRingStartIndex + j;
+ *indexPtr++ = nextRingStartIndex + j;
+ *indexPtr++ = ringStartIndex + j + 1;
+ *indexPtr++ = nextRingStartIndex + j + 1;
+ }
+ }
+
+ // bottom cap
+ {
+ const int ringStartIndex = (rings - 1) * ( slices + 1);
+ const int nextRingStartIndex = (rings) * ( slices + 1);
+ for ( int j = 0; j < slices; ++j )
+ {
+ *indexPtr++ = ringStartIndex + j + 1;
+ *indexPtr++ = nextRingStartIndex;
+ *indexPtr++ = ringStartIndex + j;
+ }
+ }
+
+ return indexBytes;
+}
+
+} // anonymous
+
+class SphereVertexDataFunctor : public QBufferDataGenerator
+{
+public:
+ SphereVertexDataFunctor(int rings, int slices, float radius)
+ : m_rings(rings)
+ , m_slices(slices)
+ , m_radius(radius)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ return createSphereMeshVertexData(m_radius, m_rings, m_slices);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const SphereVertexDataFunctor *otherFunctor = functor_cast<SphereVertexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices &&
+ otherFunctor->m_radius == m_radius);
+ return false;
+ }
+
+ QT3D_FUNCTOR(SphereVertexDataFunctor)
+
+private:
+ int m_rings;
+ int m_slices;
+ float m_radius;
+};
+
+class SphereIndexDataFunctor : public QBufferDataGenerator
+{
+public:
+ SphereIndexDataFunctor(int rings, int slices)
+ : m_rings(rings)
+ , m_slices(slices)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ return createSphereMeshIndexData(m_rings, m_slices);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const SphereIndexDataFunctor *otherFunctor = functor_cast<SphereIndexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_slices == m_slices);
+ return false;
+ }
+
+ QT3D_FUNCTOR(SphereIndexDataFunctor)
+
+private:
+ int m_rings;
+ int m_slices;
+};
+
+QSphereGeometryPrivate::QSphereGeometryPrivate()
+ : QGeometryPrivate()
+ , m_generateTangents(false)
+ , m_rings(16)
+ , m_slices(16)
+ , m_radius(1.0f)
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_tangentAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QSphereGeometryPrivate::init()
+{
+ Q_Q(QSphereGeometry);
+ m_positionAttribute = new QAttribute(q);
+ m_normalAttribute = new QAttribute(q);
+ m_texCoordAttribute = new QAttribute(q);
+ m_tangentAttribute = new QAttribute(q);
+ m_indexAttribute = new QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+
+ // vec3 pos, vec2 tex, vec3 normal, vec4 tangent
+ const quint32 elementSize = 3 + 2 + 3 + 4;
+ const quint32 stride = elementSize * sizeof(float);
+ const int nVerts = (m_slices + 1) * (m_rings + 1);
+ const int faces = (m_slices * 2) * (m_rings - 2) + (2 * m_slices);
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_tangentAttribute->setName(QAttribute::defaultTangentAttributeName());
+ m_tangentAttribute->setDataType(QAttribute::Float);
+ m_tangentAttribute->setDataSize(4);
+ m_tangentAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_tangentAttribute->setBuffer(m_vertexBuffer);
+ m_tangentAttribute->setByteStride(stride);
+ m_tangentAttribute->setByteOffset(8 * sizeof(float));
+ m_tangentAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ m_indexAttribute->setCount(faces * 3);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new SphereVertexDataFunctor(m_rings, m_slices, m_radius)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new SphereIndexDataFunctor(m_rings, m_slices)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ if (m_generateTangents)
+ q->addAttribute(m_tangentAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+/*!
+ * \qmltype SphereGeometry
+ * \instantiates QSphereGeometry
+ * \inqmlmodule Qt3D.Render
+ */
+
+/*!
+ * \qmlproperty int SphereGeometry::rings
+ *
+ * Holds the number of rings in the sphere.
+ */
+
+/*!
+ * \qmlproperty int SphereGeometry::slices
+ *
+ * Holds the number of slices in the sphere.
+ */
+
+/*!
+ * \qmlproperty float SphereGeometry::radius
+ *
+ * Holds the radius of the sphere.
+ */
+
+/*!
+ * \qmlproperty bool SphereGeometry::generateTangents
+ *
+ * Holds the value of the automatic tangent generation flag.
+ */
+
+/*!
+ * \qmlproperty Attribute SphereGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute SphereGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute SphereGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute SphereGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute SphereGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+
+/*!
+ * \class QSphereGeometry
+ * \inmodule Qt3DRender
+ *
+ * \inherits QGeometry
+ */
+
+/*!
+ * Constructs a new QSphereGeometry with \a parent.
+ */
+QSphereGeometry::QSphereGeometry(QNode *parent)
+ : QGeometry(*new QSphereGeometryPrivate(), parent)
+{
+ Q_D(QSphereGeometry);
+ d->init();
+}
+
+/*!
+ * \internal
+ */
+QSphereGeometry::QSphereGeometry(QSphereGeometryPrivate &dd, QNode *parent)
+ : QGeometry(dd, parent)
+{
+ Q_D(QSphereGeometry);
+ d->init();
+}
+
+/*!
+ * Destroys this geometry.
+ */
+QSphereGeometry::~QSphereGeometry()
+{
+ QGeometry::cleanup();
+}
+
+/*!
+ * Updates vertices based on rings and slices.
+ */
+void QSphereGeometry::updateVertices()
+{
+ Q_D(QSphereGeometry);
+ const int nVerts = (d->m_slices + 1) * (d->m_rings + 1);
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+ d->m_tangentAttribute->setCount(nVerts);
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new SphereVertexDataFunctor(d->m_rings, d->m_slices, d->m_radius)));
+}
+
+/*!
+ * Updates indices based on rings and slices.
+ */
+void QSphereGeometry::updateIndices()
+{
+ Q_D(QSphereGeometry);
+ const int faces = (d->m_slices * 2) * (d->m_rings - 2) + (2 * d->m_slices);
+ d->m_indexAttribute->setCount(faces * 3);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new SphereIndexDataFunctor(d->m_rings, d->m_slices)));
+
+}
+
+void QSphereGeometry::setRings(int rings)
+{
+ Q_D(QSphereGeometry);
+ if (rings != d->m_rings) {
+ d->m_rings = rings;
+ updateVertices();
+ updateIndices();
+ emit ringsChanged(rings);
+ }
+}
+
+void QSphereGeometry::setSlices(int slices)
+{
+ Q_D(QSphereGeometry);
+ if (slices != d->m_slices) {
+ d->m_slices = slices;
+ updateVertices();
+ updateIndices();
+ emit slicesChanged(slices);
+ }
+}
+
+void QSphereGeometry::setRadius(float radius)
+{
+ Q_D(QSphereGeometry);
+ if (radius != d->m_radius) {
+ d->m_radius = radius;
+ updateVertices();
+ emit radiusChanged(radius);
+ }
+}
+
+void QSphereGeometry::setGenerateTangents(bool gen)
+{
+ Q_D(QSphereGeometry);
+ if (d->m_generateTangents != gen) {
+ if (d->m_generateTangents)
+ removeAttribute(d->m_tangentAttribute);
+ d->m_generateTangents = gen;
+ if (d->m_generateTangents)
+ addAttribute(d->m_tangentAttribute);
+ emit generateTangentsChanged(gen);
+ }
+}
+
+/*!
+ * \property QSphereGeometry::generateTangents
+ *
+ * Holds the value of the automatic tangent generation flag.
+ */
+bool QSphereGeometry::generateTangents() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_generateTangents;
+}
+
+/*!
+ * \property QSphereGeometry::rings
+ *
+ * Holds the number of rings in the sphere.
+ */
+int QSphereGeometry::rings() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_rings;
+}
+
+/*!
+ * \property QSphereGeometry::slices
+ *
+ * Holds the number of slices in the sphere.
+ */
+int QSphereGeometry::slices() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_slices;
+}
+
+/*!
+ * \property QSphereGeometry::radius
+ *
+ * Holds the radius of the sphere.
+ */
+float QSphereGeometry::radius() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_radius;
+}
+
+/*!
+ * \property QSphereGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+QAttribute *QSphereGeometry::positionAttribute() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_positionAttribute;
+}
+
+/*!
+ * \property QSphereGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+QAttribute *QSphereGeometry::normalAttribute() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_normalAttribute;
+}
+
+/*!
+ * \property QSphereGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+QAttribute *QSphereGeometry::texCoordAttribute() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_texCoordAttribute;
+}
+
+/*!
+ * \property QSphereGeometry::tangentAttribute
+ *
+ * Holds the geometry tangent attribute.
+ */
+QAttribute *QSphereGeometry::tangentAttribute() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_tangentAttribute;
+}
+
+/*!
+ * \property QSphereGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+QAttribute *QSphereGeometry::indexAttribute() const
+{
+ Q_D(const QSphereGeometry);
+ return d->m_indexAttribute;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
diff --git a/src/extras/geometries/qspheregeometry.h b/src/extras/geometries/qspheregeometry.h
new file mode 100644
index 000000000..acc908d35
--- /dev/null
+++ b/src/extras/geometries/qspheregeometry.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QSPHEREGEOMETRY_H
+#define QT3DEXTRAS_QSPHEREGEOMETRY_H
+
+#include <Qt3DRender/qgeometry.h>
+#include <Qt3DExtras/qt3dextras_global.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QSphereGeometryPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QSphereGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(bool generateTangents READ generateTangents WRITE setGenerateTangents NOTIFY generateTangentsChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *tangentAttribute READ tangentAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QSphereGeometry(QNode *parent = Q_NULLPTR);
+ ~QSphereGeometry();
+
+ void updateVertices();
+ void updateIndices();
+
+ bool generateTangents() const;
+ int rings() const;
+ int slices() const;
+ float radius() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *tangentAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setGenerateTangents(bool gen);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void generateTangentsChanged(bool generateTangents);
+
+protected:
+ QSphereGeometry(QSphereGeometryPrivate &dd, QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QSphereGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QSPHEREGEOMETRY_H
diff --git a/src/extras/geometries/qspheregeometry_p.h b/src/extras/geometries/qspheregeometry_p.h
new file mode 100644
index 000000000..dc96766e1
--- /dev/null
+++ b/src/extras/geometries/qspheregeometry_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Paul Lemire paul.lemire350@gmail.com
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QSPHEREGEOMETRY_P_H
+#define QT3DEXTRAS_QSPHEREGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QSphereGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QSphereGeometryPrivate();
+ void init();
+
+ bool m_generateTangents;
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_tangentAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+
+ Q_DECLARE_PUBLIC(QSphereGeometry);
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif //QT3DEXTRAS_QSPHEREGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qspheremesh.cpp b/src/extras/geometries/qspheremesh.cpp
new file mode 100644
index 000000000..d5c4a1317
--- /dev/null
+++ b/src/extras/geometries/qspheremesh.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qspheremesh.h"
+#include "qspheregeometry.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+/*!
+ * \qmltype SphereMesh
+ * \instantiates Qt3DRender::QSphereMesh
+ * \inqmlmodule Qt3D.Render
+ * \brief A spherical mesh.
+ */
+
+/*!
+ * \qmlproperty int SphereMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+
+/*!
+ * \qmlproperty int SphereMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+
+/*!
+ * \qmlproperty float SphereMesh::radius
+ *
+ * Holds the radius of the sphere.
+ */
+
+/*!
+ * \qmlproperty bool SphereMesh::generateTangents
+ *
+ * Holds the value of the automatic tangent generation flag.
+ */
+
+/*!
+ * \class Qt3DRender::QSphereMesh
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometryRenderer
+ *
+ * \brief A spherical mesh.
+ */
+
+/*!
+ * Constructs a new QSphereMesh with \a parent.
+ */
+QSphereMesh::QSphereMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QSphereGeometry *geometry = new QSphereGeometry(this);
+ QObject::connect(geometry, &QSphereGeometry::radiusChanged, this, &QSphereMesh::radiusChanged);
+ QObject::connect(geometry, &QSphereGeometry::ringsChanged, this, &QSphereMesh::ringsChanged);
+ QObject::connect(geometry, &QSphereGeometry::slicesChanged, this, &QSphereMesh::slicesChanged);
+ QObject::connect(geometry, &QSphereGeometry::generateTangentsChanged, this, &QSphereMesh::generateTangentsChanged);
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+/*!
+ * Destroys this sphere mesh.
+ */
+QSphereMesh::~QSphereMesh()
+{
+ QNode::cleanup();
+}
+
+void QSphereMesh::setRings(int rings)
+{
+ static_cast<QSphereGeometry *>(geometry())->setRings(rings);
+}
+
+void QSphereMesh::setSlices(int slices)
+{
+ static_cast<QSphereGeometry *>(geometry())->setSlices(slices);
+}
+
+void QSphereMesh::setRadius(float radius)
+{
+ static_cast<QSphereGeometry *>(geometry())->setRadius(radius);
+}
+
+void QSphereMesh::setGenerateTangents(bool gen)
+{
+ static_cast<QSphereGeometry *>(geometry())->setGenerateTangents(gen);
+}
+
+/*!
+ * \property QSphereMesh::generateTangents
+ *
+ * Holds the value of the automatic tangent generation flag.
+ */
+bool QSphereMesh::generateTangents() const
+{
+ return static_cast<QSphereGeometry *>(geometry())->generateTangents();
+}
+
+/*!
+ * \property QSphereMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+int QSphereMesh::rings() const
+{
+ return static_cast<QSphereGeometry *>(geometry())->rings();
+}
+
+/*!
+ * \property QSphereMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+int QSphereMesh::slices() const
+{
+ return static_cast<QSphereGeometry *>(geometry())->slices();
+}
+
+/*!
+ * \property QSphereMesh::radius
+ *
+ * Holds the radius of the sphere.
+ */
+float QSphereMesh::radius() const
+{
+ return static_cast<QSphereGeometry *>(geometry())->radius();
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qspheremesh.h b/src/extras/geometries/qspheremesh.h
new file mode 100644
index 000000000..7fe346e41
--- /dev/null
+++ b/src/extras/geometries/qspheremesh.h
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QSPHEREMESH_H
+#define QT3DEXTRAS_QSPHEREMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QSphereMeshPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QSphereMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(bool generateTangents READ generateTangents WRITE setGenerateTangents NOTIFY generateTangentsChanged)
+
+public:
+ explicit QSphereMesh(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QSphereMesh();
+
+ int rings() const;
+ int slices() const;
+ float radius() const;
+ bool generateTangents() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setGenerateTangents(bool gen);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void generateTangentsChanged(bool generateTangents);
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QSPHEREMESH_H
diff --git a/src/extras/geometries/qtorusgeometry.cpp b/src/extras/geometries/qtorusgeometry.cpp
new file mode 100644
index 000000000..fe9ac7821
--- /dev/null
+++ b/src/extras/geometries/qtorusgeometry.cpp
@@ -0,0 +1,511 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtorusgeometry.h"
+#include "qtorusgeometry_p.h"
+#include <Qt3DRender/qbuffer.h>
+#include <Qt3DRender/qbufferdatagenerator.h>
+#include <Qt3DRender/qattribute.h>
+#include <qmath.h>
+#include <QVector3D>
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt3DRender;
+
+namespace Qt3DExtras {
+
+namespace {
+
+QByteArray createTorusVertexData(double radius, double minorRadius,
+ int rings, int sides)
+{
+ const int nVerts = sides * (rings + 1);
+ QByteArray bufferBytes;
+ // vec3 pos, vec2 texCoord, vec3 normal
+ const quint32 elementSize = 3 + 2 + 3;
+ const quint32 stride = elementSize * sizeof(float);
+ bufferBytes.resize(stride * nVerts);
+
+ float* fptr = reinterpret_cast<float*>(bufferBytes.data());
+
+ const float ringFactor = (M_PI * 2) / static_cast<float>( rings );
+ const float sideFactor = (M_PI * 2) / static_cast<float>( sides );
+
+ for (int ring = 0; ring <= rings; ++ring) {
+ const float u = ring * ringFactor;
+ const float cu = qCos( u );
+ const float su = qSin( u );
+
+ for (int side = 0; side < sides; ++side) {
+ const float v = side * sideFactor;
+ const float cv = qCos( v );
+ const float sv = qSin( v );
+ const float r = (radius + minorRadius * cv);
+
+ *fptr++ = r * cu;
+ *fptr++ = r * su;
+ *fptr++ = minorRadius * sv;
+
+ *fptr++ = u / (M_PI * 2);
+ *fptr++ = v / (M_PI * 2);
+
+ QVector3D n(cv * cu * r, cv * su * r, sv * r);
+ n.normalize();
+ *fptr++ = n.x();
+ *fptr++ = n.y();
+ *fptr++ = n.z();
+ }
+ }
+
+ return bufferBytes;
+}
+
+QByteArray createTorusIndexData(int rings, int sides)
+{
+ QByteArray indexBytes;
+ int faces = (sides * 2) * rings; // two tris per side, for all rings
+ int indices = faces * 3;
+ Q_ASSERT(indices < 65536);
+ indexBytes.resize(indices * sizeof(quint16));
+ quint16* indexPtr = reinterpret_cast<quint16*>(indexBytes.data());
+
+ for (int ring = 0; ring < rings; ++ring) {
+ const int ringStart = ring * sides;
+ const int nextRingStart = (ring + 1) * sides;
+ for (int side = 0; side < sides; ++side) {
+ const int nextSide = (side + 1) % sides;
+ *indexPtr++ = (ringStart + side);
+ *indexPtr++ = (nextRingStart + side);
+ *indexPtr++ = (nextRingStart + nextSide);
+ *indexPtr++ = ringStart + side;
+ *indexPtr++ = nextRingStart + nextSide;
+ *indexPtr++ = (ringStart + nextSide);
+ }
+ }
+
+ return indexBytes;
+}
+
+} // anonymous
+
+class TorusVertexDataFunctor : public QBufferDataGenerator
+{
+public:
+ TorusVertexDataFunctor(int rings, int slices, float radius, float minorRadius)
+ : m_rings(rings)
+ , m_sides(slices)
+ , m_radius(radius)
+ , m_minorRadius(minorRadius)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ return createTorusVertexData(m_radius, m_minorRadius, m_rings, m_sides);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const TorusVertexDataFunctor *otherFunctor = functor_cast<TorusVertexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_sides == m_sides &&
+ otherFunctor->m_radius == m_radius &&
+ otherFunctor->m_minorRadius == m_minorRadius);
+ return false;
+ }
+
+ QT3D_FUNCTOR(TorusVertexDataFunctor)
+
+private:
+ int m_rings;
+ int m_sides;
+ float m_radius;
+ float m_minorRadius;
+};
+
+class TorusIndexDataFunctor : public QBufferDataGenerator
+{
+public:
+ TorusIndexDataFunctor(int rings, int slices)
+ : m_rings(rings)
+ , m_sides(slices)
+ {
+ }
+
+ QByteArray operator ()() Q_DECL_OVERRIDE
+ {
+ return createTorusIndexData(m_rings, m_sides);
+ }
+
+ bool operator ==(const QBufferDataGenerator &other) const Q_DECL_OVERRIDE
+ {
+ const TorusIndexDataFunctor *otherFunctor = functor_cast<TorusIndexDataFunctor>(&other);
+ if (otherFunctor != Q_NULLPTR)
+ return (otherFunctor->m_rings == m_rings &&
+ otherFunctor->m_sides == m_sides);
+ return false;
+ }
+
+ QT3D_FUNCTOR(TorusIndexDataFunctor)
+
+private:
+ int m_rings;
+ int m_sides;
+};
+
+QTorusGeometryPrivate::QTorusGeometryPrivate()
+ : QGeometryPrivate()
+ , m_rings(16)
+ , m_slices(16)
+ , m_radius(1.0f)
+ , m_minorRadius(1.0f)
+ , m_positionAttribute(Q_NULLPTR)
+ , m_normalAttribute(Q_NULLPTR)
+ , m_texCoordAttribute(Q_NULLPTR)
+ , m_indexAttribute(Q_NULLPTR)
+ , m_vertexBuffer(Q_NULLPTR)
+ , m_indexBuffer(Q_NULLPTR)
+{
+}
+
+void QTorusGeometryPrivate::init()
+{
+ Q_Q(QTorusGeometry);
+ m_positionAttribute = new QAttribute(q);
+ m_normalAttribute = new QAttribute(q);
+ m_texCoordAttribute = new QAttribute(q);
+ m_indexAttribute = new QAttribute(q);
+ m_vertexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, q);
+ m_indexBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, q);
+ // vec3 pos, vec2 tex, vec3 normal
+ const quint32 elementSize = 3 + 2 + 3;
+ const quint32 stride = elementSize * sizeof(float);
+ const int nVerts = (m_slices + 1) * (m_rings + 1);
+ const int faces = (m_slices * 2) * m_rings;
+
+ m_positionAttribute->setName(QAttribute::defaultPositionAttributeName());
+ m_positionAttribute->setDataType(QAttribute::Float);
+ m_positionAttribute->setDataSize(3);
+ m_positionAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_positionAttribute->setBuffer(m_vertexBuffer);
+ m_positionAttribute->setByteStride(stride);
+ m_positionAttribute->setCount(nVerts);
+
+ m_texCoordAttribute->setName(QAttribute::defaultTextureCoordinateAttributeName());
+ m_texCoordAttribute->setDataType(QAttribute::Float);
+ m_texCoordAttribute->setDataSize(2);
+ m_texCoordAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_texCoordAttribute->setBuffer(m_vertexBuffer);
+ m_texCoordAttribute->setByteStride(stride);
+ m_texCoordAttribute->setByteOffset(3 * sizeof(float));
+ m_texCoordAttribute->setCount(nVerts);
+
+ m_normalAttribute->setName(QAttribute::defaultNormalAttributeName());
+ m_normalAttribute->setDataType(QAttribute::Float);
+ m_normalAttribute->setDataSize(3);
+ m_normalAttribute->setAttributeType(QAttribute::VertexAttribute);
+ m_normalAttribute->setBuffer(m_vertexBuffer);
+ m_normalAttribute->setByteStride(stride);
+ m_normalAttribute->setByteOffset(5 * sizeof(float));
+ m_normalAttribute->setCount(nVerts);
+
+ m_indexAttribute->setAttributeType(QAttribute::IndexAttribute);
+ m_indexAttribute->setDataType(QAttribute::UnsignedShort);
+ m_indexAttribute->setBuffer(m_indexBuffer);
+
+ m_indexAttribute->setCount(faces * 3);
+
+ m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new TorusVertexDataFunctor(m_rings, m_slices, m_radius, m_minorRadius)));
+ m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new TorusIndexDataFunctor(m_rings, m_slices)));
+
+ q->addAttribute(m_positionAttribute);
+ q->addAttribute(m_texCoordAttribute);
+ q->addAttribute(m_normalAttribute);
+ q->addAttribute(m_indexAttribute);
+}
+
+/*!
+ * \qmltype TorusGeometry
+ * \instantiates Qt3DRender::QTorusGeometry
+ * \inqmlmodule Qt3D.Render
+ */
+
+/*!
+ * \qmlproperty int TorusGeometry::rings
+ *
+ * Holds the number of rings in the torus.
+ */
+
+/*!
+ * \qmlproperty int TorusGeometry::slices
+ *
+ * Holds the number of slices in the torus.
+ */
+
+/*!
+ * \qmlproperty float TorusGeometry::radius
+ *
+ * Holds the outer radius of the torus.
+ */
+
+/*!
+ * \qmlproperty float TorusGeometry::minorRadius
+ *
+ * Holds the inner radius of the torus.
+ */
+
+/*!
+ * \qmlproperty Attribute TorusGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute TorusGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute TorusGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+
+/*!
+ * \qmlproperty Attribute TorusGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+
+/*!
+ * \class Qt3DRender::QTorusGeometry
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometry
+ */
+
+/*!
+ * Constructs a new QTorusGeometry with \a parent.
+ */
+QTorusGeometry::QTorusGeometry(QNode *parent)
+ : QGeometry(*new QTorusGeometryPrivate(), parent)
+{
+ Q_D(QTorusGeometry);
+ d->init();
+}
+
+/*!
+ * \internal
+ */
+QTorusGeometry::QTorusGeometry(QTorusGeometryPrivate &dd, QNode *parent)
+ : QGeometry(dd, parent)
+{
+ Q_D(QTorusGeometry);
+ d->init();
+}
+
+/*!
+ * Destroys this geometry.
+ */
+QTorusGeometry::~QTorusGeometry()
+{
+ QGeometry::cleanup();
+}
+
+/*!
+ * Updates vertices based on rings and slices.
+ */
+void QTorusGeometry::updateVertices()
+{
+ Q_D(QTorusGeometry);
+ const int nVerts = d->m_slices * (d->m_rings + 1);
+ d->m_positionAttribute->setCount(nVerts);
+ d->m_texCoordAttribute->setCount(nVerts);
+ d->m_normalAttribute->setCount(nVerts);
+ d->m_vertexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new TorusVertexDataFunctor(d->m_rings, d->m_slices, d->m_radius, d->m_minorRadius)));
+}
+
+/*!
+ * Updates indices based on rings and slices.
+ */
+void QTorusGeometry::updateIndices()
+{
+ Q_D(QTorusGeometry);
+ const int faces = (d->m_slices * 2) * d->m_rings;
+ d->m_indexAttribute->setCount(faces * 3);
+ d->m_indexBuffer->setDataGenerator(QBufferDataGeneratorPtr(new TorusIndexDataFunctor(d->m_rings, d->m_slices)));
+
+}
+
+void QTorusGeometry::setRings(int rings)
+{
+ Q_D(QTorusGeometry);
+ if (rings != d->m_rings) {
+ d->m_rings = rings;
+ updateVertices();
+ updateIndices();
+ emit ringsChanged(rings);
+ }
+}
+
+void QTorusGeometry::setSlices(int slices)
+{
+ Q_D(QTorusGeometry);
+ if (slices != d->m_slices) {
+ d->m_slices = slices;
+ updateVertices();
+ updateIndices();
+ emit slicesChanged(slices);
+ }
+}
+
+void QTorusGeometry::setRadius(float radius)
+{
+ Q_D(QTorusGeometry);
+ if (radius != d->m_radius) {
+ d->m_radius = radius;
+ updateVertices();
+ emit radiusChanged(radius);
+ }
+}
+
+void QTorusGeometry::setMinorRadius(float minorRadius)
+{
+ Q_D(QTorusGeometry);
+ if (minorRadius != d->m_minorRadius) {
+ d->m_minorRadius = minorRadius;
+ updateVertices();
+ emit minorRadiusChanged(minorRadius);
+ }
+}
+
+/*!
+ * \property QTorusGeometry::rings
+ *
+ * Holds the number of rings in the torus.
+ */
+int QTorusGeometry::rings() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_rings;
+}
+
+/*!
+ * \property QTorusGeometry::slices
+ *
+ * Holds the number of slices in the torus.
+ */
+int QTorusGeometry::slices() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_slices;
+}
+
+/*!
+ * \property QTorusGeometry::radius
+ *
+ * Holds the outer radius of the torus.
+ */
+float QTorusGeometry::radius() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_radius;
+}
+
+/*!
+ * \property QTorusGeometry::minorRadius
+ *
+ * Holds the inner radius of the torus.
+ */
+float QTorusGeometry::minorRadius() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_minorRadius;
+}
+
+/*!
+ * \property QTorusGeometry::positionAttribute
+ *
+ * Holds the geometry position attribute.
+ */
+QAttribute *QTorusGeometry::positionAttribute() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_positionAttribute;
+}
+
+/*!
+ * \property QTorusGeometry::normalAttribute
+ *
+ * Holds the geometry normal attribute.
+ */
+QAttribute *QTorusGeometry::normalAttribute() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_normalAttribute;
+}
+
+/*!
+ * \property QTorusGeometry::texCoordAttribute
+ *
+ * Holds the geometry texture coordinate attribute.
+ */
+QAttribute *QTorusGeometry::texCoordAttribute() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_texCoordAttribute;
+}
+
+/*!
+ * \property QTorusGeometry::indexAttribute
+ *
+ * Holds the geometry index attribute.
+ */
+QAttribute *QTorusGeometry::indexAttribute() const
+{
+ Q_D(const QTorusGeometry);
+ return d->m_indexAttribute;
+}
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qtorusgeometry.h b/src/extras/geometries/qtorusgeometry.h
new file mode 100644
index 000000000..99b76acd3
--- /dev/null
+++ b/src/extras/geometries/qtorusgeometry.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QTORUSGEOMETRY_H
+#define QT3DEXTRAS_QTORUSGEOMETRY_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometry.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QTorusGeometryPrivate;
+
+class QT3DEXTRASSHARED_EXPORT QTorusGeometry : public Qt3DRender::QGeometry
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(float minorRadius READ minorRadius WRITE setMinorRadius NOTIFY minorRadiusChanged)
+ Q_PROPERTY(Qt3DRender::QAttribute *positionAttribute READ positionAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *normalAttribute READ normalAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *texCoordAttribute READ texCoordAttribute CONSTANT)
+ Q_PROPERTY(Qt3DRender::QAttribute *indexAttribute READ indexAttribute CONSTANT)
+
+public:
+ explicit QTorusGeometry(QNode *parent = Q_NULLPTR);
+ ~QTorusGeometry();
+
+ void updateVertices();
+ void updateIndices();
+
+ int rings() const;
+ int slices() const;
+ float radius() const;
+ float minorRadius() const;
+
+ Qt3DRender::QAttribute *positionAttribute() const;
+ Qt3DRender::QAttribute *normalAttribute() const;
+ Qt3DRender::QAttribute *texCoordAttribute() const;
+ Qt3DRender::QAttribute *indexAttribute() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setMinorRadius(float minorRadius);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void minorRadiusChanged(float minorRadius);
+
+
+protected:
+ QTorusGeometry(QTorusGeometryPrivate &dd, QNode *parent = Q_NULLPTR);
+
+private:
+ Q_DECLARE_PRIVATE(QTorusGeometry)
+};
+
+} // Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QTORUSGEOMETRY_H
diff --git a/src/extras/geometries/qtorusgeometry_p.h b/src/extras/geometries/qtorusgeometry_p.h
new file mode 100644
index 000000000..b4bcbde9f
--- /dev/null
+++ b/src/extras/geometries/qtorusgeometry_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QTORUSGEOMETRY_P_H
+#define QT3DEXTRAS_QTORUSGEOMETRY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <Qt3DRender/private/qgeometry_p.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DRender {
+
+class QAttribute;
+class QBuffer;
+
+} // Qt3DRender
+
+namespace Qt3DExtras {
+
+class QTorusGeometryPrivate : public Qt3DRender::QGeometryPrivate
+{
+public:
+ QTorusGeometryPrivate();
+ void init();
+
+ int m_rings;
+ int m_slices;
+ float m_radius;
+ float m_minorRadius;
+ Qt3DRender::QAttribute *m_positionAttribute;
+ Qt3DRender::QAttribute *m_normalAttribute;
+ Qt3DRender::QAttribute *m_texCoordAttribute;
+ Qt3DRender::QAttribute *m_indexAttribute;
+ Qt3DRender::QBuffer *m_vertexBuffer;
+ Qt3DRender::QBuffer *m_indexBuffer;
+
+ Q_DECLARE_PUBLIC(QTorusGeometry)
+};
+
+} // Qt3DExtras
+
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QTORUSGEOMETRY_P_H
+
diff --git a/src/extras/geometries/qtorusmesh.cpp b/src/extras/geometries/qtorusmesh.cpp
new file mode 100644
index 000000000..0f2143835
--- /dev/null
+++ b/src/extras/geometries/qtorusmesh.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Copyright (C) 2016 The Qt Company Ltd and/or its subsidiary(-ies).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // For MSVC
+#endif
+
+#include "qtorusmesh.h"
+#include "qtorusgeometry.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+/*!
+ * \qmltype TorusMesh
+ * \instantiates Qt3DRender::QTorusMesh
+ * \inqmlmodule Qt3D.Render
+ * \brief A custom mesh.
+ */
+
+/*!
+ * \qmlproperty int TorusMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+
+/*!
+ * \qmlproperty int TorusMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+
+/*!
+ * \qmlproperty float TorusMesh::radius
+ *
+ * Holds the outer radius of the torus.
+ */
+
+/*!
+ * \qmlproperty float TorusMesh::minorRadius
+ *
+ * Holds the inner radius of the torus.
+ */
+
+/*!
+ * \class Qt3DRender::QTorusMesh
+ * \inmodule Qt3DRender
+ *
+ * \inherits Qt3DRender::QGeometryRenderer
+ *
+ * \brief A custom mesh.
+ */
+
+/*!
+ * Constructs a new QTorusMesh with \a parent.
+ */
+QTorusMesh::QTorusMesh(QNode *parent)
+ : QGeometryRenderer(parent)
+{
+ QTorusGeometry *geometry = new QTorusGeometry(this);
+ QObject::connect(geometry, &QTorusGeometry::radiusChanged, this, &QTorusMesh::radiusChanged);
+ QObject::connect(geometry, &QTorusGeometry::ringsChanged, this, &QTorusMesh::ringsChanged);
+ QObject::connect(geometry, &QTorusGeometry::slicesChanged, this, &QTorusMesh::slicesChanged);
+ QObject::connect(geometry, &QTorusGeometry::minorRadiusChanged, this, &QTorusMesh::minorRadiusChanged);
+
+ QGeometryRenderer::setGeometry(geometry);
+}
+
+/*!
+ * Destroys this torus mesh.
+ */
+QTorusMesh::~QTorusMesh()
+{
+ QGeometryRenderer::cleanup();
+}
+
+void QTorusMesh::setRings(int rings)
+{
+ static_cast<QTorusGeometry *>(geometry())->setRings(rings);
+}
+
+void QTorusMesh::setSlices(int slices)
+{
+ static_cast<QTorusGeometry *>(geometry())->setSlices(slices);
+}
+
+void QTorusMesh::setRadius(float radius)
+{
+ static_cast<QTorusGeometry *>(geometry())->setRadius(radius);
+}
+
+void QTorusMesh::setMinorRadius(float minorRadius)
+{
+ static_cast<QTorusGeometry *>(geometry())->setMinorRadius(minorRadius);
+}
+
+/*!
+ * \property QTorusMesh::rings
+ *
+ * Holds the number of rings in the mesh.
+ */
+int QTorusMesh::rings() const
+{
+ return static_cast<QTorusGeometry *>(geometry())->rings();
+}
+
+/*!
+ * \property QTorusMesh::slices
+ *
+ * Holds the number of slices in the mesh.
+ */
+int QTorusMesh::slices() const
+{
+ return static_cast<QTorusGeometry *>(geometry())->slices();
+}
+
+/*!
+ * \property QTorusMesh::radius
+ *
+ * Holds the outer radius of the torus.
+ */
+float QTorusMesh::radius() const
+{
+ return static_cast<QTorusGeometry *>(geometry())->radius();
+}
+
+/*!
+ * \property QTorusMesh::minorRadius
+ *
+ * Holds the inner radius of the torus.
+ */
+float QTorusMesh::minorRadius() const
+{
+ return static_cast<QTorusGeometry *>(geometry())->minorRadius();
+}
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
diff --git a/src/extras/geometries/qtorusmesh.h b/src/extras/geometries/qtorusmesh.h
new file mode 100644
index 000000000..16d1be736
--- /dev/null
+++ b/src/extras/geometries/qtorusmesh.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_QTORUSMESH_H
+#define QT3DEXTRAS_QTORUSMESH_H
+
+#include <Qt3DExtras/qt3dextras_global.h>
+#include <Qt3DRender/qgeometryrenderer.h>
+
+QT_BEGIN_NAMESPACE
+
+namespace Qt3DExtras {
+
+class QT3DEXTRASSHARED_EXPORT QTorusMesh : public Qt3DRender::QGeometryRenderer
+{
+ Q_OBJECT
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY ringsChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY slicesChanged)
+ Q_PROPERTY(float radius READ radius WRITE setRadius NOTIFY radiusChanged)
+ Q_PROPERTY(float minorRadius READ minorRadius WRITE setMinorRadius NOTIFY minorRadiusChanged)
+public:
+ explicit QTorusMesh(Qt3DCore::QNode *parent = Q_NULLPTR);
+ ~QTorusMesh();
+
+ int rings() const;
+ int slices() const;
+ float radius() const;
+ float minorRadius() const;
+
+public Q_SLOTS:
+ void setRings(int rings);
+ void setSlices(int slices);
+ void setRadius(float radius);
+ void setMinorRadius(float minorRadius);
+
+Q_SIGNALS:
+ void radiusChanged(float radius);
+ void ringsChanged(int rings);
+ void slicesChanged(int slices);
+ void minorRadiusChanged(float minorRadius);
+
+private:
+ // As this is a default provided geometry renderer, no one should be able
+ // to modify the QGeometryRenderer's properties
+
+ void setInstanceCount(int instanceCount);
+ void setVertexCount(int vertexCount);
+ void setIndexOffset(int indexOffset);
+ void setFirstInstance(int firstInstance);
+ void setRestartIndexValue(int index);
+ void setPrimitiveRestartEnabled(bool enabled);
+ void setGeometry(Qt3DRender::QGeometry *geometry);
+ void setPrimitiveType(PrimitiveType primitiveType);
+};
+
+} // namespace Qt3DExtras
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_QTORUSMESH_H
diff --git a/src/extras/qt3dextras_global.h b/src/extras/qt3dextras_global.h
new file mode 100644
index 000000000..bd4160ab8
--- /dev/null
+++ b/src/extras/qt3dextras_global.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DEXTRAS_GLOBAL_H
+#define QT3DEXTRAS_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+#if defined(QT_SHARED) || !defined(QT_STATIC)
+# if defined(QT3DEXTRAS_LIBRARY)
+# define QT3DEXTRASSHARED_EXPORT Q_DECL_EXPORT
+# else
+# define QT3DEXTRASSHARED_EXPORT Q_DECL_IMPORT
+# endif
+#else
+# define QT3DEXTRASSHARED_EXPORT
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QT3DEXTRAS_GLOBAL_H
diff --git a/src/extras/shaders/es2/diffusemap.frag b/src/extras/shaders/es2/diffusemap.frag
new file mode 100644
index 000000000..7d06d8e2c
--- /dev/null
+++ b/src/extras/shaders/es2/diffusemap.frag
@@ -0,0 +1,25 @@
+#define FP highp
+
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+uniform sampler2D diffuseTexture;
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec2 texCoord;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
+
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+
+ gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/diffusemap.vert b/src/extras/shaders/es2/diffusemap.vert
new file mode 100644
index 000000000..13798279e
--- /dev/null
+++ b/src/extras/shaders/es2/diffusemap.vert
@@ -0,0 +1,22 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec2 vertexTexCoord;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+varying vec2 texCoord;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+uniform float texCoordScale;
+
+void main()
+{
+ texCoord = vertexTexCoord * texCoordScale;
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/es2/diffusespecularmap.frag b/src/extras/shaders/es2/diffusespecularmap.frag
new file mode 100644
index 000000000..4d776772c
--- /dev/null
+++ b/src/extras/shaders/es2/diffusespecularmap.frag
@@ -0,0 +1,27 @@
+#define FP highp
+
+// TODO: Replace with a struct
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D specularTexture;
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec2 texCoord;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ FP vec3 diffuseTextureColor = texture2D( diffuseTexture, texCoord ).rgb;
+ FP vec3 specularTextureColor = texture2D( specularTexture, texCoord ).rgb;
+
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+
+ gl_FragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/gooch.frag b/src/extras/shaders/es2/gooch.frag
new file mode 100644
index 000000000..622aaf0b4
--- /dev/null
+++ b/src/extras/shaders/es2/gooch.frag
@@ -0,0 +1,56 @@
+#define FP highp
+
+// TODO: Replace with a struct
+uniform FP vec3 kd; // Diffuse reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP vec3 kblue; // Cool color
+uniform FP vec3 kyellow; // Warm color
+uniform FP float alpha; // Fraction of diffuse added to kblue
+uniform FP float beta; // Fraction of diffuse added to kyellow
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+
+#pragma include light.inc.frag
+
+FP vec3 goochModel( const in FP vec3 pos, const in FP vec3 n )
+{
+ // Based upon the original Gooch lighting model paper at:
+ // http://www.cs.northwestern.edu/~ago820/SIG98/abstract.html
+
+ // Calculate kcool and kwarm from equation (3)
+ FP vec3 kcool = clamp(kblue + alpha * kd, 0.0, 1.0);
+ FP vec3 kwarm = clamp(kyellow + beta * kd, 0.0, 1.0);
+
+ // Calculate the vector from the light to the fragment
+ FP vec3 s = normalize( vec3( lights[0].position ) - pos );
+
+ // Calculate the cos theta factor mapped onto the range [0,1]
+ FP float sDotNFactor = ( 1.0 + dot( s, n ) ) / 2.0;
+
+ // Calculate the tone by blending the kcool and kwarm contributions
+ // as per equation (2)
+ FP vec3 intensity = mix( kcool, kwarm, sDotNFactor );
+
+ // Calculate the vector from the fragment to the eye position
+ FP vec3 v = normalize( eyePosition - pos );
+
+ // Reflect the light beam using the normal at this fragment
+ FP vec3 r = reflect( -s, n );
+
+ // Calculate the specular component
+ FP float specular = 0.0;
+ if ( dot( s, n ) > 0.0 )
+ specular = pow( max( dot( r, v ), 0.0 ), shininess );
+
+ // Sum the blended tone and specular highlight
+ return intensity + ks * specular;
+}
+
+void main()
+{
+ gl_FragColor = vec4( goochModel( worldPosition, normalize( worldNormal ) ), 1.0 );
+}
diff --git a/src/extras/shaders/es2/gooch.vert b/src/extras/shaders/es2/gooch.vert
new file mode 100644
index 000000000..dd162a66b
--- /dev/null
+++ b/src/extras/shaders/es2/gooch.vert
@@ -0,0 +1,17 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/es2/light.inc.frag b/src/extras/shaders/es2/light.inc.frag
new file mode 100644
index 000000000..cdec536cf
--- /dev/null
+++ b/src/extras/shaders/es2/light.inc.frag
@@ -0,0 +1,131 @@
+const int MAX_LIGHTS = 8;
+const int TYPE_POINT = 0;
+const int TYPE_DIRECTIONAL = 1;
+const int TYPE_SPOT = 2;
+struct Light {
+ int type;
+ FP vec3 position;
+ FP vec3 color;
+ FP float intensity;
+ FP vec3 direction;
+ FP vec3 attenuation;
+ FP float cutOffAngle;
+};
+uniform Light lights[MAX_LIGHTS];
+uniform int lightCount;
+
+void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ const in FP mat3 tangentMatrix,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = tangentMatrix * ( lights[i].position - vpos );
+ if (length( lights[i].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( tangentMatrix * -lights[i].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = lights[i].position - vpos;
+ if (length( lights[i].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[i].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
+{
+ diffuseColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ int i;
+ FP vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ FP float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = lights[i].position - vpos;
+ if (length( lights[i].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[i].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ }
+}
diff --git a/src/extras/shaders/es2/light.inc.frag100 b/src/extras/shaders/es2/light.inc.frag100
new file mode 100644
index 000000000..b4988ad82
--- /dev/null
+++ b/src/extras/shaders/es2/light.inc.frag100
@@ -0,0 +1,218 @@
+const int MAX_LIGHTS = 2; // RPi: cannot use more than two as we run out of uniforms
+const int TYPE_POINT = 0;
+const int TYPE_DIRECTIONAL = 1;
+const int TYPE_SPOT = 2;
+struct Light {
+ int type;
+ FP vec3 position;
+ FP vec3 color;
+ FP float intensity;
+ FP vec3 direction;
+ FP vec3 attenuation;
+ FP float cutOffAngle;
+};
+uniform Light lights[MAX_LIGHTS];
+uniform int lightCount;
+
+void adsModelNormalMapped(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ const in FP mat3 tangentMatrix,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = tangentMatrix * ( lights[0].position - vpos );
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[0].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( tangentMatrix * -lights[0].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += att * specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = tangentMatrix * ( lights[1].position - vpos );
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[1].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( tangentMatrix * -lights[1].direction );
+ }
+
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += att * specular;
+}
+
+void adsModel(const in FP vec3 vpos, const in FP vec3 vnormal, const in FP vec3 eye, const in FP float shininess,
+ out FP vec3 diffuseColor, out FP vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[0].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[0].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ FP float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+ specularColor += att * specular;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[1].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[1].direction );
+ }
+
+ diffuse = max( dot( s, n ), 0.0 );
+
+ specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ FP vec3 r = reflect( -s, n );
+ FP vec3 v = normalize( eye - vpos );
+ FP float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+ specularColor += att * specular;
+}
+
+void adModel(const in FP vec3 vpos, const in FP vec3 vnormal, out FP vec3 diffuseColor)
+{
+ diffuseColor = vec3(0.0);
+
+ FP vec3 n = normalize( vnormal );
+
+ // 0
+ if (lightCount < 1)
+ return;
+ FP vec3 s;
+ FP float att = 1.0;
+ if ( lights[0].type != TYPE_DIRECTIONAL ) {
+ s = lights[0].position - vpos;
+ if (length( lights[0].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[0].attenuation.x + lights[0].attenuation.y * dist + lights[0].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[0].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[0].direction))) ) > lights[0].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[0].direction );
+ }
+
+ FP float diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[0].intensity * diffuse * lights[0].color;
+
+ // 1
+ if (lightCount < 2)
+ return;
+ att = 1.0;
+ if ( lights[1].type != TYPE_DIRECTIONAL ) {
+ s = lights[1].position - vpos;
+ if (length( lights[1].attenuation ) != 0.0) {
+ FP float dist = length(s);
+ att = 1.0 / (lights[1].attenuation.x + lights[1].attenuation.y * dist + lights[1].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[1].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[1].direction))) ) > lights[1].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[1].direction );
+ }
+
+ diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[1].intensity * diffuse * lights[1].color;
+}
diff --git a/src/extras/shaders/es2/normaldiffusemap.frag b/src/extras/shaders/es2/normaldiffusemap.frag
new file mode 100644
index 000000000..c69aa8b81
--- /dev/null
+++ b/src/extras/shaders/es2/normaldiffusemap.frag
@@ -0,0 +1,31 @@
+#define FP highp
+
+varying FP vec3 worldPosition;
+varying FP vec2 texCoord;
+varying FP mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/normaldiffusemap.vert b/src/extras/shaders/es2/normaldiffusemap.vert
new file mode 100644
index 000000000..ecc689f69
--- /dev/null
+++ b/src/extras/shaders/es2/normaldiffusemap.vert
@@ -0,0 +1,38 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec2 vertexTexCoord;
+attribute vec4 vertexTangent;
+
+varying vec3 worldPosition;
+varying vec2 texCoord;
+varying mat3 tangentMatrix;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 mvp;
+
+uniform float texCoordScale;
+
+void main()
+{
+ // Pass through texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
+
+ // Transform position, normal, and tangent to world coords
+ vec3 normal = normalize( modelNormalMatrix * vertexNormal );
+ vec3 tangent = normalize( modelNormalMatrix * vertexTangent.xyz );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ // Calculate binormal vector
+ vec3 binormal = normalize( cross( normal, tangent ) );
+
+ // Construct matrix to transform from eye coords to tangent space
+ tangentMatrix = mat3 (
+ tangent.x, binormal.x, normal.x,
+ tangent.y, binormal.y, normal.y,
+ tangent.z, binormal.z, normal.z );
+
+ // Calculate vertex position in clip coordinates
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/es2/normaldiffusemapalpha.frag b/src/extras/shaders/es2/normaldiffusemapalpha.frag
new file mode 100644
index 000000000..98acbf01d
--- /dev/null
+++ b/src/extras/shaders/es2/normaldiffusemapalpha.frag
@@ -0,0 +1,32 @@
+#define FP highp
+
+varying FP vec3 worldPosition;
+varying FP vec2 texCoord;
+varying FP mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ // Use the alpha from the diffuse texture (for alpha to coverage)
+ gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
+}
diff --git a/src/extras/shaders/es2/normaldiffusespecularmap.frag b/src/extras/shaders/es2/normaldiffusespecularmap.frag
new file mode 100644
index 000000000..b30c1bd5f
--- /dev/null
+++ b/src/extras/shaders/es2/normaldiffusespecularmap.frag
@@ -0,0 +1,32 @@
+#define FP highp
+
+varying FP vec3 worldPosition;
+varying FP vec2 texCoord;
+varying FP mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D specularTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ FP vec4 diffuseTextureColor = texture2D( diffuseTexture, texCoord );
+ FP vec4 specularTextureColor = texture2D( specularTexture, texCoord );
+ FP vec3 normal = 2.0 * texture2D( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ FP vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ gl_FragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + specularTextureColor.rgb * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/pervertexcolor.frag b/src/extras/shaders/es2/pervertexcolor.frag
new file mode 100644
index 000000000..ab429d942
--- /dev/null
+++ b/src/extras/shaders/es2/pervertexcolor.frag
@@ -0,0 +1,14 @@
+#define FP highp
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+varying FP vec3 color;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ FP vec3 diffuseColor;
+ adModel(worldPosition, worldNormal, diffuseColor);
+ gl_FragColor = vec4( color + color * diffuseColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/pervertexcolor.vert b/src/extras/shaders/es2/pervertexcolor.vert
new file mode 100644
index 000000000..7fc3e649f
--- /dev/null
+++ b/src/extras/shaders/es2/pervertexcolor.vert
@@ -0,0 +1,20 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+attribute vec3 vertexColor;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+varying vec3 color;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+ color = vertexColor;
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/es2/phong.frag b/src/extras/shaders/es2/phong.frag
new file mode 100644
index 000000000..c00f89db0
--- /dev/null
+++ b/src/extras/shaders/es2/phong.frag
@@ -0,0 +1,20 @@
+#define FP highp
+
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec3 kd; // Diffuse reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP float shininess; // Specular shininess factor
+
+uniform FP vec3 eyePosition;
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+ gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/es2/phong.vert b/src/extras/shaders/es2/phong.vert
new file mode 100644
index 000000000..2b4c51b14
--- /dev/null
+++ b/src/extras/shaders/es2/phong.vert
@@ -0,0 +1,17 @@
+attribute vec3 vertexPosition;
+attribute vec3 vertexNormal;
+
+varying vec3 worldPosition;
+varying vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/es2/phongalpha.frag b/src/extras/shaders/es2/phongalpha.frag
new file mode 100644
index 000000000..c5ec43049
--- /dev/null
+++ b/src/extras/shaders/es2/phongalpha.frag
@@ -0,0 +1,22 @@
+#define FP highp
+
+// TODO: Replace with a struct
+uniform FP vec3 ka; // Ambient reflectivity
+uniform FP vec3 kd; // Diffuse reflectivity
+uniform FP vec3 ks; // Specular reflectivity
+uniform FP float shininess; // Specular shininess factor
+uniform FP float alpha;
+
+uniform FP vec3 eyePosition;
+
+varying FP vec3 worldPosition;
+varying FP vec3 worldNormal;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ FP vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+ gl_FragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
+}
diff --git a/src/extras/shaders/es2/skybox.frag b/src/extras/shaders/es2/skybox.frag
new file mode 100644
index 000000000..3de08be44
--- /dev/null
+++ b/src/extras/shaders/es2/skybox.frag
@@ -0,0 +1,8 @@
+varying highp vec3 texCoord0;
+uniform samplerCube skyboxTexture;
+
+void main()
+{
+ gl_FragColor = textureCube(skyboxTexture, texCoord0);
+}
+
diff --git a/src/extras/shaders/es2/skybox.vert b/src/extras/shaders/es2/skybox.vert
new file mode 100644
index 000000000..e2de1d88b
--- /dev/null
+++ b/src/extras/shaders/es2/skybox.vert
@@ -0,0 +1,12 @@
+attribute vec3 vertexPosition;
+varying vec3 texCoord0;
+
+uniform mat4 mvp;
+uniform mat4 inverseProjectionMatrix;
+uniform mat4 inverseModelView;
+
+void main()
+{
+ texCoord0 = vertexPosition.xyz;
+ gl_Position = vec4(mvp * vec4(vertexPosition, 1.0)).xyww;
+}
diff --git a/src/extras/shaders/es2/unlittexture.frag b/src/extras/shaders/es2/unlittexture.frag
new file mode 100644
index 000000000..66752ed32
--- /dev/null
+++ b/src/extras/shaders/es2/unlittexture.frag
@@ -0,0 +1,11 @@
+#define FP highp
+
+uniform sampler2D diffuseTexture;
+
+varying FP vec3 position;
+varying FP vec2 texCoord;
+
+void main()
+{
+ gl_FragColor = texture2D( diffuseTexture, texCoord );
+}
diff --git a/src/extras/shaders/es2/unlittexture.vert b/src/extras/shaders/es2/unlittexture.vert
new file mode 100644
index 000000000..050b2b7e2
--- /dev/null
+++ b/src/extras/shaders/es2/unlittexture.vert
@@ -0,0 +1,17 @@
+attribute vec3 vertexPosition;
+attribute vec2 vertexTexCoord;
+
+varying vec3 position;
+varying vec2 texCoord;
+
+uniform mat4 modelView;
+uniform mat4 mvp;
+uniform vec2 texCoordOffset;
+
+void main()
+{
+ texCoord = vertexTexCoord + texCoordOffset;
+ position = vec3( modelView * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/diffusemap.frag b/src/extras/shaders/gl3/diffusemap.frag
new file mode 100644
index 000000000..7810fdb68
--- /dev/null
+++ b/src/extras/shaders/gl3/diffusemap.frag
@@ -0,0 +1,27 @@
+#version 150 core
+
+uniform vec3 ka; // Ambient reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+uniform sampler2D diffuseTexture;
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+in vec2 texCoord;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
+
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+
+ fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/diffusemap.vert b/src/extras/shaders/gl3/diffusemap.vert
new file mode 100644
index 000000000..439be6e99
--- /dev/null
+++ b/src/extras/shaders/gl3/diffusemap.vert
@@ -0,0 +1,24 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec2 vertexTexCoord;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+out vec2 texCoord;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+uniform float texCoordScale;
+
+void main()
+{
+ texCoord = vertexTexCoord * texCoordScale;
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/diffusespecularmap.frag b/src/extras/shaders/gl3/diffusespecularmap.frag
new file mode 100644
index 000000000..fb809393a
--- /dev/null
+++ b/src/extras/shaders/gl3/diffusespecularmap.frag
@@ -0,0 +1,29 @@
+#version 150 core
+
+// TODO: Replace with a struct
+uniform vec3 ka; // Ambient reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D specularTexture;
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+in vec2 texCoord;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ vec3 diffuseTextureColor = texture( diffuseTexture, texCoord ).rgb;
+ vec3 specularTextureColor = texture( specularTexture, texCoord ).rgb;
+
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+
+ fragColor = vec4( diffuseTextureColor * ( ka + diffuseColor ) + specularTextureColor * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/gooch.frag b/src/extras/shaders/gl3/gooch.frag
new file mode 100644
index 000000000..1beab1c01
--- /dev/null
+++ b/src/extras/shaders/gl3/gooch.frag
@@ -0,0 +1,64 @@
+#version 150 core
+
+// TODO: Replace with a struct
+uniform vec3 kd; // Diffuse reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform vec3 kblue; // Cool color
+uniform vec3 kyellow; // Warm color
+uniform float alpha; // Fraction of diffuse added to kblue
+uniform float beta; // Fraction of diffuse added to kyellow
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+vec3 goochModel( const in vec3 pos, const in vec3 n )
+{
+ // Based upon the original Gooch lighting model paper at:
+ // http://www.cs.northwestern.edu/~ago820/SIG98/abstract.html
+
+ // Calculate kcool and kwarm from equation (3)
+ vec3 kcool = clamp(kblue + alpha * kd, 0.0, 1.0);
+ vec3 kwarm = clamp(kyellow + beta * kd, 0.0, 1.0);
+
+ vec3 result = vec3(0.0);
+ int i;
+ for (i = 0; i < lightCount; ++i) {
+ // Calculate the vector from the light to the fragment
+ vec3 s = normalize( vec3( lights[i].position ) - pos );
+
+ // Calculate the cos theta factor mapped onto the range [0,1]
+ float sDotNFactor = ( 1.0 + dot( s, n ) ) / 2.0;
+
+ // Calculate the tone by blending the kcool and kwarm contributions
+ // as per equation (2)
+ vec3 intensity = mix( kcool, kwarm, sDotNFactor );
+
+ // Calculate the vector from the fragment to the eye position
+ vec3 v = normalize( eyePosition - pos );
+
+ // Reflect the light beam using the normal at this fragment
+ vec3 r = reflect( -s, n );
+
+ // Calculate the specular component
+ float specular = 0.0;
+ if ( dot( s, n ) > 0.0 )
+ specular = pow( max( dot( r, v ), 0.0 ), shininess );
+
+ // Sum the blended tone and specular highlight
+ result += intensity + ks * specular;
+ }
+
+ return result;
+}
+
+void main()
+{
+ fragColor = vec4( goochModel( worldPosition, normalize( worldNormal ) ), 1.0 );
+}
diff --git a/src/extras/shaders/gl3/gooch.vert b/src/extras/shaders/gl3/gooch.vert
new file mode 100644
index 000000000..5230fb70e
--- /dev/null
+++ b/src/extras/shaders/gl3/gooch.vert
@@ -0,0 +1,19 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/light.inc.frag b/src/extras/shaders/gl3/light.inc.frag
new file mode 100644
index 000000000..8cee315c1
--- /dev/null
+++ b/src/extras/shaders/gl3/light.inc.frag
@@ -0,0 +1,131 @@
+const int MAX_LIGHTS = 8;
+const int TYPE_POINT = 0;
+const int TYPE_DIRECTIONAL = 1;
+const int TYPE_SPOT = 2;
+struct Light {
+ int type;
+ vec3 position;
+ vec3 color;
+ float intensity;
+ vec3 direction;
+ vec3 attenuation;
+ float cutOffAngle;
+};
+uniform Light lights[MAX_LIGHTS];
+uniform int lightCount;
+
+void adsModelNormalMapped(const in vec3 vpos, const in vec3 vnormal, const in vec3 eye, const in float shininess,
+ const in mat3 tangentMatrix,
+ out vec3 diffuseColor, out vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ vec3 n = normalize( vnormal );
+
+ int i;
+ vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = tangentMatrix * ( lights[i].position - vpos );
+ if (length( lights[i].attenuation ) != 0.0) {
+ float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( tangentMatrix * -lights[i].direction );
+ }
+
+ float diffuse = max( dot( s, n ), 0.0 );
+
+ float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ vec3 r = reflect( -s, n );
+ vec3 v = normalize( tangentMatrix * ( eye - vpos ) );
+ float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+void adsModel(const in vec3 vpos, const in vec3 vnormal, const in vec3 eye, const in float shininess,
+ out vec3 diffuseColor, out vec3 specularColor)
+{
+ diffuseColor = vec3(0.0);
+ specularColor = vec3(0.0);
+
+ vec3 n = normalize( vnormal );
+
+ int i;
+ vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = lights[i].position - vpos;
+ if (length( lights[i].attenuation ) != 0.0) {
+ float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[i].direction );
+ }
+
+ float diffuse = max( dot( s, n ), 0.0 );
+
+ float specular = 0.0;
+ if (diffuse > 0.0 && shininess > 0.0 && att > 0.0) {
+ vec3 r = reflect( -s, n );
+ vec3 v = normalize( eye - vpos );
+ float normFactor = ( shininess + 2.0 ) / 2.0;
+ specular = normFactor * pow( max( dot( r, v ), 0.0 ), shininess );
+ }
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ specularColor += att * lights[i].intensity * specular * lights[i].color;
+ }
+}
+
+void adModel(const in vec3 vpos, const in vec3 vnormal, out vec3 diffuseColor)
+{
+ diffuseColor = vec3(0.0);
+
+ vec3 n = normalize( vnormal );
+
+ int i;
+ vec3 s;
+ for (i = 0; i < lightCount; ++i) {
+ float att = 1.0;
+ if ( lights[i].type != TYPE_DIRECTIONAL ) {
+ s = lights[i].position - vpos;
+ if (length( lights[i].attenuation ) != 0.0) {
+ float dist = length(s);
+ att = 1.0 / (lights[i].attenuation.x + lights[i].attenuation.y * dist + lights[i].attenuation.z * dist * dist);
+ }
+ s = normalize( s );
+ if ( lights[i].type == TYPE_SPOT ) {
+ if ( degrees(acos(dot(-s, normalize(lights[i].direction))) ) > lights[i].cutOffAngle)
+ att = 0.0;
+ }
+ } else {
+ s = normalize( -lights[i].direction );
+ }
+
+ float diffuse = max( dot( s, n ), 0.0 );
+
+ diffuseColor += att * lights[i].intensity * diffuse * lights[i].color;
+ }
+}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.frag b/src/extras/shaders/gl3/normaldiffusemap.frag
new file mode 100644
index 000000000..a99a7ed73
--- /dev/null
+++ b/src/extras/shaders/gl3/normaldiffusemap.frag
@@ -0,0 +1,33 @@
+#version 150 core
+
+in vec3 worldPosition;
+in vec2 texCoord;
+in mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform vec3 ka; // Ambient reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/normaldiffusemap.vert b/src/extras/shaders/gl3/normaldiffusemap.vert
new file mode 100644
index 000000000..306a562fb
--- /dev/null
+++ b/src/extras/shaders/gl3/normaldiffusemap.vert
@@ -0,0 +1,39 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec2 vertexTexCoord;
+in vec4 vertexTangent;
+
+out vec3 worldPosition;
+out vec2 texCoord;
+out mat3 tangentMatrix;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+uniform float texCoordScale;
+
+void main()
+{
+ // Pass through texture coordinates
+ texCoord = vertexTexCoord * texCoordScale;
+
+ // Transform position, normal, and tangent to world coords
+ vec3 normal = normalize( modelNormalMatrix * vertexNormal );
+ vec3 tangent = normalize( modelNormalMatrix * vertexTangent.xyz );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ // Calculate binormal vector
+ vec3 binormal = normalize( cross( normal, tangent ) );
+
+ // Construct matrix to transform from eye coords to tangent space
+ tangentMatrix = mat3 (
+ tangent.x, binormal.x, normal.x,
+ tangent.y, binormal.y, normal.y,
+ tangent.z, binormal.z, normal.z );
+
+ // Calculate vertex position in clip coordinates
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/normaldiffusemapalpha.frag b/src/extras/shaders/gl3/normaldiffusemapalpha.frag
new file mode 100644
index 000000000..ce5cf0e90
--- /dev/null
+++ b/src/extras/shaders/gl3/normaldiffusemapalpha.frag
@@ -0,0 +1,34 @@
+#version 150 core
+
+in vec3 worldPosition;
+in vec2 texCoord;
+in mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform vec3 ka; // Ambient reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ // Use the alpha from the diffuse texture (for alpha to coverage)
+ fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + ks * specularColor, diffuseTextureColor.a );
+}
diff --git a/src/extras/shaders/gl3/normaldiffusespecularmap.frag b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
new file mode 100644
index 000000000..b62932ffd
--- /dev/null
+++ b/src/extras/shaders/gl3/normaldiffusespecularmap.frag
@@ -0,0 +1,34 @@
+#version 150 core
+
+in vec3 worldPosition;
+in vec2 texCoord;
+in mat3 tangentMatrix;
+
+uniform sampler2D diffuseTexture;
+uniform sampler2D specularTexture;
+uniform sampler2D normalTexture;
+
+// TODO: Replace with a struct
+uniform vec3 ka; // Ambient reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ // Sample the textures at the interpolated texCoords
+ vec4 diffuseTextureColor = texture( diffuseTexture, texCoord );
+ vec4 specularTextureColor = texture( specularTexture, texCoord );
+ vec3 normal = 2.0 * texture( normalTexture, texCoord ).rgb - vec3( 1.0 );
+
+ // Calculate the lighting model, keeping the specular component separate
+ vec3 diffuseColor, specularColor;
+ adsModelNormalMapped(worldPosition, normal, eyePosition, shininess, tangentMatrix, diffuseColor, specularColor);
+
+ // Combine spec with ambient+diffuse for final fragment color
+ fragColor = vec4( ka + diffuseTextureColor.rgb * diffuseColor + specularTextureColor.rgb * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/pervertexcolor.frag b/src/extras/shaders/gl3/pervertexcolor.frag
new file mode 100644
index 000000000..b5ed5a33d
--- /dev/null
+++ b/src/extras/shaders/gl3/pervertexcolor.frag
@@ -0,0 +1,16 @@
+#version 150 core
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+in vec3 color;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ vec3 diffuseColor;
+ adModel(worldPosition, worldNormal, diffuseColor);
+ fragColor = vec4( color + color * diffuseColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/pervertexcolor.vert b/src/extras/shaders/gl3/pervertexcolor.vert
new file mode 100644
index 000000000..87713a520
--- /dev/null
+++ b/src/extras/shaders/gl3/pervertexcolor.vert
@@ -0,0 +1,22 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+in vec3 vertexColor;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+out vec3 color;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 mvp;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+ color = vertexColor;
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/phong.frag b/src/extras/shaders/gl3/phong.frag
new file mode 100644
index 000000000..a4d7e0969
--- /dev/null
+++ b/src/extras/shaders/gl3/phong.frag
@@ -0,0 +1,22 @@
+#version 150 core
+
+uniform vec3 ka; // Ambient reflectivity
+uniform vec3 kd; // Diffuse reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform float shininess; // Specular shininess factor
+
+uniform vec3 eyePosition;
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+ fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/phong.vert b/src/extras/shaders/gl3/phong.vert
new file mode 100644
index 000000000..cdb3c70e9
--- /dev/null
+++ b/src/extras/shaders/gl3/phong.vert
@@ -0,0 +1,19 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec3 vertexNormal;
+
+out vec3 worldPosition;
+out vec3 worldNormal;
+
+uniform mat4 modelMatrix;
+uniform mat3 modelNormalMatrix;
+uniform mat4 modelViewProjection;
+
+void main()
+{
+ worldNormal = normalize( modelNormalMatrix * vertexNormal );
+ worldPosition = vec3( modelMatrix * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = modelViewProjection * vec4( vertexPosition, 1.0 );
+}
diff --git a/src/extras/shaders/gl3/phongalpha.frag b/src/extras/shaders/gl3/phongalpha.frag
new file mode 100644
index 000000000..cb019e9aa
--- /dev/null
+++ b/src/extras/shaders/gl3/phongalpha.frag
@@ -0,0 +1,24 @@
+#version 150 core
+
+// TODO: Replace with a struct
+uniform vec3 ka; // Ambient reflectivity
+uniform vec3 kd; // Diffuse reflectivity
+uniform vec3 ks; // Specular reflectivity
+uniform float shininess; // Specular shininess factor
+uniform float alpha;
+
+uniform vec3 eyePosition;
+
+in vec3 worldPosition;
+in vec3 worldNormal;
+
+out vec4 fragColor;
+
+#pragma include light.inc.frag
+
+void main()
+{
+ vec3 diffuseColor, specularColor;
+ adsModel(worldPosition, worldNormal, eyePosition, shininess, diffuseColor, specularColor);
+ fragColor = vec4( ka + kd * diffuseColor + ks * specularColor, alpha );
+}
diff --git a/src/extras/shaders/gl3/skybox.frag b/src/extras/shaders/gl3/skybox.frag
new file mode 100644
index 000000000..99c8f111b
--- /dev/null
+++ b/src/extras/shaders/gl3/skybox.frag
@@ -0,0 +1,10 @@
+#version 140
+
+in vec3 texCoord0;
+out vec4 fragColor;
+uniform samplerCube skyboxTexture;
+
+void main()
+{
+ fragColor = texture(skyboxTexture, texCoord0);
+}
diff --git a/src/extras/shaders/gl3/skybox.vert b/src/extras/shaders/gl3/skybox.vert
new file mode 100644
index 000000000..17bb2b00b
--- /dev/null
+++ b/src/extras/shaders/gl3/skybox.vert
@@ -0,0 +1,14 @@
+#version 140
+
+in vec3 vertexPosition;
+out vec3 texCoord0;
+
+uniform mat4 mvp;
+uniform mat4 inverseProjectionMatrix;
+uniform mat4 inverseModelView;
+
+void main()
+{
+ texCoord0 = vertexPosition.xyz;
+ gl_Position = vec4(mvp * vec4(vertexPosition, 1.0)).xyww;
+}
diff --git a/src/extras/shaders/gl3/unlittexture.frag b/src/extras/shaders/gl3/unlittexture.frag
new file mode 100644
index 000000000..8abbeee8f
--- /dev/null
+++ b/src/extras/shaders/gl3/unlittexture.frag
@@ -0,0 +1,13 @@
+#version 150 core
+
+uniform sampler2D diffuseTexture;
+
+in vec3 position;
+in vec2 texCoord;
+
+out vec4 fragColor;
+
+void main()
+{
+ fragColor = texture( diffuseTexture, texCoord );
+}
diff --git a/src/extras/shaders/gl3/unlittexture.vert b/src/extras/shaders/gl3/unlittexture.vert
new file mode 100644
index 000000000..4aaa10a8f
--- /dev/null
+++ b/src/extras/shaders/gl3/unlittexture.vert
@@ -0,0 +1,19 @@
+#version 150 core
+
+in vec3 vertexPosition;
+in vec2 vertexTexCoord;
+
+out vec3 position;
+out vec2 texCoord;
+
+uniform mat4 modelView;
+uniform mat4 mvp;
+uniform vec2 texCoordOffset;
+
+void main()
+{
+ texCoord = vertexTexCoord + texCoordOffset;
+ position = vec3( modelView * vec4( vertexPosition, 1.0 ) );
+
+ gl_Position = mvp * vec4( vertexPosition, 1.0 );
+}