summaryrefslogtreecommitdiffstats
path: root/src/threed/materials
diff options
context:
space:
mode:
Diffstat (limited to 'src/threed/materials')
-rw-r--r--src/threed/materials/materials.pri18
-rw-r--r--src/threed/materials/qglabstractmaterial.cpp239
-rw-r--r--src/threed/materials/qglabstractmaterial.h82
-rw-r--r--src/threed/materials/qglcolormaterial.cpp162
-rw-r--r--src/threed/materials/qglcolormaterial.h85
-rw-r--r--src/threed/materials/qglmaterial.cpp586
-rw-r--r--src/threed/materials/qglmaterial.h149
-rw-r--r--src/threed/materials/qglmaterial_p.h85
-rw-r--r--src/threed/materials/qgltwosidedmaterial.cpp259
-rw-r--r--src/threed/materials/qgltwosidedmaterial.h89
10 files changed, 1754 insertions, 0 deletions
diff --git a/src/threed/materials/materials.pri b/src/threed/materials/materials.pri
new file mode 100644
index 000000000..3eb8e0173
--- /dev/null
+++ b/src/threed/materials/materials.pri
@@ -0,0 +1,18 @@
+
+INCLUDEPATH += $$PWD
+VPATH += $$PWD
+
+HEADERS += \
+ qglabstractmaterial.h \
+ qglcolormaterial.h \
+ qglmaterial.h \
+ qgltwosidedmaterial.h
+
+SOURCES += \
+ qglabstractmaterial.cpp \
+ qglcolormaterial.cpp \
+ qglmaterial.cpp \
+ qgltwosidedmaterial.cpp
+
+PRIVATE_HEADERS += \
+ qglmaterial_p.h
diff --git a/src/threed/materials/qglabstractmaterial.cpp b/src/threed/materials/qglabstractmaterial.cpp
new file mode 100644
index 000000000..c0b37dc37
--- /dev/null
+++ b/src/threed/materials/qglabstractmaterial.cpp
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglabstractmaterial.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGLAbstractMaterial
+ \since 4.8
+ \brief The QGLAbstractMaterial class provides a standard interface for rendering surface materials with GL.
+ \ingroup qt3d
+ \ingroup qt3d::materials
+
+ Materials are the primary method to specify the surface appearance of an
+ object, as distinct from the geometry for the object. Materials have an
+ almost endless variety of parameters:
+
+ \list
+ \o Properties of the material under various lighting conditions;
+ i.e., the traditional parameters for ambient, diffuse, specular, etc.
+ \o Textures in multiple layers, with different combination modes;
+ decal, modulate, replace, etc.
+ \o Environmental conditions such as fogging.
+ \o Alpha values for opacity and blending.
+ \o Interpolation factors for animated surface effects.
+ \o etc
+ \endlist
+
+ QGLAbstractMaterial is the base class for all such materials.
+ It provides a very simple API to bind() a material to a QGLPainter
+ when the material needs to be rendered, to release() a material
+ from a QGLPainter when the material is no longer needed, and to
+ prepareToDraw().
+
+ Subclasses of QGLAbstractMaterial implement specific materials.
+ QGLMaterial provides the traditional ambient, diffuse, specular, etc
+ parameters for lighting properties.
+
+ Materials are distinct from \i effects, which have the base class
+ QGLAbstractEffect. Effects are typically shader programs that are
+ used to render a specific type of material. The material's bind()
+ function will use QGLPainter::setStandardEffect() or
+ QGLPainter::setUserEffect() to select the exact effect that is
+ needed to render the material.
+
+ It is possible that the same material may be rendered with different
+ effects depending upon the material parameters. For example, a lit
+ material may select a simpler and more efficient shader program effect
+ if the material has the default spotlight properties, or if the
+ QGLPainter only has a single light source specified.
+
+ \sa QGLMaterial, QGLAbstractEffect
+*/
+
+/*!
+ Constructs a new material and attaches it to \a parent.
+*/
+QGLAbstractMaterial::QGLAbstractMaterial(QObject *parent)
+ : QObject(parent)
+{
+}
+
+/*!
+ Destroys this material.
+*/
+QGLAbstractMaterial::~QGLAbstractMaterial()
+{
+}
+
+/*!
+ Returns the material lighting parameters for rendering the front
+ faces of fragments with this abstract material. The default
+ implementation returns null.
+
+ This function is provided as a convenience for applications that
+ wish to alter the lighting parameters or textures of a material,
+ without regard to any wrapping that has been performed to add
+ blending or other options.
+
+ \sa back(), QGLMaterial
+*/
+QGLMaterial *QGLAbstractMaterial::front() const
+{
+ return 0;
+}
+
+/*!
+ Returns the material lighting parameters for rendering the back
+ faces of fragments with this abstract material. The default
+ implementation returns null, which indicates that front()
+ is also used to render back faces.
+
+ \sa front(), QGLMaterial
+*/
+QGLMaterial *QGLAbstractMaterial::back() const
+{
+ return 0;
+}
+
+/*!
+ \fn bool QGLAbstractMaterial::isTransparent() const
+
+ Returns true if this material is transparent and will therefore
+ require the \c{GL_BLEND} mode to be enabled to render the material.
+ Returns false if the material is fully opaque.
+*/
+
+/*!
+ \fn void QGLAbstractMaterial::bind(QGLPainter *painter)
+
+ Binds resources to \a painter that are needed to render this
+ material; textures, shader programs, blending modes, etc.
+
+ In the following example, lit material parameters and a texture
+ are bound to the \a painter, for rendering with the standard
+ QGL::LitModulateTexture2D effect:
+
+ \code
+ void TexturedLitMaterial::bind(QGLPainter *painter)
+ {
+ painter->setStandardEffect(QGL::LitModulateTexture2D);
+ painter->setFaceMaterial(QGL::AllFaces, material);
+ painter->glActiveTexture(GL_TEXTURE0);
+ texture->bind();
+ }
+ \endcode
+
+ Normally the effect is bound to \a painter during the bind()
+ function. However, some materials may need to use different
+ effects depending upon which attributes are present in the
+ geometry. For example, a per-vertex color effect instead of a
+ uniform color effect if the geometry has the QGL::Color attribute.
+ The prepareToDraw() function can be overridden to alter the
+ effect once the specific set of geometry attributes are known.
+
+ \sa release(), prepareToDraw()
+*/
+
+/*!
+ \fn void QGLAbstractMaterial::release(QGLPainter *painter, QGLAbstractMaterial *next)
+
+ Releases resources from \a painter that were used to render this
+ material. The QGLPainter::effect() can be left bound to \a painter,
+ but other resources such as textures and blending modes
+ should be disabled.
+
+ If \a next is not null, then it indicates the next material that
+ will be bound to \a painter. If \a next is the same type of
+ material as this material, then this function can choose not to
+ release resources that would be immediately re-bound to
+ \a painter in the next call to bind().
+
+ In the following example, texture unit 0 is unbound if \a painter
+ is about to switch to another effect that is not an instance
+ of \c{TexturedLitMaterial}:
+
+ \code
+ void TexturedLitMaterial::release(QGLPainter *painter, QGLAbstractMaterial *next)
+ {
+ if (!qobject_cast<TexturedLitMaterial *>(next)) {
+ painter->glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+ }
+ \endcode
+
+ \sa bind(), prepareToDraw()
+*/
+
+/*!
+ Prepares to draw geometry to \a painter that has the specified
+ set of vertex \a attributes. The default implementation
+ does nothing.
+
+ Multiple effects may be used to render some materials depending upon
+ the available vertex attributes. For example, if QGL::Color is
+ present in \a attributes, then a per-vertex color should be used
+ instead of a single uniform color.
+
+ This function is provided for such materials to have one last
+ chance during QGLPainter::draw() to alter the QGLPainter::effect()
+ to something that is tuned for the specific geometry. It can
+ be assumed that bind() has already been called on this material.
+
+ \sa bind(), release()
+*/
+void QGLAbstractMaterial::prepareToDraw(QGLPainter *painter, const QGLAttributeSet &attributes)
+{
+ Q_UNUSED(painter);
+ Q_UNUSED(attributes);
+}
+
+/*!
+ \fn void QGLAbstractMaterial::materialChanged()
+
+ Signal that is emitted when an object that is using this material
+ should be redrawn because some property on the material has changed.
+*/
+
+QT_END_NAMESPACE
diff --git a/src/threed/materials/qglabstractmaterial.h b/src/threed/materials/qglabstractmaterial.h
new file mode 100644
index 000000000..b5a60e5ae
--- /dev/null
+++ b/src/threed/materials/qglabstractmaterial.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLABSTRACTMATERIAL_H
+#define QGLABSTRACTMATERIAL_H
+
+#include <QtCore/qobject.h>
+#include "qglattributeset.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3D)
+
+class QGLPainter;
+class QGLMaterial;
+
+class Q_QT3D_EXPORT QGLAbstractMaterial : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(QGLAbstractMaterial)
+public:
+ explicit QGLAbstractMaterial(QObject *parent = 0);
+ ~QGLAbstractMaterial();
+
+ virtual QGLMaterial *front() const;
+ virtual QGLMaterial *back() const;
+
+ virtual bool isTransparent() const = 0;
+
+ virtual void bind(QGLPainter *painter) = 0;
+ virtual void release(QGLPainter *painter, QGLAbstractMaterial *next) = 0;
+ virtual void prepareToDraw(QGLPainter *painter, const QGLAttributeSet &attributes);
+
+Q_SIGNALS:
+ void materialChanged();
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/threed/materials/qglcolormaterial.cpp b/src/threed/materials/qglcolormaterial.cpp
new file mode 100644
index 000000000..4a507f12a
--- /dev/null
+++ b/src/threed/materials/qglcolormaterial.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglcolormaterial.h"
+#include "qglpainter.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGLColorMaterial
+ \since 4.8
+ \brief The QGLColorMaterial class implements flat or per-vertex color materials for 3D rendering.
+ \ingroup qt3d
+ \ingroup qt3d::materials
+
+ When bound to a QGLPainter, QGLColorMaterial will select a flat
+ color drawing effect, to render fragments with color(), ignoring
+ any lights or textures that may be active on the QGLPainter state.
+ If the geometry has the QGL::Color attribute, then a per-vertex
+ color will be used instead and color() is ignored.
+
+ \sa QGLMaterial
+*/
+
+class QGLColorMaterialPrivate
+{
+public:
+ QGLColorMaterialPrivate() : color(255, 255, 255, 255) {}
+
+ QColor color;
+};
+
+/*!
+ Constructs a new flat color material and attaches it to \a parent.
+*/
+QGLColorMaterial::QGLColorMaterial(QObject *parent)
+ : QGLAbstractMaterial(parent)
+ , d_ptr(new QGLColorMaterialPrivate)
+{
+}
+
+/*!
+ Destroys this flat color material.
+*/
+QGLColorMaterial::~QGLColorMaterial()
+{
+}
+
+/*!
+ \property QGLColorMaterial::color
+ \brief the flat color to use to render the material. The default
+ color is white.
+
+ If the geometry has per-vertex colors, then this property is ignored.
+
+ \sa colorChanged()
+*/
+
+QColor QGLColorMaterial::color() const
+{
+ Q_D(const QGLColorMaterial);
+ return d->color;
+}
+
+void QGLColorMaterial::setColor(const QColor &color)
+{
+ Q_D(QGLColorMaterial);
+ if (d->color != color) {
+ d->color = color;
+ emit colorChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QGLColorMaterial::isTransparent() const
+{
+ Q_D(const QGLColorMaterial);
+ return d->color.alpha() != 255;
+}
+
+/*!
+ \reimp
+*/
+void QGLColorMaterial::bind(QGLPainter *painter)
+{
+ Q_D(const QGLColorMaterial);
+ painter->setColor(d->color);
+ // Effect is set during prepareToDraw().
+}
+
+/*!
+ \reimp
+*/
+void QGLColorMaterial::release(QGLPainter *painter, QGLAbstractMaterial *next)
+{
+ // No textures or other modes, so nothing to do here.
+ Q_UNUSED(painter);
+ Q_UNUSED(next);
+}
+
+/*!
+ \reimp
+*/
+void QGLColorMaterial::prepareToDraw
+ (QGLPainter *painter, const QGLAttributeSet &attributes)
+{
+ if (attributes.contains(QGL::Color))
+ painter->setStandardEffect(QGL::FlatPerVertexColor);
+ else
+ painter->setStandardEffect(QGL::FlatColor);
+}
+
+/*!
+ \fn void QGLColorMaterial::colorChanged()
+
+ Signal that is emitted when color() changes.
+
+ \sa color()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/threed/materials/qglcolormaterial.h b/src/threed/materials/qglcolormaterial.h
new file mode 100644
index 000000000..6ec953ecd
--- /dev/null
+++ b/src/threed/materials/qglcolormaterial.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLCOLORMATERIAL_H
+#define QGLCOLORMATERIAL_H
+
+#include "qglabstractmaterial.h"
+#include <QtGui/qcolor.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3D)
+
+class QGLColorMaterialPrivate;
+
+class Q_QT3D_EXPORT QGLColorMaterial : public QGLAbstractMaterial
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGLColorMaterial)
+ Q_DISABLE_COPY(QGLColorMaterial)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
+public:
+ explicit QGLColorMaterial(QObject *parent = 0);
+ ~QGLColorMaterial();
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+ bool isTransparent() const;
+ void bind(QGLPainter *painter);
+ void release(QGLPainter *painter, QGLAbstractMaterial *next);
+ void prepareToDraw(QGLPainter *painter, const QGLAttributeSet &attributes);
+
+Q_SIGNALS:
+ void colorChanged();
+
+private:
+ QScopedPointer<QGLColorMaterialPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/threed/materials/qglmaterial.cpp b/src/threed/materials/qglmaterial.cpp
new file mode 100644
index 000000000..4d7d4d683
--- /dev/null
+++ b/src/threed/materials/qglmaterial.cpp
@@ -0,0 +1,586 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qglmaterial.h"
+#include "qglmaterial_p.h"
+#include "qglpainter.h"
+#include "qgltexture2d.h"
+#include "qglmaterialcollection.h"
+#include "qgllightmodel.h"
+#include "qfileinfo.h"
+
+#include <QtCore/qurl.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGLMaterial
+ \brief The QGLMaterial class describes one-sided material properties for rendering fragments.
+ \since 4.8
+ \ingroup qt3d
+ \ingroup qt3d::materials
+
+ \sa QGLTwoSidedMaterial
+*/
+
+/*!
+ \qmlclass Material QGLMaterial
+ \brief The Material item describes material properties for OpenGL drawing.
+ \since 4.8
+ \ingroup qt3d::qml3d
+*/
+
+QGLMaterialPrivate::QGLMaterialPrivate()
+ : specularColor(0, 0, 0, 255),
+ emittedLight(0, 0, 0, 255),
+ shininess(0),
+ collection(0),
+ index(-1),
+ used(false)
+{
+ ambientColor.setRgbF(0.2f, 0.2f, 0.2f, 1.0f);
+ diffuseColor.setRgbF(0.8f, 0.8f, 0.8f, 1.0f);
+}
+
+/*!
+ Constructs a QGLMaterial object with its default values,
+ and attaches it to \a parent.
+*/
+QGLMaterial::QGLMaterial(QObject *parent)
+ : QGLAbstractMaterial(parent)
+ , d_ptr(new QGLMaterialPrivate)
+{
+}
+
+/*!
+ Destroys this QGLMaterial object.
+*/
+QGLMaterial::~QGLMaterial()
+{
+}
+
+/*!
+ \property QGLMaterial::ambientColor
+ \brief the ambient color of the material. The default value
+ is (0.2, 0.2, 0.2, 1.0).
+
+ \sa diffuseColor(), specularColor(), ambientColorChanged()
+*/
+
+/*!
+ \qmlproperty color Material::ambientColor
+ The ambient color of the material. The default value
+ is (0.2, 0.2, 0.2, 1.0).
+
+ \sa diffuseColor, specularColor
+*/
+
+QColor QGLMaterial::ambientColor() const
+{
+ Q_D(const QGLMaterial);
+ return d->ambientColor;
+}
+
+void QGLMaterial::setAmbientColor(const QColor& value)
+{
+ Q_D(QGLMaterial);
+ if (d->ambientColor != value) {
+ d->ambientColor = value;
+ emit ambientColorChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLMaterial::diffuseColor
+ \brief the diffuse color of the material. The default value
+ is (0.8, 0.8, 0.8, 1.0).
+
+ \sa ambientColor(), specularColor(), diffuseColorChanged()
+*/
+
+/*!
+ \qmlproperty color Material::diffuseColor
+ The diffuse color of the material. The default value
+ is (0.8, 0.8, 0.8, 1.0).
+
+ \sa ambientColor, specularColor
+*/
+
+QColor QGLMaterial::diffuseColor() const
+{
+ Q_D(const QGLMaterial);
+ return d->diffuseColor;
+}
+
+void QGLMaterial::setDiffuseColor(const QColor& value)
+{
+ Q_D(QGLMaterial);
+ if (d->diffuseColor != value) {
+ d->diffuseColor = value;
+ emit diffuseColorChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLMaterial::specularColor
+ \brief the specular color of the material. The default value
+ is (0, 0, 0, 1).
+
+ \sa ambientColor(), diffuseColor(), specularColorChanged()
+*/
+
+/*!
+ \qmlproperty color Material::specularColor
+ The specular color of the material. The default value
+ is (0, 0, 0, 1).
+
+ \sa ambientColor, diffuseColor
+*/
+
+QColor QGLMaterial::specularColor() const
+{
+ Q_D(const QGLMaterial);
+ return d->specularColor;
+}
+
+void QGLMaterial::setSpecularColor(const QColor& value)
+{
+ Q_D(QGLMaterial);
+ if (d->specularColor != value) {
+ d->specularColor = value;
+ emit specularColorChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLMaterial::emittedLight
+ \brief the emitted light intensity of the material.
+ The default value is (0.0, 0.0, 0.0, 1.0), which indicates
+ that the material does not emit any light.
+
+ \sa emittedLightChanged()
+*/
+
+/*!
+ \qmlproperty color Material::emittedLight
+ The emitted light intensity of the material.
+ The default value is (0.0, 0.0, 0.0, 1.0), which indicates
+ that the material does not emit any light.
+*/
+
+QColor QGLMaterial::emittedLight() const
+{
+ Q_D(const QGLMaterial);
+ return d->emittedLight;
+}
+
+void QGLMaterial::setEmittedLight(const QColor& value)
+{
+ Q_D(QGLMaterial);
+ if (d->emittedLight != value) {
+ d->emittedLight = value;
+ emit emittedLightChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ Sets ambientColor() to 20% of \a value, and diffuseColor() to 80% of
+ \a value. This is a convenience function for quickly setting ambient
+ and diffuse lighting colors based on a flat color.
+
+ \sa ambientColor(), diffuseColor()
+*/
+void QGLMaterial::setColor(const QColor& value)
+{
+ Q_D(QGLMaterial);
+ d->ambientColor.setRgbF
+ (value.redF() * 0.2f, value.greenF() * 0.2f,
+ value.blueF() * 0.2f, value.alphaF());
+ d->diffuseColor.setRgbF
+ (value.redF() * 0.8f, value.greenF() * 0.8f,
+ value.blueF() * 0.8f, value.alphaF());
+ emit ambientColorChanged();
+ emit diffuseColorChanged();
+ emit materialChanged();
+}
+
+/*!
+ \property QGLMaterial::shininess
+ \brief the specular exponent of the material, or how shiny it is.
+ Must be between 0 and 128. The default value is 0. A value outside
+ this range will be clamped to the range when the property is set.
+
+ \sa shininessChanged()
+*/
+
+/*!
+ \qmlproperty real Material::shininess
+ The specular exponent of the material, or how shiny it is.
+ Must be between 0 and 128. The default value is 0. A value outside
+ this range will be clamped to the range when the property is set.
+*/
+
+qreal QGLMaterial::shininess() const
+{
+ Q_D(const QGLMaterial);
+ return d->shininess;
+}
+
+void QGLMaterial::setShininess(qreal value)
+{
+ Q_D(QGLMaterial);
+ if (value < 0)
+ value = 0;
+ else if (value > 128)
+ value = 128;
+ if (d->shininess != value) {
+ d->shininess = value;
+ emit shininessChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLMaterial::texture
+ \brief the 2D texture associated with \a layer on this material;
+ null if no texture.
+
+ Layer 0 is normally the primary texture associated with the material.
+ Multiple texture layers may be specified for materials with special
+ blending effects or to specify ambient, diffuse, or specular colors
+ pixel-by-pixel.
+
+ \sa texturesChanged()
+*/
+QGLTexture2D *QGLMaterial::texture(int layer) const
+{
+ Q_D(const QGLMaterial);
+ return d->textures.value(layer, 0);
+}
+
+void QGLMaterial::setTexture(QGLTexture2D *value, int layer)
+{
+ Q_ASSERT(layer >= 0);
+ Q_D(QGLMaterial);
+ QGLTexture2D *prev = d->textures.value(layer, 0);
+ if (prev != value) {
+ delete prev;
+ d->textures[layer] = value;
+ emit texturesChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLMaterial::textureUrl
+ \brief URL of the 2D texture associated with \a layer on this material.
+
+ By default \a layer is 0, the primary texture.
+
+ If the URL has not been specified, then this property is a null QUrl.
+
+ Setting this property to a non-empty URL will replace any existing texture
+ with a new texture based on the image at the given \a url. If that
+ image is not a valid texture then the new texture will be a null texture.
+
+ If an empty url is set, this has the same effect as \c{setTexture(0)}.
+
+ \sa texture(), setTexture()
+*/
+QUrl QGLMaterial::textureUrl(int layer) const
+{
+ Q_D(const QGLMaterial);
+ QGLTexture2D *tex = d->textures.value(layer, 0);
+ if (tex)
+ return tex->url();
+ else
+ return QUrl();
+}
+
+void QGLMaterial::setTextureUrl(const QUrl &url, int layer)
+{
+ Q_ASSERT(layer >= 0);
+ if (textureUrl(layer) != url)
+ {
+ QGLTexture2D *tex = 0;
+ if (!url.isEmpty())
+ {
+ tex = new QGLTexture2D(this);
+ tex->setUrl(url);
+ }
+ setTexture(tex, layer);
+ }
+}
+
+/*!
+ \enum QGLMaterial::TextureCombineMode
+ This enum defines the mode to use when combining a texture with
+ the material colors on a QGLMaterial object.
+
+ \value Modulate Modulate the texture with the lighting
+ conditions to produce a lit texture.
+ \value Decal Combine the texture with the lighting conditions
+ to produce a decal effect.
+ \value Replace Replace with the contents of the texture,
+ ignoring colors and lighting conditions.
+*/
+
+/*!
+ \property QGLMaterial::textureCombineMode
+ \brief the texture combine mode associated with \a layer on this material.
+ The default value is \l Modulate.
+
+ \sa texturesChanged()
+*/
+
+QGLMaterial::TextureCombineMode QGLMaterial::textureCombineMode(int layer) const
+{
+ Q_D(const QGLMaterial);
+ return d->textureModes.value(layer, Modulate);
+}
+
+void QGLMaterial::setTextureCombineMode(QGLMaterial::TextureCombineMode mode, int layer)
+{
+ Q_D(QGLMaterial);
+ if (d->textureModes.value(layer, Modulate) != mode) {
+ d->textureModes[layer] = mode;
+ emit texturesChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ Returns the number of texture layers associated with this material.
+
+ The return value may be larger than the number of actual texture
+ layers if some of the intermediate layers are null. For example,
+ setting layers 0 and 2 will report textureLayerCount() as 3.
+ The main use of this value is to iterate over all layers.
+
+ \sa texture()
+*/
+int QGLMaterial::textureLayerCount() const
+{
+ Q_D(const QGLMaterial);
+ int maxLayer = -1;
+ if (!d->textures.isEmpty())
+ maxLayer = qMax(maxLayer, (d->textures.end() - 1).key());
+ return maxLayer + 1;
+}
+
+/*!
+ \reimp
+ Returns this material.
+*/
+QGLMaterial *QGLMaterial::front() const
+{
+ return const_cast<QGLMaterial *>(this);
+}
+
+/*!
+ \reimp
+*/
+bool QGLMaterial::isTransparent() const
+{
+ Q_D(const QGLMaterial);
+ bool transparent = (d->diffuseColor.alpha() != 255);
+ QMap<int, QGLTexture2D *>::ConstIterator it;
+ for (it = d->textures.begin(); it != d->textures.end(); ++it) {
+ TextureCombineMode mode = d->textureModes.value(it.key(), Modulate);
+ if (mode == Modulate) {
+ // Texture alpha adds to the current alpha.
+ if (it.value() && it.value()->hasAlphaChannel())
+ transparent = true;
+ } else if (mode == Replace) {
+ // Replace the current alpha with the texture's alpha.
+ if (it.value())
+ transparent = it.value()->hasAlphaChannel();
+ }
+ }
+ return transparent;
+}
+
+/*!
+ \reimp
+*/
+void QGLMaterial::bind(QGLPainter *painter)
+{
+ painter->setFaceMaterial(QGL::AllFaces, this);
+ const_cast<QGLLightModel *>(painter->lightModel())
+ ->setModel(QGLLightModel::OneSided); // FIXME
+ bindTextures(painter);
+}
+
+/*!
+ \internal
+*/
+void QGLMaterial::bindTextures(QGLPainter *painter)
+{
+ Q_D(const QGLMaterial);
+ QMap<int, QGLTexture2D *>::ConstIterator it;
+ for (it = d->textures.begin(); it != d->textures.end(); ++it) {
+ QGLTexture2D *tex = it.value();
+ painter->glActiveTexture(GL_TEXTURE0 + it.key());
+ if (tex)
+ tex->bind();
+ else
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGLMaterial::release(QGLPainter *painter, QGLAbstractMaterial *next)
+{
+ Q_UNUSED(next);
+ Q_D(const QGLMaterial);
+ QMap<int, QGLTexture2D *>::ConstIterator it;
+ for (it = d->textures.begin(); it != d->textures.end(); ++it) {
+ painter->glActiveTexture(GL_TEXTURE0 + it.key());
+ glBindTexture(GL_TEXTURE_2D, 0);
+ }
+}
+
+/*!
+ \reimp
+*/
+void QGLMaterial::prepareToDraw
+ (QGLPainter *painter, const QGLAttributeSet &attributes)
+{
+ bindEffect(painter, attributes, false);
+}
+
+/*!
+ \internal
+*/
+void QGLMaterial::bindEffect
+ (QGLPainter *painter, const QGLAttributeSet &attributes, bool twoSided)
+{
+ Q_D(const QGLMaterial);
+ Q_UNUSED(twoSided);
+ QGL::StandardEffect effect = QGL::LitMaterial;
+ if (!d->textures.isEmpty() && attributes.contains(QGL::TextureCoord0)) {
+ // TODO: different combine modes for each layer.
+ QGLMaterial::TextureCombineMode mode =
+ d->textureModes.value(0, Modulate);
+ if (mode == Replace)
+ effect = QGL::FlatReplaceTexture2D;
+ else if (mode == Decal)
+ effect = QGL::LitDecalTexture2D;
+ else
+ effect = QGL::LitModulateTexture2D;
+ }
+ painter->setStandardEffect(effect);
+}
+
+/*!
+ \fn void QGLMaterial::ambientColorChanged()
+
+ This signal is emitted when ambientColor() changes.
+
+ \sa ambientColor(), setAmbientColor(), materialChanged()
+*/
+
+/*!
+ \fn void QGLMaterial::diffuseColorChanged()
+
+ This signal is emitted when diffuseColor() changes.
+
+ \sa diffuseColor(), setDiffuseColor(), materialChanged()
+*/
+
+/*!
+ \fn void QGLMaterial::specularColorChanged()
+
+ This signal is emitted when specularColor() changes.
+
+ \sa specularColor(), setSpecularColor(), materialChanged()
+*/
+
+/*!
+ \fn void QGLMaterial::emittedLightChanged()
+
+ This signal is emitted when emittedLight() changes.
+
+ \sa emittedLight(), setEmittedLight(), materialChanged()
+*/
+
+/*!
+ \fn void QGLMaterial::shininessChanged()
+
+ This signal is emitted when shininess() changes.
+
+ \sa shininess(), setShininess(), materialChanged()
+*/
+
+/*!
+ \fn void QGLMaterial::texturesChanged()
+
+ This signal is emitted when the texture layers associated with
+ this material change.
+
+ \sa texture(), setTexture(), materialChanged()
+*/
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<(QDebug dbg, const QGLMaterial &material)
+{
+ dbg << &material <<
+ "-- Amb:" << material.ambientColor() <<
+ "-- Diff:" << material.diffuseColor() <<
+ "-- Spec:" << material.specularColor() <<
+ "-- Shin:" << material.shininess();
+ for (int i = 0; i < material.textureLayerCount(); ++i)
+ if (material.texture(i) != 0)
+ dbg << "\n -- Tex" << i << ":" << material.texture(i)
+ << material.texture(i)->objectName();
+ dbg << "\n";
+ return dbg;
+}
+#endif
+
+QT_END_NAMESPACE
diff --git a/src/threed/materials/qglmaterial.h b/src/threed/materials/qglmaterial.h
new file mode 100644
index 000000000..74feb9e90
--- /dev/null
+++ b/src/threed/materials/qglmaterial.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLMATERIAL_H
+#define QGLMATERIAL_H
+
+#include "qglabstractmaterial.h"
+#include <QtCore/qobject.h>
+#include <QtCore/qscopedpointer.h>
+#include <QtGui/qcolor.h>
+#include <QtCore/qurl.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3D)
+
+class QGLMaterialPrivate;
+class QGLTexture2D;
+class QGLTextureCube;
+class QGLPainter;
+class QGLMaterialCollection;
+class QGLTwoSidedMaterial;
+
+class Q_QT3D_EXPORT QGLMaterial : public QGLAbstractMaterial
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGLMaterial)
+ Q_DISABLE_COPY(QGLMaterial)
+ Q_ENUMS(TextureCombineMode)
+ Q_PROPERTY(QColor ambientColor READ ambientColor WRITE setAmbientColor NOTIFY ambientColorChanged)
+ Q_PROPERTY(QColor diffuseColor READ diffuseColor WRITE setDiffuseColor NOTIFY diffuseColorChanged)
+ Q_PROPERTY(QColor specularColor READ specularColor WRITE setSpecularColor NOTIFY specularColorChanged)
+ Q_PROPERTY(QColor emittedLight READ emittedLight WRITE setEmittedLight NOTIFY emittedLightChanged)
+ Q_PROPERTY(qreal shininess READ shininess WRITE setShininess NOTIFY shininessChanged)
+ Q_PROPERTY(QGLTexture2D *texture READ texture WRITE setTexture NOTIFY texturesChanged)
+ Q_PROPERTY(QGLMaterial::TextureCombineMode textureCombineMode READ textureCombineMode WRITE setTextureCombineMode NOTIFY texturesChanged)
+ Q_PROPERTY(QUrl textureUrl READ textureUrl WRITE setTextureUrl NOTIFY texturesChanged)
+public:
+ explicit QGLMaterial(QObject *parent = 0);
+ ~QGLMaterial();
+
+ QColor ambientColor() const;
+ void setAmbientColor(const QColor& value);
+
+ QColor diffuseColor() const;
+ void setDiffuseColor(const QColor& value);
+
+ QColor specularColor() const;
+ void setSpecularColor(const QColor& value);
+
+ QColor emittedLight() const;
+ void setEmittedLight(const QColor& value);
+
+ void setColor(const QColor& value);
+
+ qreal shininess() const;
+ void setShininess(qreal value);
+
+ QGLTexture2D *texture(int layer = 0) const;
+ void setTexture(QGLTexture2D *value, int layer = 0);
+
+ QUrl textureUrl(int layer = 0) const;
+ void setTextureUrl(const QUrl &url, int layer = 0);
+
+ enum TextureCombineMode
+ {
+ Modulate,
+ Decal,
+ Replace
+ };
+
+ QGLMaterial::TextureCombineMode textureCombineMode(int layer = 0) const;
+ void setTextureCombineMode(QGLMaterial::TextureCombineMode mode, int layer = 0);
+
+ int textureLayerCount() const;
+
+ QGLMaterial *front() const;
+ bool isTransparent() const;
+ void bind(QGLPainter *painter);
+ void release(QGLPainter *painter, QGLAbstractMaterial *next);
+ void prepareToDraw(QGLPainter *painter, const QGLAttributeSet &attributes);
+
+Q_SIGNALS:
+ void ambientColorChanged();
+ void diffuseColorChanged();
+ void specularColorChanged();
+ void emittedLightChanged();
+ void shininessChanged();
+ void texturesChanged();
+
+private:
+ friend class QGLMaterialCollection;
+ friend class QGLTwoSidedMaterial;
+
+ void bindTextures(QGLPainter *painter);
+ void bindEffect(QGLPainter *painter, const QGLAttributeSet &attributes, bool twoSided);
+
+ QScopedPointer<QGLMaterialPrivate> d_ptr;
+};
+
+#ifndef QT_NO_DEBUG_STREAM
+Q_QT3D_EXPORT QDebug operator<<(QDebug dbg, const QGLMaterial &material);
+#endif
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/threed/materials/qglmaterial_p.h b/src/threed/materials/qglmaterial_p.h
new file mode 100644
index 000000000..2084f99f0
--- /dev/null
+++ b/src/threed/materials/qglmaterial_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLMATERIAL_P_H
+#define QGLMATERIAL_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 "qglmaterial.h"
+#include <QtCore/qmap.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QGLMaterialPrivate
+{
+public:
+ explicit QGLMaterialPrivate();
+
+ QColor ambientColor;
+ QColor diffuseColor;
+ QColor specularColor;
+ QColor emittedLight;
+ qreal shininess;
+ QMap<int, QGLTexture2D *> textures;
+ QMap<int, QGLMaterial::TextureCombineMode> textureModes;
+ QGLMaterialCollection *collection;
+ int index;
+ QString name;
+ bool used;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/threed/materials/qgltwosidedmaterial.cpp b/src/threed/materials/qgltwosidedmaterial.cpp
new file mode 100644
index 000000000..d8d69b227
--- /dev/null
+++ b/src/threed/materials/qgltwosidedmaterial.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgltwosidedmaterial.h"
+#include "qglpainter.h"
+#include "qgllightmodel.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QGLTwoSidedMaterial
+ \since 4.8
+ \brief The QGLTwoSidedMaterial class implemented two-sided materials for 3D rendering.
+ \ingroup qt3d
+ \ingroup qt3d::materials
+
+ Two-sided materials consist of a front() material and a back()
+ material. The specific material rendered is determined by the
+ direction faced by a fragment when it is rendered. Fragments
+ that point towards the viewer are rendered with front(),
+ and fragments that point away from the viewer are rendered
+ with back(). In both cases, any textures that are used to
+ render the material are taken from front().
+
+ If front() and back() are the same, then the same material
+ will be used on both sides of the fragment. However, this
+ is not exactly the same as using a one-sided QGLMaterial in
+ place of the two-sided material. One-sided materials will
+ render the back of the fragment as black because the normal
+ is always pointing away from the viewer. Two-sided materials
+ reverse the back-facing normal so that back() is lit as
+ though it was on a front-facing face.
+
+ \sa QGLMaterial
+*/
+
+class QGLTwoSidedMaterialPrivate
+{
+public:
+ QGLTwoSidedMaterialPrivate() : front(0), back(0), defaultMaterial(0) {}
+
+ QGLMaterial *front;
+ QGLMaterial *back;
+ QGLMaterial *defaultMaterial;
+};
+
+/*!
+ Constructs a two-sided material object and attaches it to \a parent.
+
+ \sa setFront(), setBack()
+*/
+QGLTwoSidedMaterial::QGLTwoSidedMaterial(QObject *parent)
+ : QGLAbstractMaterial(parent)
+ , d_ptr(new QGLTwoSidedMaterialPrivate)
+{
+}
+
+/*!
+ Destroys this two-sided material object.
+*/
+QGLTwoSidedMaterial::~QGLTwoSidedMaterial()
+{
+}
+
+/*!
+ \property QGLTwoSidedMaterial::front
+ \brief the material for the front side of the object's fragments.
+
+ The default value is null, which will result in a default QGLMaterial
+ object being used when bind() is called.
+
+ \sa back(), frontChanged(), materialChanged()
+*/
+
+QGLMaterial *QGLTwoSidedMaterial::front() const
+{
+ Q_D(const QGLTwoSidedMaterial);
+ return d->front;
+}
+
+void QGLTwoSidedMaterial::setFront(QGLMaterial *material)
+{
+ Q_D(QGLTwoSidedMaterial);
+ if (d->front != material) {
+ if (d->front && d->front != d->back) {
+ disconnect(d->front, SIGNAL(materialChanged()),
+ this, SIGNAL(materialChanged()));
+ }
+ d->front = material;
+ if (d->front && d->front != d->back) {
+ connect(d->front, SIGNAL(materialChanged()),
+ this, SIGNAL(materialChanged()));
+ }
+ emit frontChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \property QGLTwoSidedMaterial::back
+ \brief the material for the back side of the object's fragments.
+
+ The default value is null, which indicates that front() should
+ be used on both the front and back sides of the object's fragments.
+
+ Textures are taken from the front() material. Any textures that
+ appear in the back() material are ignored. Only the material
+ lighting parameters from back() will be used.
+
+ \sa front(), backChanged(), materialChanged()
+*/
+
+QGLMaterial *QGLTwoSidedMaterial::back() const
+{
+ Q_D(const QGLTwoSidedMaterial);
+ return d->back;
+}
+
+void QGLTwoSidedMaterial::setBack(QGLMaterial *material)
+{
+ Q_D(QGLTwoSidedMaterial);
+ if (d->back != material) {
+ if (d->back && d->back != d->front) {
+ disconnect(d->back, SIGNAL(materialChanged()),
+ this, SIGNAL(materialChanged()));
+ }
+ d->back = material;
+ if (d->back && d->back != d->front) {
+ connect(d->back, SIGNAL(materialChanged()),
+ this, SIGNAL(materialChanged()));
+ }
+ emit backChanged();
+ emit materialChanged();
+ }
+}
+
+/*!
+ \reimp
+*/
+bool QGLTwoSidedMaterial::isTransparent() const
+{
+ Q_D(const QGLTwoSidedMaterial);
+ if (d->front && d->front->isTransparent())
+ return true;
+ return d->back && d->back->isTransparent();
+}
+
+/*!
+ \reimp
+*/
+void QGLTwoSidedMaterial::bind(QGLPainter *painter)
+{
+ Q_D(QGLTwoSidedMaterial);
+ QGLMaterial *front = d->front;
+ if (!front) {
+ // We need to have something for the front material.
+ front = d->defaultMaterial;
+ if (!front) {
+ d->defaultMaterial = new QGLMaterial(this);
+ front = d->defaultMaterial;
+ }
+ }
+ const_cast<QGLLightModel *>(painter->lightModel())
+ ->setModel(QGLLightModel::TwoSided); // FIXME
+ if (d->back && d->back != front) {
+ painter->setFaceMaterial(QGL::FrontFaces, front);
+ painter->setFaceMaterial(QGL::BackFaces, d->back);
+ } else {
+ painter->setFaceMaterial(QGL::AllFaces, front);
+ }
+ front->bindTextures(painter);
+}
+
+/*!
+ \reimp
+*/
+void QGLTwoSidedMaterial::release(QGLPainter *painter, QGLAbstractMaterial *next)
+{
+ Q_D(const QGLTwoSidedMaterial);
+ if (d->front)
+ d->front->release(painter, next);
+ else if (d->defaultMaterial)
+ d->defaultMaterial->release(painter, next);
+}
+
+/*!
+ \reimp
+*/
+void QGLTwoSidedMaterial::prepareToDraw
+ (QGLPainter *painter, const QGLAttributeSet &attributes)
+{
+ Q_D(QGLTwoSidedMaterial);
+ QGLMaterial *front = d->front;
+ if (!front)
+ front = d->defaultMaterial;
+ front->bindEffect(painter, attributes, true);
+}
+
+/*!
+ \fn void QGLTwoSidedMaterial::frontChanged()
+
+ Signal that is emitted when the front() material pointer changes.
+
+ This signal is not emitted when a property on front() changes.
+ Use materialChanged() for that purpose instead.
+
+ \sa front(), backChanged()
+*/
+
+/*!
+ \fn void QGLTwoSidedMaterial::backChanged()
+
+ Signal that is emitted when the back() material pointer changes.
+
+ This signal is not emitted when a property on back() changes.
+ Use materialChanged() for that purpose instead.
+
+ \sa back(), frontChanged()
+*/
+
+QT_END_NAMESPACE
diff --git a/src/threed/materials/qgltwosidedmaterial.h b/src/threed/materials/qgltwosidedmaterial.h
new file mode 100644
index 000000000..65f544e03
--- /dev/null
+++ b/src/threed/materials/qgltwosidedmaterial.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtQuick3D module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGLTWOSIDEDMATERIAL_H
+#define QGLTWOSIDEDMATERIAL_H
+
+#include "qglmaterial.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3D)
+
+class QGLTwoSidedMaterialPrivate;
+
+class Q_QT3D_EXPORT QGLTwoSidedMaterial : public QGLAbstractMaterial
+{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QGLTwoSidedMaterial)
+ Q_DISABLE_COPY(QGLTwoSidedMaterial)
+ Q_PROPERTY(QGLMaterial *front READ front WRITE setFront NOTIFY frontChanged)
+ Q_PROPERTY(QGLMaterial *back READ back WRITE setBack NOTIFY backChanged)
+public:
+ explicit QGLTwoSidedMaterial(QObject *parent = 0);
+ ~QGLTwoSidedMaterial();
+
+ QGLMaterial *front() const;
+ void setFront(QGLMaterial *material);
+
+ QGLMaterial *back() const;
+ void setBack(QGLMaterial *material);
+
+ bool isTransparent() const;
+ void bind(QGLPainter *painter);
+ void release(QGLPainter *painter, QGLAbstractMaterial *next);
+ void prepareToDraw(QGLPainter *painter, const QGLAttributeSet &attributes);
+
+Q_SIGNALS:
+ void frontChanged();
+ void backChanged();
+
+private:
+ QScopedPointer<QGLTwoSidedMaterialPrivate> d_ptr;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif