diff options
Diffstat (limited to 'src/extras')
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 ); +} |