summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Harmer <sean.harmer@kdab.com>2014-02-07 15:14:56 +0000
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2014-02-10 11:58:22 +0100
commitf653515003a8e4c1dae5ba93afd0a6e72e9783cc (patch)
tree21d82c45963a743306ada0f124c310e611fc9dfa
parent4cce3d37ebd35df207ff8dae6f53c576b156202c (diff)
Initial import of Qt3DCore and Renderer aspect
For now the renderer aspect is still compiled into the Qt3DCore library. This needs to be split out into a plugin so it can be loaded dynamically along with other future aspects. Change-Id: Iba8402b35c7ebc1c503d438c87aad77f5fef2261 Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
-rw-r--r--src/core/abstractaspect.cpp84
-rw-r--r--src/core/abstractaspect.h104
-rw-r--r--src/core/abstracttransform.cpp55
-rw-r--r--src/core/abstracttransform.h64
-rw-r--r--src/core/axisalignedboundingbox.cpp86
-rw-r--r--src/core/axisalignedboundingbox.h157
-rw-r--r--src/core/bounds.cpp61
-rw-r--r--src/core/bounds.h67
-rw-r--r--src/core/cameracontroller.cpp292
-rw-r--r--src/core/cameracontroller.h134
-rw-r--r--src/core/component.cpp65
-rw-r--r--src/core/component.h69
-rw-r--r--src/core/core.pri56
-rw-r--r--src/core/core.pro27
-rw-r--r--src/core/entity.cpp232
-rw-r--r--src/core/entity.h162
-rw-r--r--src/core/lookattransform.cpp112
-rw-r--r--src/core/lookattransform.h93
-rw-r--r--src/core/matrixtransform.cpp60
-rw-r--r--src/core/matrixtransform.h66
-rw-r--r--src/core/node.cpp228
-rw-r--r--src/core/node.h103
-rw-r--r--src/core/nodevisitor.cpp129
-rw-r--r--src/core/nodevisitor.h90
-rw-r--r--src/core/qaspectengine.cpp88
-rw-r--r--src/core/qaspectengine.h80
-rw-r--r--src/core/qaspectmanager.cpp191
-rw-r--r--src/core/qaspectmanager.h92
-rw-r--r--src/core/qaspectscheduler.cpp54
-rw-r--r--src/core/qaspectscheduler.h60
-rw-r--r--src/core/qaspectthread.cpp92
-rw-r--r--src/core/qaspectthread.h76
-rw-r--r--src/core/qchangearbiter.cpp249
-rw-r--r--src/core/qchangearbiter.h232
-rw-r--r--src/core/qjob.cpp59
-rw-r--r--src/core/qjob.h71
-rw-r--r--src/core/qjobmanagerinterface.h70
-rw-r--r--src/core/qjobproviderinterface.h60
-rw-r--r--src/core/qscheduler.cpp92
-rw-r--r--src/core/qscheduler.h69
-rw-r--r--src/core/qt3dcore_global.h53
-rw-r--r--src/core/qtickclock.cpp106
-rw-r--r--src/core/qtickclock.h73
-rw-r--r--src/core/rotatetransform.cpp98
-rw-r--r--src/core/rotatetransform.h91
-rw-r--r--src/core/scene.cpp134
-rw-r--r--src/core/scene.h96
-rw-r--r--src/core/sphere.cpp175
-rw-r--r--src/core/sphere.h138
-rw-r--r--src/core/translatetransform.cpp110
-rw-r--r--src/core/translatetransform.h88
-rw-r--r--src/core/window.cpp249
-rw-r--r--src/core/window.h115
-rw-r--r--src/render/backend/drawable.cpp79
-rw-r--r--src/render/backend/drawable.h103
-rw-r--r--src/render/backend/drawstate.cpp182
-rw-r--r--src/render/backend/drawstate.h121
-rw-r--r--src/render/backend/framegraph/cameraselectornode.cpp65
-rw-r--r--src/render/backend/framegraph/cameraselectornode.h68
-rw-r--r--src/render/backend/framegraph/framegraph.pri15
-rw-r--r--src/render/backend/framegraph/framegraphnode.cpp72
-rw-r--r--src/render/backend/framegraph/framegraphnode.h80
-rw-r--r--src/render/backend/framegraph/framegraphvisitor.cpp86
-rw-r--r--src/render/backend/framegraph/framegraphvisitor.h67
-rw-r--r--src/render/backend/framegraph/renderpassfilternode.cpp65
-rw-r--r--src/render/backend/framegraph/renderpassfilternode.h68
-rw-r--r--src/render/backend/framegraph/techniquefilternode.cpp65
-rw-r--r--src/render/backend/framegraph/techniquefilternode.h69
-rw-r--r--src/render/backend/framegraph/viewportnode.cpp69
-rw-r--r--src/render/backend/framegraph/viewportnode.h68
-rw-r--r--src/render/backend/genericstate.h114
-rw-r--r--src/render/backend/jobs/jobs.pri11
-rw-r--r--src/render/backend/jobs/loadmeshdatajob.cpp89
-rw-r--r--src/render/backend/jobs/loadmeshdatajob.h73
-rw-r--r--src/render/backend/jobs/updateboundingvolumejob.cpp105
-rw-r--r--src/render/backend/jobs/updateboundingvolumejob.h71
-rw-r--r--src/render/backend/jobs/updateworldtransformjob.cpp88
-rw-r--r--src/render/backend/jobs/updateworldtransformjob.h71
-rw-r--r--src/render/backend/meshmanager.cpp64
-rw-r--r--src/render/backend/meshmanager.h81
-rw-r--r--src/render/backend/qgraphicscontext.cpp466
-rw-r--r--src/render/backend/qgraphicscontext.h177
-rw-r--r--src/render/backend/quniformvalue.cpp306
-rw-r--r--src/render/backend/quniformvalue.h142
-rw-r--r--src/render/backend/render-backend.pri52
-rw-r--r--src/render/backend/renderbin.cpp204
-rw-r--r--src/render/backend/renderbin.h94
-rw-r--r--src/render/backend/rendercamera.cpp121
-rw-r--r--src/render/backend/rendercamera.h96
-rw-r--r--src/render/backend/renderconfiguration.cpp52
-rw-r--r--src/render/backend/renderconfiguration.h57
-rw-r--r--src/render/backend/renderdevice.cpp52
-rw-r--r--src/render/backend/renderdevice.h57
-rw-r--r--src/render/backend/renderer.cpp524
-rw-r--r--src/render/backend/renderer.h171
-rw-r--r--src/render/backend/rendereraspect.cpp129
-rw-r--r--src/render/backend/rendereraspect.h78
-rw-r--r--src/render/backend/rendermaterial.cpp204
-rw-r--r--src/render/backend/rendermaterial.h102
-rw-r--r--src/render/backend/rendermesh.cpp333
-rw-r--r--src/render/backend/rendermesh.h125
-rw-r--r--src/render/backend/rendernode.cpp108
-rw-r--r--src/render/backend/rendernode.h90
-rw-r--r--src/render/backend/renderscenebuilder.cpp111
-rw-r--r--src/render/backend/renderscenebuilder.h75
-rw-r--r--src/render/backend/rendershader.cpp150
-rw-r--r--src/render/backend/rendershader.h103
-rw-r--r--src/render/backend/rendertechnique.cpp156
-rw-r--r--src/render/backend/rendertechnique.h94
-rw-r--r--src/render/backend/rendertexture.cpp149
-rw-r--r--src/render/backend/rendertexture.h72
-rw-r--r--src/render/backend/rendertextureprovider.cpp63
-rw-r--r--src/render/backend/rendertextureprovider.h67
-rw-r--r--src/render/backend/renderthread.cpp84
-rw-r--r--src/render/backend/renderthread.h80
-rw-r--r--src/render/backend/states/blendstate.cpp197
-rw-r--r--src/render/backend/states/blendstate.h153
-rw-r--r--src/render/frontend/camera.cpp483
-rw-r--r--src/render/frontend/camera.h184
-rw-r--r--src/render/frontend/camera_p.h129
-rw-r--r--src/render/frontend/cameraselector.cpp65
-rw-r--r--src/render/frontend/cameraselector.h73
-rw-r--r--src/render/frontend/effect.cpp81
-rw-r--r--src/render/frontend/effect.h82
-rw-r--r--src/render/frontend/material.cpp157
-rw-r--r--src/render/frontend/material.h108
-rw-r--r--src/render/frontend/mesh.cpp129
-rw-r--r--src/render/frontend/mesh.h83
-rw-r--r--src/render/frontend/qitemmodelbuffer.cpp289
-rw-r--r--src/render/frontend/qitemmodelbuffer.h103
-rw-r--r--src/render/frontend/render-frontend.pri37
-rw-r--r--src/render/frontend/renderpass.cpp120
-rw-r--r--src/render/frontend/renderpass.h104
-rw-r--r--src/render/frontend/renderpassfilter.cpp64
-rw-r--r--src/render/frontend/renderpassfilter.h73
-rw-r--r--src/render/frontend/shaderprogram.cpp133
-rw-r--r--src/render/frontend/shaderprogram.h92
-rw-r--r--src/render/frontend/shape.cpp386
-rw-r--r--src/render/frontend/shape.h118
-rw-r--r--src/render/frontend/tag.h97
-rw-r--r--src/render/frontend/technique.cpp281
-rw-r--r--src/render/frontend/technique.h194
-rw-r--r--src/render/frontend/techniquefilter.cpp95
-rw-r--r--src/render/frontend/techniquefilter.h80
-rw-r--r--src/render/frontend/texture.cpp101
-rw-r--r--src/render/frontend/texture.h86
-rw-r--r--src/render/frontend/transform.cpp147
-rw-r--r--src/render/frontend/transform.h94
-rw-r--r--src/render/frontend/viewport.cpp64
-rw-r--r--src/render/frontend/viewport.h76
-rw-r--r--src/render/io/gltfparser.cpp842
-rw-r--r--src/render/io/gltfparser.h157
-rw-r--r--src/render/io/meshdata.cpp422
-rw-r--r--src/render/io/meshdata.h181
-rw-r--r--src/render/io/objloader.cpp442
-rw-r--r--src/render/io/objloader.h143
-rw-r--r--src/render/io/render-io.pri13
-rw-r--r--src/render/io/texturedata.cpp167
-rw-r--r--src/render/io/texturedata.h164
-rw-r--r--src/render/render.pri3
-rw-r--r--src/src.pro6
-rw-r--r--sync.profile1
162 files changed, 20107 insertions, 2 deletions
diff --git a/src/core/abstractaspect.cpp b/src/core/abstractaspect.cpp
new file mode 100644
index 000000000..3096aa58f
--- /dev/null
+++ b/src/core/abstractaspect.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstractaspect.h"
+
+namespace Qt3D {
+
+AbstractAspect::AbstractAspect(AspectType aspectType, QObject *parent)
+ : QObject(parent)
+ , m_aspectType(aspectType)
+{
+}
+
+void AbstractAspect::registerAspect(Node *rootObject)
+{
+ if (rootObject == m_root)
+ return;
+
+ m_root = rootObject;
+ registerAspectHelper(rootObject);
+}
+
+void AbstractAspect::unregisterAspect(Node *rootObject)
+{
+ unregisterAspectHelper(rootObject);
+ m_root = rootObject;
+}
+
+void AbstractAspect::initialize(QAspectManager *aspectManager)
+{
+ m_aspectManager = aspectManager;
+ initializeHelper(aspectManager);
+}
+
+void AbstractAspect::cleanup()
+{
+ cleanupHelper();
+}
+
+void AbstractAspect::setWindow(QWindow *win)
+{
+ Q_UNUSED(win);
+}
+
+} // of namespace Qt3D
+
diff --git a/src/core/abstractaspect.h b/src/core/abstractaspect.h
new file mode 100644
index 000000000..7dd555b32
--- /dev/null
+++ b/src/core/abstractaspect.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ABSTRACTASPECT_H
+#define ABSTRACTASPECT_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include "qjobproviderinterface.h"
+
+#include <QSharedPointer>
+
+// forward decls
+class QWindow;
+
+namespace Qt3D {
+
+class QAspectManager;
+class Node;
+
+class QT3DCORESHARED_EXPORT AbstractAspect : public QObject, public QJobProviderInterface
+{
+ Q_OBJECT
+
+public:
+ enum AspectType {
+ AspectRenderer,
+ AspectAnimation,
+ AspectCollision,
+ AspectPhysics,
+ AspectPhysicsAndCollision,
+ AspectAI,
+ AspectAudio,
+ AspectOther
+ };
+
+ explicit AbstractAspect(AspectType aspectType, QObject *parent = 0);
+
+ AspectType aspectType() const { return m_aspectType; }
+ QAspectManager *aspectManager() const { return m_aspectManager; }
+
+ void registerAspect(Node *rootObject);
+ void unregisterAspect(Node *rootObject);
+
+ void initialize(QAspectManager *aspectManager);
+ void cleanup();
+
+ virtual void setWindow(QWindow* win);
+
+protected:
+ virtual void registerAspectHelper(Node *rootObject) = 0;
+ virtual void unregisterAspectHelper(Node *rootObject) = 0;
+
+ virtual void initializeHelper(QAspectManager *aspectManager) = 0;
+ virtual void cleanupHelper() = 0;
+
+private:
+ QAspectManager *m_aspectManager;
+ Node *m_root;
+ AspectType m_aspectType;
+};
+
+}
+
+#endif // ABSTRACTASPECT_H
diff --git a/src/core/abstracttransform.cpp b/src/core/abstracttransform.cpp
new file mode 100644
index 000000000..a7a892259
--- /dev/null
+++ b/src/core/abstracttransform.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "abstracttransform.h"
+
+namespace Qt3D {
+
+AbstractTransform::AbstractTransform(Node *parent)
+ : Node(parent)
+{
+}
+
+AbstractTransform::~AbstractTransform()
+{
+}
+
+} // of namespace Qt3D
diff --git a/src/core/abstracttransform.h b/src/core/abstracttransform.h
new file mode 100644
index 000000000..1715bd70c
--- /dev/null
+++ b/src/core/abstracttransform.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_ABSTRACT_TRANSFORM_H
+#define QT3D_ABSTRACT_TRANSFORM_H
+
+#include <node.h>
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+
+namespace Qt3D {
+
+class AbstractTransform : public Node
+{
+ Q_OBJECT
+public:
+ explicit AbstractTransform(Node *parent = 0);
+ virtual ~AbstractTransform();
+
+ virtual QMatrix4x4 matrix() const = 0;
+};
+
+} // of namespace Qt3D
+
+#endif // of QT3D_ABSTRACT_TRANSFORM_H
diff --git a/src/core/axisalignedboundingbox.cpp b/src/core/axisalignedboundingbox.cpp
new file mode 100644
index 000000000..8ee394127
--- /dev/null
+++ b/src/core/axisalignedboundingbox.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "axisalignedboundingbox.h"
+
+#include <QDebug>
+#include <QMatrix4x4>
+
+namespace Qt3D {
+
+void AxisAlignedBoundingBox::update(const QVector<QVector3D> &points)
+{
+ QVector3D minPoint, maxPoint;
+ for (int i = 0; i < points.size(); ++i)
+ {
+ const QVector3D &point = points.at(i);
+ if (point.x() > maxPoint.x())
+ maxPoint.setX(point.x());
+ if (point.y() > maxPoint.y())
+ maxPoint.setY(point.y());
+ if (point.z() > maxPoint.z())
+ maxPoint.setZ(point.z());
+ if (point.x() < minPoint.x())
+ minPoint.setX(point.x());
+ if (point.y() < minPoint.y())
+ minPoint.setY(point.y());
+ if (point.z() < minPoint.z())
+ minPoint.setZ(point.z());
+ }
+
+ m_center = 0.5 * (minPoint + maxPoint);
+ m_radii = 0.5 * (maxPoint - minPoint);
+#if 0
+ qDebug() << "AABB:";
+ qDebug() << " min =" << minPoint;
+ qDebug() << " max =" << maxPoint;
+ qDebug() << " center =" << m_center;
+ qDebug() << " radii =" << m_radii;
+#endif
+}
+
+QDebug operator<<(QDebug dbg, const AxisAlignedBoundingBox &c)
+{
+ dbg.nospace() << "AABB ( min:" << c.minPoint() << ", max:" << c.maxPoint() << ")";
+ return dbg.space();
+}
+
+}
diff --git a/src/core/axisalignedboundingbox.h b/src/core/axisalignedboundingbox.h
new file mode 100644
index 000000000..e16dda1a8
--- /dev/null
+++ b/src/core/axisalignedboundingbox.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef AXIS_ALIGNED_BOUNDING_BOX
+#define AXIS_ALIGNED_BOUNDING_BOX
+
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+#include <QVector>
+#include <QVector3D>
+
+// forward decls
+class QDebug;
+
+namespace Qt3D {
+
+class AxisAlignedBoundingBox
+{
+public:
+ inline AxisAlignedBoundingBox()
+ : m_center(),
+ m_radii()
+ {}
+
+ inline explicit AxisAlignedBoundingBox(const QVector<QVector3D> &points)
+ : m_center(),
+ m_radii()
+ {
+ update(points);
+ }
+
+ void clear()
+ {
+ m_center = QVector3D();
+ m_radii = QVector3D();
+ }
+
+ void update(const QVector<QVector3D> &points);
+
+ inline QVector3D center() const { return m_center; }
+ inline QVector3D radii() const { return m_radii; }
+
+ inline QVector3D minPoint() const { return m_center - m_radii; }
+ inline QVector3D maxPoint() const { return m_center + m_radii; }
+
+ inline float xExtent() const { return 2.0f * m_radii.x(); }
+ inline float yExtent() const { return 2.0f * m_radii.y(); }
+ inline float zExtent() const { return 2.0f * m_radii.z(); }
+
+ inline float maxExtent() const { return qMax( xExtent(), qMax( yExtent(), zExtent() ) ); }
+ inline float minExtent() const { return qMin( xExtent(), qMin( yExtent(), zExtent() ) ); }
+
+ inline bool contains( const QVector3D& pt ) const
+ {
+ QVector3D minP(minPoint()), maxP(maxPoint());
+ if ((pt.x() < minP.x()) || (pt.x() > maxP.x()) ||
+ (pt.y() < minP.y()) || (pt.y() > maxP.y()) ||
+ (pt.z() < minP.z()) || (pt.z() > maxP.z()) )
+ {
+ return false;
+ }
+ return true;
+ }
+
+ inline void expandToContain(const QVector3D &pt)
+ {
+ QVector<QVector3D> pts = QVector<QVector3D>() << pt;
+ update(pts);
+ }
+
+ inline void expandToContain(const AxisAlignedBoundingBox &other)
+ {
+ QVector<QVector3D> pts = QVector<QVector3D>() << other.minPoint() << other.maxPoint();
+ update(pts);
+ }
+
+ inline AxisAlignedBoundingBox transformBy(const QMatrix4x4 &mat) const
+ {
+ AxisAlignedBoundingBox r;
+ r.m_center = mat.map(m_center);
+ r.m_radii = mat.map(m_radii);
+ return r;
+ }
+
+ inline AxisAlignedBoundingBox &transform(const QMatrix4x4 &mat)
+ {
+ m_center = mat.map(m_center);
+ m_radii = mat.map(m_radii);
+ return *this;
+ }
+
+private:
+ QVector3D m_center;
+ QVector3D m_radii;
+
+ friend bool intersects(const AxisAlignedBoundingBox &a,
+ const AxisAlignedBoundingBox &b);
+};
+
+QDebug operator<<(QDebug dbg, const AxisAlignedBoundingBox &c);
+
+inline bool intersects(const AxisAlignedBoundingBox &a,
+ const AxisAlignedBoundingBox &b)
+{
+ // Test y axis last as this is often the least discriminatory in OpenGL applications
+ // where worlds tend to be mostly in the xz-plane
+ if (qAbs(a.m_center[0] - b.m_center[0]) > a.m_radii[0] + b.m_radii[0])
+ return false;
+ if (qAbs(a.m_center[2] - b.m_center[2]) > a.m_radii[2] + b.m_radii[2])
+ return false;
+ if (qAbs(a.m_center[1] - b.m_center[1]) > a.m_radii[1] + b.m_radii[1])
+ return false;
+ return true;
+}
+
+}
+
+#endif // AXIS_ALIGNED_BOUNDING_BOX
diff --git a/src/core/bounds.cpp b/src/core/bounds.cpp
new file mode 100644
index 000000000..89db913ae
--- /dev/null
+++ b/src/core/bounds.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bounds.h"
+
+namespace Qt3D {
+
+Bounds::Bounds(QObject *parent) :
+ QObject(parent)
+{
+}
+
+AxisAlignedBoundingBox Bounds::box() const
+{
+ return m_box;
+}
+
+void Bounds::setBox( const AxisAlignedBoundingBox& aabb )
+{
+ m_box = aabb;
+}
+
+}
diff --git a/src/core/bounds.h b/src/core/bounds.h
new file mode 100644
index 000000000..cf59d7776
--- /dev/null
+++ b/src/core/bounds.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOUNDS_H
+#define BOUNDS_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include "axisalignedboundingbox.h"
+
+namespace Qt3D {
+
+class Bounds : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Bounds(QObject *parent = 0);
+
+ AxisAlignedBoundingBox box() const;
+ void setBox( const AxisAlignedBoundingBox& aabb );
+
+private:
+ AxisAlignedBoundingBox m_box;
+};
+
+}
+
+#endif // BOUNDS_H
diff --git a/src/core/cameracontroller.cpp b/src/core/cameracontroller.cpp
new file mode 100644
index 000000000..10d1aa386
--- /dev/null
+++ b/src/core/cameracontroller.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cameracontroller.h"
+
+#include <QMouseEvent>
+#include <QKeyEvent>
+
+#include "camera.h"
+#include "entity.h"
+#include "matrixtransform.h"
+
+namespace Qt3D
+{
+
+CameraController::CameraController() :
+ m_camera( 0 ),
+ m_vx( 0.0f ),
+ m_vy( 0.0f ),
+ m_vz( 0.0f ),
+ m_viewCenterFixed( false ),
+ m_panAngle( 0.0f ),
+ m_tiltAngle( 0.0f ),
+ m_leftButtonPressed( false ),
+ m_orbitMode( false ),
+ m_linearSpeed( 40.0f ),
+ m_time( 0.0f ),
+ m_orbitRate( -1.0f ),
+ m_lookRate( 0.1f ),
+ m_translateFast( false ),
+ m_multisampleEnabled( true )
+{
+}
+
+void CameraController::setCamera( Camera* cam )
+{
+ m_camera = cam;
+ m_camera->setPerspectiveProjection( 25.0, 1.0, 0.1, 1000 );
+
+ Entity* cameraEntity = cam->parentNode()->asEntity();
+ Q_ASSERT(cameraEntity);
+ m_cameraEntity = cameraEntity;
+}
+
+void CameraController::setLinearSpeed( float speed )
+{
+ if ( qFuzzyCompare( m_linearSpeed, speed ) )
+ return;
+ m_linearSpeed = speed;
+ emit linearSpeedChanged();
+}
+
+float CameraController::linearSpeed() const
+{
+ return m_linearSpeed;
+}
+
+float CameraController::orbitRate() const
+{
+ return m_orbitRate;
+}
+
+void CameraController::setOrbitRate( float rate )
+{
+ if ( qFuzzyCompare( m_orbitRate, rate ) )
+ return;
+ m_orbitRate = rate;
+ emit orbitRateChanged();
+}
+
+float CameraController::lookRate() const
+{
+ return m_lookRate;
+}
+
+void CameraController::setLookRate( float rate )
+{
+ if ( qFuzzyCompare( m_lookRate, rate ) )
+ return;
+ m_lookRate = rate;
+ emit lookRateChanged();
+}
+
+void CameraController::update(double dt)
+{
+ if ( !m_camera )
+ return;
+
+ if (m_translateFast)
+ dt *= 10;
+
+ // Update the camera position and orientation
+ Camera::CameraTranslationOption option = m_viewCenterFixed
+ ? Camera::DontTranslateViewCenter
+ : Camera::TranslateViewCenter;
+ m_camera->translate(dt * QVector3D(m_vx, m_vy, m_vz), option);
+
+ m_cameraEntity->setMatrix(m_camera->viewMatrix().inverted());
+
+ if (!qFuzzyIsNull(m_panAngle)) {
+ m_camera->pan(m_panAngle);
+ m_panAngle = 0.0f;
+ }
+
+ if (!qFuzzyIsNull(m_tiltAngle)) {
+ m_camera->tilt(m_tiltAngle);
+ m_tiltAngle = 0.0f;
+ }
+}
+
+bool CameraController::keyPressEvent( QKeyEvent* e )
+{
+ switch ( e->key() )
+ {
+ case Qt::Key_Right:
+ m_vx = m_linearSpeed;
+ break;
+
+ case Qt::Key_Left:
+ m_vx = -m_linearSpeed;
+ break;
+
+ case Qt::Key_Up:
+ m_vz = m_linearSpeed;
+ break;
+
+ case Qt::Key_Down:
+ m_vz = -m_linearSpeed;
+ break;
+
+ case Qt::Key_PageUp:
+ m_vy = m_linearSpeed;
+ break;
+
+ case Qt::Key_PageDown:
+ m_vy = -m_linearSpeed;
+ break;
+
+ case Qt::Key_Shift:
+ m_viewCenterFixed = true;
+ break;
+
+ case Qt::Key_Alt:
+ m_translateFast = true;
+ break;
+
+ case Qt::Key_A:
+ toggleMSAA();
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool CameraController::keyReleaseEvent( QKeyEvent* e )
+{
+ switch ( e->key() )
+ {
+ case Qt::Key_Right:
+ case Qt::Key_Left:
+ m_vx = 0.0;
+ break;
+
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ m_vz = 0.0;
+ break;
+
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ m_vy = 0.0;
+ break;
+
+ case Qt::Key_Shift:
+ m_viewCenterFixed = false;
+ break;
+
+ case Qt::Key_Alt:
+ m_translateFast = false;
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void CameraController::mousePressEvent( QMouseEvent* e )
+{
+ if ( e->button() == Qt::LeftButton )
+ {
+ m_leftButtonPressed = true;
+ m_pos = m_prevPos = e->pos();
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ m_orbitMode = true;
+ m_pos = m_prevPos = e->pos();
+ }
+}
+
+void CameraController::mouseReleaseEvent( QMouseEvent* e )
+{
+ if ( e->button() == Qt::LeftButton )
+ {
+ m_leftButtonPressed = false;
+ }
+ else if ( e->button() == Qt::RightButton )
+ {
+ m_orbitMode = false;
+ }
+}
+
+void CameraController::mouseMoveEvent( QMouseEvent* e )
+{
+ if (!m_camera )
+ return;
+
+ if (!m_leftButtonPressed && !m_orbitMode)
+ return;
+
+ m_pos = e->pos();
+ float dx = m_pos.x() - m_prevPos.x();
+ float dy = m_pos.y() - m_prevPos.y();
+ m_prevPos = m_pos;
+
+ if ( m_leftButtonPressed )
+ {
+ m_camera->pan( dx * m_lookRate );
+ m_camera->tilt( dy * m_lookRate );
+ }
+ else if ( m_orbitMode )
+ {
+ m_camera->panAboutViewCenter( dx * m_orbitRate );
+ m_camera->tiltAboutViewCenter( dy * m_orbitRate );
+ }
+}
+
+bool CameraController::isMultisampleEnabled() const
+{
+ return m_multisampleEnabled;
+}
+
+void CameraController::toggleMSAA()
+{
+ m_multisampleEnabled = !m_multisampleEnabled;
+ emit multisampleEnabledChanged();
+}
+
+} // of namespace Qt3D
diff --git a/src/core/cameracontroller.h b/src/core/cameracontroller.h
new file mode 100644
index 000000000..28a9ec6cd
--- /dev/null
+++ b/src/core/cameracontroller.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CAMERA_CONTROLLER_H
+#define CAMERA_CONTROLLER_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include <QPoint>
+
+class QMouseEvent;
+class QWheelEvent;
+class QKeyEvent;
+
+
+namespace Qt3D
+{
+
+class Camera;
+class Entity;
+
+class CameraController : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY( float linearSpeed READ linearSpeed WRITE setLinearSpeed NOTIFY linearSpeedChanged )
+
+ Q_PROPERTY( float orbitRate READ orbitRate WRITE setOrbitRate NOTIFY orbitRateChanged )
+ Q_PROPERTY( float lookRate READ lookRate WRITE setLookRate NOTIFY lookRateChanged )
+
+ Q_PROPERTY( bool multisampleEnabled READ isMultisampleEnabled() NOTIFY multisampleEnabledChanged )
+public:
+ CameraController();
+
+ void setCamera( Camera* cam );
+ void setLinearSpeed( float speed );
+ float linearSpeed() const;
+
+ float orbitRate() const;
+ void setOrbitRate( float rate );
+
+ float lookRate() const;
+ void setLookRate( float rate );
+
+ void mousePressEvent( QMouseEvent* aEvent );
+ void mouseReleaseEvent( QMouseEvent* aEvent );
+ void mouseMoveEvent( QMouseEvent* aEvent );
+
+ bool keyPressEvent( QKeyEvent* aEvent );
+ bool keyReleaseEvent( QKeyEvent* aEvent );
+
+ bool handleScroll( QWheelEvent* aWheel );
+
+ void update( double t );
+
+ bool isMultisampleEnabled() const;
+public slots:
+ void toggleMSAA();
+
+
+
+signals:
+ void linearSpeedChanged();
+ void orbitRateChanged();
+ void lookRateChanged();
+
+ void multisampleEnabledChanged();
+private:
+
+ Camera* m_camera;
+ Entity* m_cameraEntity;
+
+ float m_vx;
+ float m_vy;
+ float m_vz;
+ bool m_viewCenterFixed;
+ float m_panAngle;
+ float m_tiltAngle;
+
+ bool m_leftButtonPressed;
+ QPoint m_prevPos;
+ QPoint m_pos;
+ bool m_orbitMode;
+
+ float m_linearSpeed;
+ float m_time;
+ float m_orbitRate;
+ float m_lookRate;
+
+ bool m_translateFast;
+ bool m_multisampleEnabled;
+};
+
+} // of namespace Qt3D
+
+#endif // of CAMERA_CONTROLLER_H
diff --git a/src/core/component.cpp b/src/core/component.cpp
new file mode 100644
index 000000000..9f5e3a26c
--- /dev/null
+++ b/src/core/component.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "component.h"
+
+namespace Qt3D {
+
+Component::Component(Node *parent)
+ : Node(parent)
+ , m_changeArbiter(0)
+{
+}
+
+void Component::registerChangeArbiter(QChangeArbiter *changeArbiter)
+{
+ Q_CHECK_PTR(changeArbiter);
+ m_changeArbiter = changeArbiter;
+}
+
+void Component::notifySceneChange(const QSceneChangePtr &change)
+{
+ Q_CHECK_PTR(change);
+ if (m_changeArbiter)
+ m_changeArbiter->sceneChangeEventWithLock(change);
+}
+
+} // namespace Qt3D
diff --git a/src/core/component.h b/src/core/component.h
new file mode 100644
index 000000000..608015e95
--- /dev/null
+++ b/src/core/component.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_COMPONENT_H
+#define QT3D_COMPONENT_H
+
+#include "node.h"
+#include "qt3dcore_global.h"
+
+#include <qchangearbiter.h>
+
+namespace Qt3D {
+
+class Component : public Node
+{
+ Q_OBJECT
+public:
+ explicit Component(Node *parent = 0);
+
+ void registerChangeArbiter(QChangeArbiter *changeArbiter);
+
+protected:
+ virtual void notifySceneChange(const QSceneChangePtr &change);
+
+private:
+ QChangeArbiter *m_changeArbiter;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_COMPONENT_H
diff --git a/src/core/core.pri b/src/core/core.pri
new file mode 100644
index 000000000..5f062c585
--- /dev/null
+++ b/src/core/core.pri
@@ -0,0 +1,56 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/qt3dcore_global.h \
+ $$PWD/abstractaspect.h \
+ $$PWD/node.h \
+ $$PWD/nodevisitor.h \
+ $$PWD/abstracttransform.h \
+ $$PWD/matrixtransform.h \
+ $$PWD/axisalignedboundingbox.h \
+ $$PWD/sphere.h \
+ $$PWD/bounds.h \
+ $$PWD/component.h \
+ $$PWD/window.h \
+ $$PWD/qaspectengine.h \
+ $$PWD/qaspectscheduler.h \
+ $$PWD/qaspectthread.h \
+ $$PWD/qaspectmanager.h \
+ $$PWD/qtickclock.h \
+ $$PWD/entity.h \
+ $$PWD/scene.h \
+ $$PWD/qjob.h \
+ $$PWD/qjobmanagerinterface.h \
+ $$PWD/qscheduler.h \
+ $$PWD/qjobproviderinterface.h \
+ $$PWD/cameracontroller.h \
+ $$PWD/translatetransform.h \
+ $$PWD/rotatetransform.h \
+ $$PWD/qchangearbiter.h \
+ $$PWD/lookattransform.h
+
+SOURCES += \
+ $$PWD/abstractaspect.cpp \
+ $$PWD/node.cpp \
+ $$PWD/nodevisitor.cpp \
+ $$PWD/abstracttransform.cpp \
+ $$PWD/matrixtransform.cpp \
+ $$PWD/axisalignedboundingbox.cpp \
+ $$PWD/sphere.cpp \
+ $$PWD/bounds.cpp \
+ $$PWD/component.cpp \
+ $$PWD/window.cpp \
+ $$PWD/qaspectengine.cpp \
+ $$PWD/qaspectscheduler.cpp \
+ $$PWD/qaspectthread.cpp \
+ $$PWD/qaspectmanager.cpp \
+ $$PWD/qtickclock.cpp \
+ $$PWD/entity.cpp \
+ $$PWD/scene.cpp \
+ $$PWD/qjob.cpp \
+ $$PWD/qscheduler.cpp \
+ $$PWD/cameracontroller.cpp \
+ $$PWD/translatetransform.cpp \
+ $$PWD/rotatetransform.cpp \
+ $$PWD/qchangearbiter.cpp \
+ $$PWD/lookattransform.cpp
diff --git a/src/core/core.pro b/src/core/core.pro
new file mode 100644
index 000000000..c599bbdba
--- /dev/null
+++ b/src/core/core.pro
@@ -0,0 +1,27 @@
+TARGET = Qt3DCore
+MODULE = 3dcore
+QT = core-private gui-private qml qml-private quick
+
+load(qt_module)
+
+DEFINES += QT3DCORE_LIBRARY
+
+#QMAKE_DOCS = $$PWD/doc/qt3d.qdocconf
+
+gcov {
+ CONFIG += static
+ QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage
+ QMAKE_LFLAGS += -fprofile-arcs -ftest-coverage
+} else {
+ CONFIG += dll
+}
+
+# otherwise mingw headers do not declare common functions like ::strcasecmp
+win32-g++*:QMAKE_CXXFLAGS_CXX11 = -std=gnu++0x
+
+include(core.pri)
+include(../render/render.pri)
+PUBLIC_HEADERS = $$HEADERS
+HEADERS += $$PRIVATE_HEADERS
+
+!contains(QT_CONFIG, egl):DEFINES += QT_NO_EGL
diff --git a/src/core/entity.cpp b/src/core/entity.cpp
new file mode 100644
index 000000000..136778216
--- /dev/null
+++ b/src/core/entity.cpp
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "entity.h"
+
+#include "component.h"
+#include "abstracttransform.h"
+#include "matrixtransform.h"
+
+#include <QMetaObject>
+#include <QMetaProperty>
+#include <QDebug>
+
+namespace Qt3D {
+
+Entity::Entity(Node *parent)
+ : Node(parent)
+ , m_enabled(true)
+{
+}
+
+QQmlListProperty<AbstractTransform> Entity::transformList()
+{
+ return QQmlListProperty<AbstractTransform>(this, 0,
+ Entity::qmlAppendTransform,
+ Entity::transformCount,
+ Entity::transformAt,
+ Entity::qmlClearTransforms);
+}
+
+QList<Component *> Entity::components() const
+{
+ // Construct the list of components by looking for all properties that
+ // inherit from Component
+ QList<Component *> componentList;
+ const QMetaObject *meta = metaObject();
+ for (int i = 0; i < meta->propertyCount(); ++i) {
+ const QMetaProperty metaProperty = meta->property(i);
+ const QVariant value = property(metaProperty.name());
+ Component *component = value.value<Component *>();
+ if (component)
+ componentList.append(component);
+ }
+
+ return componentList + m_components;
+}
+
+void Entity::addComponent(Component *comp)
+{
+ Q_CHECK_PTR( comp );
+ Q_ASSERT(m_components.count(comp) == 0);
+ comp->setParent(this);
+ m_components.append(comp);
+}
+
+void Entity::removeComponent(Component *comp)
+{
+ Q_CHECK_PTR(comp);
+ m_components.removeOne(comp);
+}
+
+bool Entity::isEnabled() const
+{
+ return m_enabled;
+}
+
+void Entity::setEnabled(bool on)
+{
+ if (m_enabled != on) {
+ m_enabled = on;
+ emit enabledChanged();
+ }
+}
+
+QMatrix4x4 Entity::matrix() const
+{
+ if (m_transformsDirty) {
+ m_matrix = applyTransforms();
+ m_transformsDirty = false;
+ }
+ return m_matrix;
+}
+
+void Entity::update()
+{
+ if (m_transformsDirty) {
+ m_matrix = applyTransforms();
+ m_transformsDirty = false;
+ }
+
+ QMatrix4x4 prM;
+ if (parentEntity())
+ prM = parentEntity()->sceneMatrix();
+
+ m_sceneMatrix = prM * matrix();
+ // invalidate bounding volume information as required
+}
+
+void Entity::setMatrix(const QMatrix4x4 &m)
+{
+ qDeleteAll(m_transforms);
+ m_transforms.clear();
+ appendTransfrom(new MatrixTransform(m));
+}
+
+/*!
+ The combined transform relative to the root of the scene
+*/
+QMatrix4x4 Entity::sceneMatrix() const
+{
+ return m_sceneMatrix;
+}
+
+/*!
+ The center of rotation for the entity. Defaults to the local origin.
+*/
+QVector3D Entity::rotationCenter() const
+{
+ return QVector3D();
+}
+
+QList<AbstractTransform *> Entity::transforms() const
+{
+ return m_transforms;
+}
+
+void setRotationCenter(const QVector3D &rc)
+{
+ Q_UNUSED(rc);
+}
+
+void Entity::appendTransfrom(AbstractTransform *xform)
+{
+ m_transformsDirty = true;
+ m_transforms.append( xform );
+}
+
+void Entity::removeTransform(AbstractTransform *xform)
+{
+ m_transformsDirty = true;
+ m_transforms.removeOne( xform );
+}
+
+Entity *Entity::asEntity()
+{
+ return this;
+}
+
+Entity *Entity::parentEntity()
+{
+ return qobject_cast<Entity*>(parent());
+}
+
+QMatrix4x4 Entity::applyTransforms() const
+{
+ QMatrix4x4 m;
+ m.setToIdentity();
+ Q_FOREACH (AbstractTransform *t, m_transforms)
+ m = t->matrix() * m;
+ return m;
+}
+
+
+void Entity::qmlAppendTransform(QQmlListProperty<AbstractTransform> *list, AbstractTransform *obj )
+{
+ if ( !obj )
+ return;
+
+ Entity* self = static_cast<Entity*>(list->object);
+ self->appendTransfrom(obj);
+}
+
+AbstractTransform* Entity::transformAt(QQmlListProperty<AbstractTransform>* list, int index)
+{
+ Entity* self = static_cast<Entity*>(list->object);
+ return self->transforms().at(index);
+}
+
+int Entity::transformCount(QQmlListProperty<AbstractTransform>* list)
+{
+ Entity* self = static_cast<Entity*>(list->object);
+ return self->transforms().count();
+}
+
+void Entity::qmlClearTransforms(QQmlListProperty<AbstractTransform> *list)
+{
+ Entity* self = static_cast<Entity*>(list->object);
+ qDeleteAll(self->m_transforms);
+ self->m_transforms.clear();
+ self->m_transformsDirty = true;
+}
+
+
+} // namespace Qt3D
diff --git a/src/core/entity.h b/src/core/entity.h
new file mode 100644
index 000000000..e79856e70
--- /dev/null
+++ b/src/core/entity.h
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_ENTITY_H
+#define QT3D_ENTITY_H
+
+#include "node.h"
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+
+namespace Qt3D {
+
+class AbstractTransform;
+class Component;
+
+typedef QList<Component*> ComponentList;
+
+class Entity : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
+
+ Q_PROPERTY(QQmlListProperty<Qt3D::AbstractTransform> transforms READ transformList)
+
+
+public:
+ explicit Entity(Node *parent = 0);
+
+ ComponentList components() const;
+
+ template <class T>
+ QList<T*> componentsOfType() const
+ {
+ QList<T*> result;
+ foreach (Component* comp, components()) {
+ T* i = qobject_cast<T*>(comp);
+ if (i)
+ result.append(i);
+ }
+
+ return result;
+ }
+
+ template <class T>
+ static T* findComponentInTree(Node* root)
+ {
+ if (!root)
+ return NULL;
+
+ if (root->asEntity()) {
+ foreach (Component* comp, root->asEntity()->components()) {
+ T* i = qobject_cast<T*>(comp);
+ if (i)
+ return i;
+ } // of component iteration
+ } // of is-entity
+
+ foreach (Node* child, root->children()) {
+ T* i = findComponentInTree<T>(child);
+ if (i)
+ return i;
+ } // of child nodes iteration
+
+ return NULL;
+ }
+
+ void addComponent(Component *comp);
+ void removeComponent(Component *comp);
+
+ bool isEnabled() const;
+ void setEnabled(bool on);
+
+ QMatrix4x4 matrix() const;
+ void setMatrix(const QMatrix4x4 &m);
+
+ QMatrix4x4 sceneMatrix() const;
+
+ QVector3D rotationCenter() const;
+ void setRotationCenter(const QVector3D &rc);
+
+ QList<AbstractTransform*> transforms() const;
+
+ // void insertTransformAt(...)
+ Q_INVOKABLE void appendTransfrom(AbstractTransform *xform);
+ Q_INVOKABLE void removeTransform(AbstractTransform *xform);
+
+ virtual Entity* asEntity();
+
+ Entity* parentEntity();
+
+ // TEMPORARY - should be driven by an Update traversal in the core
+ void update();
+signals:
+ void enabledChanged();
+
+private:
+ QQmlListProperty<Qt3D::AbstractTransform> transformList();
+
+ ComponentList m_components;
+
+ QMatrix4x4 applyTransforms() const;
+
+ mutable bool m_transformsDirty;
+ bool m_visible;
+ QList<AbstractTransform*> m_transforms;
+
+ mutable QMatrix4x4 m_matrix;
+ QMatrix4x4 m_sceneMatrix;
+
+ // TODO: Is a bool enough here or do we need additional states for entities?
+ // Perhaps aboutToBeDeleted would be useful?
+ bool m_enabled;
+
+ static void qmlAppendTransform(QQmlListProperty<Qt3D::AbstractTransform> *list, Qt3D::AbstractTransform *bar);
+ static AbstractTransform* transformAt(QQmlListProperty<Qt3D::AbstractTransform> *list, int index);
+ static int transformCount(QQmlListProperty<Qt3D::AbstractTransform> *list);
+ static void qmlClearTransforms(QQmlListProperty<Qt3D::AbstractTransform> *list);
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_ENTITY_H
diff --git a/src/core/lookattransform.cpp b/src/core/lookattransform.cpp
new file mode 100644
index 000000000..6d2109906
--- /dev/null
+++ b/src/core/lookattransform.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lookattransform.h"
+
+namespace Qt3D {
+
+LookAtTransform::LookAtTransform(Node *parent)
+ : AbstractTransform(parent)
+{
+}
+
+QMatrix4x4 LookAtTransform::matrix() const
+{
+ if (m_matrixDirty) {
+ m_matrix.setToIdentity();
+ m_matrix.lookAt(m_position, m_viewCenter, m_upVector);
+ m_matrixDirty = false;
+ }
+ return m_matrix;
+}
+
+QVector3D LookAtTransform::position() const
+{
+ return m_position;
+}
+
+void LookAtTransform::setPosition(const QVector3D &position)
+{
+ if (m_position != position) {
+ m_position = position;
+ m_viewVector = m_viewCenter - position;
+ m_matrixDirty = true;
+ emit positionChanged();
+ emit viewVectorChanged();
+ }
+}
+
+void LookAtTransform::setUpVector(const QVector3D &upVector)
+{
+ if (m_upVector != upVector) {
+ m_upVector = upVector;
+ m_matrixDirty = true;
+ emit upVectorChanged();
+ }
+}
+
+QVector3D LookAtTransform::upVector() const
+{
+ return m_upVector;
+}
+
+void LookAtTransform::setViewCenter(const QVector3D &viewCenter)
+{
+ if (m_viewCenter != viewCenter) {
+ m_viewCenter = viewCenter;
+ m_viewVector = viewCenter - m_position;
+ m_matrixDirty = true;
+ emit viewCenterChanged();
+ emit viewVectorChanged();
+ }
+}
+
+QVector3D LookAtTransform::viewCenter() const
+{
+ return m_viewCenter;
+}
+
+QVector3D LookAtTransform::viewVector() const
+{
+ return m_viewVector;
+}
+
+} // namespace Qt3D
diff --git a/src/core/lookattransform.h b/src/core/lookattransform.h
new file mode 100644
index 000000000..c032f32dc
--- /dev/null
+++ b/src/core/lookattransform.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_LOOKATTRANSFORM_H
+#define QT3D_LOOKATTRANSFORM_H
+
+#include "abstracttransform.h"
+#include "qt3dcore_global.h"
+
+#include <QVector3D>
+
+namespace Qt3D {
+
+class LookAtTransform : public Qt3D::AbstractTransform
+{
+ Q_OBJECT
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition)
+ Q_PROPERTY(QVector3D upVector READ upVector WRITE setUpVector)
+ Q_PROPERTY(QVector3D viewCenter READ viewCenter WRITE setViewCenter)
+ Q_PROPERTY(QVector3D viewVector READ viewVector NOTIFY viewVectorChanged)
+
+public:
+ explicit LookAtTransform(Node *parent = 0);
+
+ QMatrix4x4 matrix() const Q_DECL_OVERRIDE;
+
+ void setPosition(const QVector3D &position);
+ QVector3D position() const;
+
+ void setUpVector(const QVector3D &upVector);
+ QVector3D upVector() const;
+
+ void setViewCenter(const QVector3D &viewCenter);
+ QVector3D viewCenter() const;
+
+ QVector3D viewVector() const;
+
+signals:
+ void positionChanged();
+ void upVectorChanged();
+ void viewCenterChanged();
+ void viewVectorChanged();
+
+private:
+ mutable QMatrix4x4 m_matrix;
+ QVector3D m_position;
+ QVector3D m_upVector;
+ QVector3D m_viewCenter;
+ QVector3D m_viewVector; // From "camera" position to view center
+ mutable bool m_matrixDirty;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_LOOKATTRANSFORM_H
diff --git a/src/core/matrixtransform.cpp b/src/core/matrixtransform.cpp
new file mode 100644
index 000000000..e93b96835
--- /dev/null
+++ b/src/core/matrixtransform.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "matrixtransform.h"
+
+namespace Qt3D {
+
+MatrixTransform::MatrixTransform()
+{
+}
+
+MatrixTransform::MatrixTransform(const QMatrix4x4& m) :
+ m_matrix(m)
+{
+}
+
+QMatrix4x4 MatrixTransform::matrix() const
+{
+ return m_matrix;
+}
+
+}
diff --git a/src/core/matrixtransform.h b/src/core/matrixtransform.h
new file mode 100644
index 000000000..0019a2aef
--- /dev/null
+++ b/src/core/matrixtransform.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MATRIXTRANSFORM_H
+#define MATRIXTRANSFORM_H
+
+#include "abstracttransform.h"
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+
+namespace Qt3D {
+
+class MatrixTransform : public AbstractTransform
+{
+public:
+ MatrixTransform();
+
+ MatrixTransform( const QMatrix4x4& m );
+
+ virtual QMatrix4x4 matrix() const;
+private:
+ QMatrix4x4 m_matrix;
+};
+
+}
+
+#endif // MATRIXTRANSFORM_H
diff --git a/src/core/node.cpp b/src/core/node.cpp
new file mode 100644
index 000000000..81f11ea77
--- /dev/null
+++ b/src/core/node.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "node.h"
+
+#include "entity.h"
+
+#include <QEvent>
+#include <QMetaObject>
+#include <QMetaProperty>
+#include <QDebug>
+
+namespace Qt3D {
+
+Node::Node( Node* parent )
+ : QObject( parent )
+{
+ if (parent)
+ parent->m_children.append(this);
+}
+
+Node::~Node()
+{
+}
+
+QQmlListProperty<QObject> Node::data()
+{
+ return QQmlListProperty<QObject>(this, 0,
+ Node::appendData,
+ Node::dataCount,
+ Node::dataAt,
+ Node::clearData);
+}
+
+QQmlListProperty<Node> Node::childNodes()
+{
+ return QQmlListProperty<Node>(this, 0,
+ Node::appendChild,
+ Node::childCount,
+ Node::childAt,
+ Node::clearChildren);
+}
+
+void Node::dump()
+{
+ const QMetaObject *meta = metaObject();
+ QStringList result;
+ for (int i = 0; i < meta->propertyCount(); ++i) {
+ const QMetaProperty metaProperty = meta->property(i);
+ const QVariant value = property(metaProperty.name());
+ result += QString(QStringLiteral("%1 %2 = %3;"))
+ .arg(QString::fromLatin1(metaProperty.typeName()))
+ .arg(QString::fromLatin1(metaProperty.name()))
+ .arg(value.toString());
+ }
+
+ qDebug() << result.join(QStringLiteral("\n"));
+
+ foreach (QObject *child, children()) {
+ Node *node = qobject_cast<Node *>(child);
+ if (!node)
+ continue;
+ node->dump();
+ }
+}
+
+NodeList Node::children() const
+{
+ return m_children;
+}
+
+void Node::addChild(Node *childNode)
+{
+ Q_CHECK_PTR( childNode );
+ if (childNode->parent() == this)
+ return;
+
+ m_children.append(childNode);
+ childNode->setParent(this);
+
+ if (childNode->asEntity())
+ childNode->asEntity()->update();
+}
+
+void Node::removeChild(Node *childNode)
+{
+ Q_CHECK_PTR( childNode );
+ if (childNode->parent() != this)
+ qWarning() << Q_FUNC_INFO << "not a child";
+
+ m_children.removeOne(childNode);
+ childNode->setParent(NULL);
+}
+
+void Node::removeAllChildren()
+{
+ foreach (QObject *child, children()) {
+ child->deleteLater();
+ }
+
+ m_children.clear();
+}
+
+Entity *Node::asEntity()
+{
+ return NULL;
+}
+
+Node *Node::parentNode() const
+{
+ return qobject_cast<Node*>(parent());
+}
+
+bool Node::event(QEvent *e)
+{
+ if (e->type() == QEvent::DynamicPropertyChange) {
+ qDebug() << "*** Dynamic Property Change ***";
+ }
+ return QObject::event(e);
+}
+
+void Node::appendData(QQmlListProperty<QObject> *list, QObject *obj)
+{
+ if (!obj)
+ return;
+
+ QObject *self = static_cast<QObject *>(list->object);
+ if (obj->parent() == self)
+ obj->setParent(0);
+ obj->setParent(self);
+
+ Node *parentNode = qobject_cast<Qt3D::Node *>(self);
+ Node *node = qobject_cast<Qt3D::Node *>(obj);
+ if (node && parentNode)
+ parentNode->m_children.append(node);
+}
+
+QObject *Node::dataAt(QQmlListProperty<QObject> *list, int index)
+{
+ QObject *self = static_cast<QObject *>(list->object);
+ return self->children().at(index);
+}
+
+int Node::dataCount(QQmlListProperty<QObject> *list)
+{
+ QObject *self = static_cast<QObject *>(list->object);
+ return self->children().count();
+}
+
+void Node::clearData(QQmlListProperty<QObject> *list)
+{
+ QObject *self = static_cast<QObject *>(list->object);
+ Q_FOREACH (QObject *const child, self->children())
+ child->setParent(0);
+}
+
+void Node::appendChild(QQmlListProperty<Qt3D::Node> *list, Qt3D::Node *obj)
+{
+ if (!obj)
+ return;
+
+ Node *self = static_cast<Node *>(list->object);
+ Q_ASSERT(!self->m_children.contains(obj));
+ if (obj->parent() == self)
+ obj->setParent(0);
+ self->m_children.append(obj);
+ obj->setParent(self);
+}
+
+Qt3D::Node *Node::childAt(QQmlListProperty<Qt3D::Node> *list, int index)
+{
+ Node *self = static_cast<Node *>(list->object);
+ return self->m_children.at(index);
+}
+
+int Node::childCount(QQmlListProperty<Qt3D::Node> *list)
+{
+ Node *self = static_cast<Node *>(list->object);
+ return self->m_children.count();
+}
+
+void Node::clearChildren(QQmlListProperty<Qt3D::Node> *list)
+{
+ Node *self = static_cast<Node *>(list->object);
+ Q_FOREACH (Node *const child, self->m_children)
+ child->setParent(0);
+ self->m_children.clear();
+}
+
+} // of namespace Qt3D
diff --git a/src/core/node.h b/src/core/node.h
new file mode 100644
index 000000000..c1776774f
--- /dev/null
+++ b/src/core/node.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_NODE_H
+#define QT3D_NODE_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include <QQmlListProperty>
+
+namespace Qt3D {
+
+class Node;
+class Component;
+class Entity;
+
+typedef QList<Node *> NodeList;
+
+class QT3DCORESHARED_EXPORT Node : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<QObject> data READ data)
+ Q_PROPERTY(QQmlListProperty<Qt3D::Node> childNodes READ childNodes)
+ Q_CLASSINFO("DefaultProperty", "data")
+
+public:
+ explicit Node(Node *parent = 0);
+ ~Node();
+
+ QQmlListProperty<QObject> data();
+ QQmlListProperty<Qt3D::Node> childNodes();
+
+ void dump();
+
+ NodeList children() const;
+ void addChild( Node* childNode );
+ void removeChild( Node* childNode );
+
+ void removeAllChildren();
+
+ virtual Entity* asEntity();
+
+ Node* parentNode() const;
+
+protected:
+ bool event(QEvent *e);
+
+private:
+ static void appendData(QQmlListProperty<QObject> *list, QObject *obj);
+ static QObject *dataAt(QQmlListProperty<QObject> *list, int index);
+ static int dataCount(QQmlListProperty<QObject> *list);
+ static void clearData(QQmlListProperty<QObject> *list);
+
+ static void appendChild(QQmlListProperty<Qt3D::Node> *list, Qt3D::Node *obj);
+ static Node *childAt(QQmlListProperty<Qt3D::Node> *list, int index);
+ static int childCount(QQmlListProperty<Qt3D::Node> *list);
+ static void clearChildren(QQmlListProperty<Qt3D::Node> *list);
+
+ NodeList m_children;
+};
+
+}
+
+#endif
diff --git a/src/core/nodevisitor.cpp b/src/core/nodevisitor.cpp
new file mode 100644
index 000000000..5c0f99752
--- /dev/null
+++ b/src/core/nodevisitor.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "nodevisitor.h"
+
+#include "node.h"
+#include "entity.h"
+
+namespace Qt3D {
+
+NodeVisitor::NodeVisitor()
+ : m_traverseDisabled(false)
+{
+}
+
+void NodeVisitor::traverse(Node *rootNode)
+{
+ m_path = NodeList() << rootNode;
+
+ m_matrixStack.clear();
+ Entity* rootEntity = rootNode->asEntity();
+
+ m_matrixStack.append(rootEntity ? rootEntity->matrix() : QMatrix4x4());
+
+ if (rootEntity)
+ visitEntity(rootEntity);
+ else
+ visitNode(rootNode);
+}
+
+Node* NodeVisitor::rootNode() const
+{
+ return m_path.front();
+}
+
+Node* NodeVisitor::currentNode() const
+{
+ return m_path.back();
+}
+
+QMatrix4x4 NodeVisitor::currentMatrix() const
+{
+ return m_matrixStack.back();
+}
+
+NodeList NodeVisitor::path() const
+{
+ return m_path;
+}
+
+void NodeVisitor::setTraverseDisabled(bool on)
+{
+ m_traverseDisabled = on;
+}
+
+void NodeVisitor::visitNode(Node *nd)
+{
+ Q_UNUSED(nd);
+ traverseChildren();
+}
+
+void NodeVisitor::visitEntity(Entity *nd)
+{
+ visitNode(nd);
+}
+
+void NodeVisitor::traverseChildren()
+{
+ foreach (Node* n, currentNode()->children()) {
+ outerVisitNode(n);
+ } // of children iteration
+}
+
+void NodeVisitor::outerVisitNode(Node *n)
+{
+ m_path.append(n);
+ Entity* e = n->asEntity();
+ if (e) {
+ QMatrix4x4 m = m_matrixStack.back() * e->matrix();
+ m_matrixStack.push_back(m);
+
+ visitEntity(e);
+
+ m_path.pop_back();
+ m_matrixStack.pop_back();
+ } else {
+ visitNode(n);
+ }
+}
+
+} // of namespace
diff --git a/src/core/nodevisitor.h b/src/core/nodevisitor.h
new file mode 100644
index 000000000..2be95a8d1
--- /dev/null
+++ b/src/core/nodevisitor.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef NODEVISITOR_H
+#define NODEVISITOR_H
+
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+
+namespace Qt3D
+{
+
+class Node;
+class Entity;
+
+typedef QList<Node *> NodeList;
+
+class NodeVisitor
+{
+public:
+ NodeVisitor();
+
+ void traverse(Node *rootNode);
+
+ Node *rootNode() const;
+
+ Node *currentNode() const;
+
+ QMatrix4x4 currentMatrix() const;
+
+ NodeList path() const;
+
+ void setTraverseDisabled(bool on);
+
+protected:
+ virtual void visitNode(Node *nd);
+ virtual void visitEntity(Entity *ent);
+
+ void traverseChildren();
+
+private:
+ NodeList m_path;
+ QVector<QMatrix4x4> m_matrixStack;
+ bool m_traverseDisabled;
+
+ void outerVisitNode(Node *n);
+};
+
+} // of namespace
+
+#endif // NODEVISITOR_H
diff --git a/src/core/qaspectengine.cpp b/src/core/qaspectengine.cpp
new file mode 100644
index 000000000..63e470bfc
--- /dev/null
+++ b/src/core/qaspectengine.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaspectengine.h"
+
+#include "qaspectthread.h"
+#include "qaspectmanager.h"
+#include "qchangearbiter.h"
+
+#include <QDebug>
+#include <QMetaObject>
+#include <QMutexLocker>
+
+namespace Qt3D {
+
+QAspectEngine::QAspectEngine(QObject *parent)
+ : QObject(parent)
+ , m_aspectThread(new QAspectThread(this))
+{
+ qDebug() << Q_FUNC_INFO;
+ qRegisterMetaType<QWaitCondition *>();
+ m_aspectThread->waitForStart(QThread::HighestPriority);
+}
+
+void QAspectEngine::initialize()
+{
+ QChangeArbiter *arbiter = m_aspectThread->aspectManager()->changeArbiter();
+ QChangeArbiter::createUnmanagedThreadLocalChangeQueue(arbiter);
+}
+
+void QAspectEngine::shutdown()
+{
+}
+
+void QAspectEngine::setWindow(QWindow *window)
+{
+ QMetaObject::invokeMethod(m_aspectThread->aspectManager(), "setWindow", Q_ARG(QWindow *, window));
+}
+
+void QAspectEngine::setRoot(QObject *rootObject)
+{
+ QMutexLocker locker(&m_mutex);
+ QMetaObject::invokeMethod(m_aspectThread->aspectManager(), "setRoot", Q_ARG(QObject *, rootObject), Q_ARG(QWaitCondition *, &m_waitCondition));
+
+ qDebug() << "Putting main thread to sleep whilst aspects build their local scenes...";
+ m_waitCondition.wait(&m_mutex);
+ qDebug() << "Main thread is now awake again";
+}
+
+} // namespace Qt3D
diff --git a/src/core/qaspectengine.h b/src/core/qaspectengine.h
new file mode 100644
index 000000000..a7f949088
--- /dev/null
+++ b/src/core/qaspectengine.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QASPECTENGINE_H
+#define QASPECTENGINE_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include <QList>
+#include <QMutex>
+#include <QWaitCondition>
+
+class QWindow;
+
+namespace Qt3D {
+
+class AbstractAspect;
+class QAspectThread;
+
+class QAspectEngine : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QAspectEngine(QObject *parent = 0);
+
+ void initialize();
+ void shutdown();
+
+ void setRoot(QObject *rootObject);
+ void setWindow(QWindow *window);
+private:
+ QAspectThread *m_aspectThread;
+ QMutex m_mutex;
+ QWaitCondition m_waitCondition;
+};
+
+} // namespace Qt3D
+
+Q_DECLARE_METATYPE(QWaitCondition *)
+
+#endif // QASPECTENGINE_H
diff --git a/src/core/qaspectmanager.cpp b/src/core/qaspectmanager.cpp
new file mode 100644
index 000000000..1205314e9
--- /dev/null
+++ b/src/core/qaspectmanager.cpp
@@ -0,0 +1,191 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaspectmanager.h"
+
+#include "rendereraspect.h"
+#include "qchangearbiter.h"
+// TODO Make the kind of job manager configurable (e.g. ThreadWeaver vs Intel TBB)
+//#include "qjobmanager.h"
+#include "qjobmanagerinterface.h"
+#include "qscheduler.h"
+#include "qtickclock.h"
+
+#include <node.h>
+
+#include <QDebug>
+#include <QElapsedTimer>
+#include <QEventLoop>
+#include <QThread>
+#include <QWaitCondition>
+#include <QWindow>
+
+namespace Qt3D {
+
+QAspectManager::QAspectManager(QObject *parent)
+ : QObject(parent)
+ , m_root(0)
+ , m_window(0)
+ , m_scheduler(new QScheduler(this))
+ , m_jobManager(0/*new QJobManager(this)*/)
+ , m_changeArbiter(new QChangeArbiter(this))
+ , m_runMainLoop(false)
+{
+ qRegisterMetaType<QWindow*>("QWindow*");
+ qDebug() << Q_FUNC_INFO;
+}
+
+void QAspectManager::initialize()
+{
+ qDebug() << Q_FUNC_INFO;
+ m_jobManager->initialize();
+ m_scheduler->setAspectManager(this);
+ m_changeArbiter->initialize(m_jobManager);
+}
+
+void QAspectManager::shutdown()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void QAspectManager::setRoot(QObject *rootObject, QWaitCondition *waitCondition)
+{
+ qDebug() << Q_FUNC_INFO;
+
+ Node *root = qobject_cast<Node *>(rootObject);
+ if (root == m_root)
+ return;
+
+ if (m_root) {
+ // Allow each aspect chance to cleanup any resources from this scene
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->unregisterAspect(m_root);
+
+ // Allow each aspect chance to cleanup any scene-independent resources
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->cleanup();
+
+ // Destroy all aspects
+ qDeleteAll(m_aspects);
+ m_aspects.clear();
+
+ m_root = 0;
+ }
+
+ m_root = root;
+
+ if (rootObject) {
+ // TODO Load all aspect plugins that are found and required.
+ // For now just load the render aspect
+ RendererAspect *renderAspect = new RendererAspect(this);
+ m_aspects.append(renderAspect);
+
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->initialize(this);
+
+ if (m_window) {
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->setWindow(m_window);
+ }
+
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->registerAspect(m_root);
+
+ m_runMainLoop = true;
+ }
+
+ if (waitCondition)
+ waitCondition->wakeOne();
+}
+
+void QAspectManager::setWindow(QWindow *window)
+{
+ qDebug() << Q_FUNC_INFO;
+
+ m_window = window;
+
+ if (m_window) {
+ Q_FOREACH (AbstractAspect *aspect, m_aspects)
+ aspect->setWindow(m_window);
+ }
+}
+
+void QAspectManager::exec()
+{
+ // Gentlemen, start your engines
+ QEventLoop eventLoop;
+
+// QElapsedTimer timer;
+// timer.start();
+// qint64 t(0);
+ QTickClock tickClock;
+ tickClock.start();
+
+ // Enter the main loop
+ while (1)
+ {
+ // Process any pending events, waiting for more to arrive if queue is empty
+ eventLoop.processEvents(QEventLoop::WaitForMoreEvents, 16);
+
+ // Only enter main render loop once the renderer and other aspects are initialized
+ while (m_runMainLoop)
+ {
+ // Process any pending events
+ eventLoop.processEvents();
+
+ // Update the clocks (just main clock for now).
+ // TODO: Add additional clocks
+ qint64 t = tickClock.waitForNextTick();
+ // qDebug() << "t =" << t / 1000000;
+// const qint64 t1 = timer.nsecsElapsed();
+// const qint64 dt = t1 - t;
+// t = t1;
+// qDebug() << "dt =" << dt;
+
+ m_scheduler->update(t);
+
+ // Distribute accumulated changes
+ m_changeArbiter->syncChanges();
+ }
+ }
+}
+
+} // namespace Qt3D
diff --git a/src/core/qaspectmanager.h b/src/core/qaspectmanager.h
new file mode 100644
index 000000000..2653d4a0f
--- /dev/null
+++ b/src/core/qaspectmanager.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QASPECTMANAGER_H
+#define QT3D_QASPECTMANAGER_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include <QList>
+
+class QWaitCondition;
+class QWindow;
+
+namespace Qt3D {
+
+class AbstractAspect;
+class Node;
+class QChangeArbiter;
+class QJobManagerInterface;
+class QScheduler;
+
+class QAspectManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QAspectManager(QObject *parent = 0);
+
+public slots:
+ void initialize();
+ void shutdown();
+
+ void setRoot(QObject *rootObject, QWaitCondition *waitCondition);
+ void setWindow(QWindow* window);
+
+ void exec();
+
+ const QList<AbstractAspect *> &aspects() const { return m_aspects; }
+ QJobManagerInterface *jobManager() const { return m_jobManager; }
+ QChangeArbiter *changeArbiter() const { return m_changeArbiter; }
+
+private:
+ QList<AbstractAspect *> m_aspects;
+ Node *m_root;
+ QWindow *m_window;
+ QScheduler *m_scheduler;
+ QJobManagerInterface *m_jobManager;
+ QChangeArbiter *m_changeArbiter;
+ bool m_runMainLoop;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QASPECTMANAGER_H
diff --git a/src/core/qaspectscheduler.cpp b/src/core/qaspectscheduler.cpp
new file mode 100644
index 000000000..22febeae6
--- /dev/null
+++ b/src/core/qaspectscheduler.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaspectscheduler.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+
+QAspectScheduler::QAspectScheduler(QObject *parent)
+ : QObject(parent)
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+} // namespace Qt3D
diff --git a/src/core/qaspectscheduler.h b/src/core/qaspectscheduler.h
new file mode 100644
index 000000000..6bc38c732
--- /dev/null
+++ b/src/core/qaspectscheduler.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QASPECTSCHEDULER_H
+#define QT3D_QASPECTSCHEDULER_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+namespace Qt3D {
+
+class QAspectScheduler : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QAspectScheduler(QObject *parent = 0);
+
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QASPECTSCHEDULER_H
diff --git a/src/core/qaspectthread.cpp b/src/core/qaspectthread.cpp
new file mode 100644
index 000000000..22d920adb
--- /dev/null
+++ b/src/core/qaspectthread.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qaspectthread.h"
+
+#include <qaspectmanager.h>
+
+#include <QDebug>
+#include <QMutexLocker>
+
+namespace Qt3D {
+
+QAspectThread::QAspectThread(QObject *parent)
+ : QThread(parent)
+ , m_aspectManager(0)
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void QAspectThread::waitForStart(Priority priority)
+{
+ qDebug() << "Starting QAspectThread and going to sleep until it is ready for us...";
+ m_mutex.lock();
+ start(priority);
+ m_waitCondition.wait(&m_mutex);
+ qDebug() << "QAspectThead is now ready & calling thread is now awake again";
+}
+
+void QAspectThread::run()
+{
+ qDebug() << "Entering void QAspectThread::run()";
+
+ // Lock mutex and create worker objects
+ QMutexLocker locker(&m_mutex);
+ m_aspectManager = new QAspectManager;
+
+ // Wake up the calling thread now that our worker objects are ready for action
+ m_waitCondition.wakeOne();
+ m_mutex.unlock();
+
+ // Load and initialize the aspects and any other core services
+ m_aspectManager->initialize();
+
+ // Enter the main loop
+ m_aspectManager->exec();
+
+ // Clean up
+ m_aspectManager->shutdown();
+ delete m_aspectManager;
+
+ qDebug() << "Exiting void QAspectThread::run()";
+}
+
+} // namespace Qt3D
diff --git a/src/core/qaspectthread.h b/src/core/qaspectthread.h
new file mode 100644
index 000000000..6d9d76707
--- /dev/null
+++ b/src/core/qaspectthread.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QASPECTTHREAD_H
+#define QT3D_QASPECTTHREAD_H
+
+#include <QThread>
+#include "qt3dcore_global.h"
+
+#include <QMutex>
+#include <QWaitCondition>
+
+namespace Qt3D {
+
+class QAspectManager;
+
+class QAspectThread : public QThread
+{
+ Q_OBJECT
+public:
+ explicit QAspectThread(QObject *parent = 0);
+
+ void waitForStart(Priority priority);
+
+ QAspectManager *aspectManager() const { return m_aspectManager; }
+
+protected:
+ void run() Q_DECL_OVERRIDE;
+
+private:
+ QAspectManager *m_aspectManager;
+ QMutex m_mutex;
+ QWaitCondition m_waitCondition;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QASPECTTHREAD_H
diff --git a/src/core/qchangearbiter.cpp b/src/core/qchangearbiter.cpp
new file mode 100644
index 000000000..6bfbfd015
--- /dev/null
+++ b/src/core/qchangearbiter.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qchangearbiter.h"
+#include "component.h"
+#include "qjobmanagerinterface.h"
+
+#include <QDebug>
+#include <QMutexLocker>
+#include <QReadLocker>
+#include <QThread>
+#include <QWriteLocker>
+
+namespace Qt3D {
+
+QObservable::QObservable()
+ : m_observers()
+ , m_lock(QReadWriteLock::NonRecursive)
+{
+}
+
+void QObservable::registerObserver(QObserverInterface *observer)
+{
+ QWriteLocker locker(&m_lock);
+ if (!m_observers.contains(observer))
+ m_observers.append(observer);
+}
+
+void QObservable::unregisterObserver(QObserverInterface *observer)
+{
+ QWriteLocker locker(&m_lock);
+ m_observers.removeOne(observer);
+}
+
+void QObservable::notifyObservers(const QSceneChangePtr &e)
+{
+ QReadLocker locker(&m_lock);
+ Q_FOREACH (QObserverInterface *observer, m_observers)
+ observer->sceneChangeEvent(e);
+}
+
+
+QChangeArbiter::QChangeArbiter(QObject *parent)
+ : QObject(parent)
+ , m_jobManager(0)
+{
+}
+
+void QChangeArbiter::initialize(QJobManagerInterface *jobManager)
+{
+ Q_CHECK_PTR(jobManager);
+ m_jobManager = jobManager;
+
+ // Init TLS for the change queues
+ m_jobManager->waitForPerThreadFunction(QChangeArbiter::createThreadLocalChangeQueue, this);
+}
+
+void QChangeArbiter::distributeQueueChanges(ChangeQueue *changeQueue)
+{
+ Q_FOREACH (const QSceneChangePtr &change, *changeQueue) {
+ // Lookup which observers care about the subject this change came from
+ // and distribute the change to them
+ switch (change->m_subjectType) {
+ case QSceneChange::ObservableType: {
+ QObservableInterface *subject = change->m_subject.m_observable;
+ if (m_observations.contains(subject)) {
+ QObserverList &observers = m_observations[subject];
+ Q_FOREACH (QObserverInterface *observer, observers)
+ observer->sceneChangeEvent(change);
+ }
+ break;
+ }
+
+ case QSceneChange::ComponentType: {
+ Component *subject = change->m_subject.m_component;
+ if (m_componentObservations.contains(subject)) {
+ QObserverList &observers = m_componentObservations[subject];
+ Q_FOREACH (QObserverInterface *observer, observers)
+ observer->sceneChangeEvent(change);
+ }
+ break;
+ }
+ }
+ }
+}
+
+void QChangeArbiter::syncChanges()
+{
+ //qDebug() << Q_FUNC_INFO;
+ QMutexLocker locker(&m_mutex);
+ Q_FOREACH (QChangeArbiter::ChangeQueue *changeQueue, m_changeQueues) {
+ distributeQueueChanges(changeQueue);
+ changeQueue->clear();
+ }
+
+ Q_FOREACH (ChangeQueue *changeQueue, m_lockingChangeQueues) {
+ distributeQueueChanges(changeQueue);
+ changeQueue->clear();
+ }
+}
+
+void QChangeArbiter::registerObserver(QObserverInterface *observer,
+ QObservableInterface *subject,
+ ChangeFlags changeFlags)
+{
+ qDebug() << Q_FUNC_INFO;
+ if (!observer || !subject)
+ return;
+
+ // Store info about which observers are watching which observables.
+ // Protect access as this could be called from any thread
+ QMutexLocker locker(&m_mutex);
+ QObserverList &observers = m_observations[subject];
+ observers.append(observer);
+
+ // TODO: Also store info about types of change observer is interested in so that we
+ // can reduce the amount of traffic
+ Q_UNUSED(changeFlags);
+
+ // Register ourselves with the observable as the intermediary
+ subject->registerObserver(this);
+}
+
+void QChangeArbiter::registerObserver(QObserverInterface *observer,
+ Component *component,
+ ChangeFlags changeFlags)
+{
+ qDebug() << Q_FUNC_INFO;
+ if (!observer || !component)
+ return;
+
+ // Store info about which observers are watching which observables.
+ // Protect access as this could be called from any thread
+ QMutexLocker locker(&m_mutex);
+ QObserverList &observers = m_componentObservations[component];
+ observers.append(observer);
+
+ // TODO: Also store info about types of change observer is interested in so that we
+ // can reduce the amount of traffic
+ Q_UNUSED(changeFlags);
+
+ // Register ourselves with the observable as the intermediary
+ component->registerChangeArbiter(this);
+}
+
+void QChangeArbiter::unregisterObserver(QObserverInterface *observer,
+ QObservableInterface *subject)
+{
+ // TODO: Implement me!
+}
+
+void QChangeArbiter::sceneChangeEvent(const QSceneChangePtr &e)
+{
+ //qDebug() << Q_FUNC_INFO << QThread::currentThread();
+
+ // Add the change to the thread local storage queue - no locking required => yay!
+ ChangeQueue *localChangeQueue = m_tlsChangeQueue.localData();
+ localChangeQueue->append(e);
+
+ //qDebug() << "Change queue for thread" << QThread::currentThread() << "now contains" << localChangeQueue->count() << "items";
+}
+
+void QChangeArbiter::sceneChangeEventWithLock(const QSceneChangePtr &e)
+{
+ QMutexLocker locker(&m_mutex);
+ sceneChangeEvent(e);
+}
+
+void QChangeArbiter::createUnmanagedThreadLocalChangeQueue(void *changeArbiter)
+{
+ Q_CHECK_PTR(changeArbiter);
+
+ QChangeArbiter *arbiter = static_cast<QChangeArbiter *>(changeArbiter);
+
+ qDebug() << Q_FUNC_INFO << QThread::currentThread();
+ if (!arbiter->m_tlsChangeQueue.hasLocalData()) {
+ ChangeQueue *localChangeQueue = new ChangeQueue;
+ arbiter->m_tlsChangeQueue.setLocalData(localChangeQueue);
+
+ QMutexLocker locker(&(arbiter->m_mutex));
+ arbiter->m_lockingChangeQueues.append(localChangeQueue);
+ }
+}
+
+static void destroyUnmanagedThreadLocalChangeQueue(void *changeArbiter)
+{
+ // TODO: Implement me!
+}
+
+void QChangeArbiter::createThreadLocalChangeQueue(void *changeArbiter)
+{
+ Q_CHECK_PTR(changeArbiter);
+
+ QChangeArbiter *arbiter = static_cast<QChangeArbiter *>(changeArbiter);
+
+ qDebug() << Q_FUNC_INFO << QThread::currentThread();
+ if (!arbiter->m_tlsChangeQueue.hasLocalData()) {
+ ChangeQueue *localChangeQueue = new ChangeQueue;
+ arbiter->m_tlsChangeQueue.setLocalData(localChangeQueue);
+
+ QMutexLocker locker(&(arbiter->m_mutex));
+ arbiter->m_changeQueues.append(localChangeQueue);
+ }
+}
+
+static void destroyThreadLocalChangeQueue(void *changeArbiter)
+{
+ // TODO: Implement me!
+}
+
+} // namespace Qt3D
diff --git a/src/core/qchangearbiter.h b/src/core/qchangearbiter.h
new file mode 100644
index 000000000..73a0411f9
--- /dev/null
+++ b/src/core/qchangearbiter.h
@@ -0,0 +1,232 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QCHANGEARBITER_H
+#define QT3D_QCHANGEARBITER_H
+
+#include "qt3dcore_global.h"
+
+#include <QObject>
+#include <QDebug>
+#include <QFlags>
+#include <QMutex>
+#include <QReadWriteLock>
+#include <QSharedPointer>
+#include <QThreadStorage>
+#include <QVariant>
+#include <QVector>
+
+namespace Qt3D {
+
+class Component;
+
+enum ChangeFlag {
+ NodeCreated = 0x00000001,
+ NodeAboutToBeDeleted = 0x00000002,
+ NodeDeleted = 0x00000004,
+ NodeStatus = 0x00000008,
+ LocalTransform = 0x00000010,
+ MeshChange = 0x00000020,
+ MaterialParameter = 0x00000040,
+ CameraProjectionMatrix = 0x00000080,
+ AllChanges = 0xFFFFFFFF
+};
+Q_DECLARE_FLAGS(ChangeFlags, ChangeFlag)
+Q_DECLARE_OPERATORS_FOR_FLAGS(ChangeFlags)
+
+
+class QObserverInterface;
+class QObservableInterface;
+
+class QT3DCORESHARED_EXPORT QSceneChange
+{
+public:
+ QSceneChange(ChangeFlag type, QObservableInterface *observable)
+ : m_type(type)
+ {
+ m_subject.m_observable = observable;
+ m_subjectType = ObservableType;
+ }
+
+ QSceneChange(ChangeFlag type, Component *component)
+ : m_type(type)
+ {
+ m_subject.m_component = component;
+ m_subjectType = ComponentType;
+ }
+
+ union {
+ QObservableInterface *m_observable;
+ Component *m_component;
+ } m_subject;
+
+ enum ObservableType {
+ ObservableType,
+ ComponentType
+ } m_subjectType;
+
+ ChangeFlag m_type;
+
+ // TODO: add timestamp from central clock and priority level
+ // These can be used to resolve any conflicts between events
+ // posted from different aspects
+};
+
+typedef QSharedPointer<QSceneChange> QSceneChangePtr;
+
+class QT3DCORESHARED_EXPORT QScenePropertyChange : public QSceneChange
+{
+public:
+ QScenePropertyChange(ChangeFlag type, QObservableInterface *subject)
+ : QSceneChange(type, subject)
+ {
+ }
+
+ QScenePropertyChange(ChangeFlag type, Component *component)
+ : QSceneChange(type, component)
+ {
+ }
+
+ QByteArray m_propertyName;
+ QVariant m_value;
+};
+
+typedef QSharedPointer<QScenePropertyChange> QScenePropertyChangePtr;
+
+
+class QT3DCORESHARED_EXPORT QObservableInterface
+{
+public:
+ virtual ~QObservableInterface() {}
+
+ virtual void registerObserver(QObserverInterface *observer) = 0;
+ virtual void unregisterObserver(QObserverInterface *observer) = 0;
+
+protected:
+ virtual void notifyObservers(const QSceneChangePtr &e) = 0;
+};
+
+
+class QT3DCORESHARED_EXPORT QObservable : public QObservableInterface
+{
+public:
+ QObservable();
+
+ void registerObserver(QObserverInterface *observer) Q_DECL_OVERRIDE;
+ void unregisterObserver(QObserverInterface *observer) Q_DECL_OVERRIDE;
+
+protected:
+ void notifyObservers(const QSceneChangePtr &e) Q_DECL_OVERRIDE;
+
+ const QList<QObserverInterface *> &observers() const { return m_observers; }
+
+private:
+ QList<QObserverInterface *> m_observers;
+ QReadWriteLock m_lock;
+};
+
+
+class QObserverInterface
+{
+public:
+ virtual ~QObserverInterface() {}
+
+ virtual void sceneChangeEvent(const QSceneChangePtr &e) = 0;
+};
+
+
+class QJobManagerInterface;
+
+class QT3DCORESHARED_EXPORT QChangeArbiter : public QObject,
+ public QObserverInterface
+{
+ Q_OBJECT
+public:
+ explicit QChangeArbiter(QObject *parent = 0);
+
+ void initialize(Qt3D::QJobManagerInterface *jobManager);
+
+ void syncChanges();
+
+ void registerObserver(QObserverInterface *observer,
+ QObservableInterface *subject,
+ ChangeFlags changeFlags = AllChanges);
+
+ void registerObserver(QObserverInterface *observer,
+ Component *component,
+ ChangeFlags changeFlags = AllChanges);
+
+ void unregisterObserver(QObserverInterface *observer,
+ QObservableInterface *subject);
+
+ void sceneChangeEvent(const QSceneChangePtr &e) Q_DECL_OVERRIDE; // QObserverInterface impl
+ void sceneChangeEventWithLock(const QSceneChangePtr &e);
+
+ static void createUnmanagedThreadLocalChangeQueue(void *changeArbiter);
+ static void destroyUnmanagedThreadLocalChangeQueue(void *changeArbiter);
+ static void createThreadLocalChangeQueue(void *changeArbiter);
+ static void destroyThreadLocalChangeQueue(void *changeArbiter);
+
+private:
+ typedef QVector<QSceneChangePtr> ChangeQueue;
+
+ void distributeQueueChanges(ChangeQueue *queue);
+
+ QMutex m_mutex;
+ QJobManagerInterface *m_jobManager;
+
+ typedef QList<QObserverInterface *> QObserverList;
+ QHash<QObservableInterface *, QObserverList> m_observations;
+ QHash<Component *, QObserverList> m_componentObservations;
+
+ // Each thread has a TLS ChangeQueue so we never need to lock whilst
+ // receiving a QSceneChange.
+ QThreadStorage<ChangeQueue *> m_tlsChangeQueue;
+
+ // We store a list of the ChangeQueue's from each thread. This will only
+ // be accesses from the aspect thread during the syncChanges() phase.
+ QList<ChangeQueue *> m_changeQueues;
+ QList<ChangeQueue *> m_lockingChangeQueues;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QCHANGEARBITER_H
diff --git a/src/core/qjob.cpp b/src/core/qjob.cpp
new file mode 100644
index 000000000..73dfabfe2
--- /dev/null
+++ b/src/core/qjob.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qjob.h"
+
+namespace Qt3D {
+
+QJob::QJob()
+{
+}
+
+QJob::~QJob()
+{
+}
+
+void QJob::addDependency(QWeakPointer<QJob> dependency)
+{
+ m_dependencies.append(dependency);
+}
+
+} // namespace Qt3D
diff --git a/src/core/qjob.h b/src/core/qjob.h
new file mode 100644
index 000000000..c49907538
--- /dev/null
+++ b/src/core/qjob.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QJOB_H
+#define QT3D_QJOB_H
+
+#include "qt3dcore_global.h"
+
+#include <QSharedPointer>
+#include <QVector>
+
+namespace Qt3D {
+
+class QJob
+{
+public:
+ QJob();
+ virtual ~QJob();
+
+ void addDependency(QWeakPointer<QJob> dependency);
+ const QVector<QWeakPointer<QJob> > &dependencies() const { return m_dependencies; }
+
+ virtual void run() = 0;
+
+private:
+ QVector<QWeakPointer<QJob> > m_dependencies;
+};
+
+typedef QSharedPointer<QJob> QJobPtr;
+
+} // namespace Qt3D
+
+#endif // QT3D_QJOB_H
diff --git a/src/core/qjobmanagerinterface.h b/src/core/qjobmanagerinterface.h
new file mode 100644
index 000000000..a003d1198
--- /dev/null
+++ b/src/core/qjobmanagerinterface.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QJOBMANAGERINTERFACE_H
+#define QJOBMANAGERINTERFACE_H
+
+#include <QObject>
+
+#include "qjob.h"
+
+namespace Qt3D {
+
+class QJobManagerInterface : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QJobManagerInterface(QObject *parent = 0)
+ : QObject(parent)
+ {}
+
+ virtual void initialize() {}
+ virtual void enqueueJobs(const QVector<QJobPtr> &jobQueue) = 0;
+ virtual void waitForAllJobs() = 0;
+
+ // Callback signature for running SynchronizedJobs
+ typedef void (*JobFunction)(void *);
+ virtual void waitForPerThreadFunction(JobFunction func, void *arg) = 0;
+};
+
+} // namespace Qt3D
+
+#endif // QJOBMANAGERINTERFACE_H
diff --git a/src/core/qjobproviderinterface.h b/src/core/qjobproviderinterface.h
new file mode 100644
index 000000000..891e44fff
--- /dev/null
+++ b/src/core/qjobproviderinterface.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QJOBPROVIDERINTERFACE_H
+#define QT3D_QJOBPROVIDERINTERFACE_H
+
+#include "qt3dcore_global.h"
+#include "qjob.h"
+
+#include <QVector>
+
+namespace Qt3D {
+
+class QJobProviderInterface
+{
+public:
+ virtual QVector<QJobPtr> jobsToExecute() = 0;
+};
+
+}
+
+#endif // QT3D_QJOBPROVIDERINTERFACE_H
diff --git a/src/core/qscheduler.cpp b/src/core/qscheduler.cpp
new file mode 100644
index 000000000..af175210c
--- /dev/null
+++ b/src/core/qscheduler.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscheduler.h"
+
+#include "abstractaspect.h"
+#include "qaspectmanager.h"
+#include "qjobmanagerinterface.h"
+
+namespace Qt3D {
+
+QScheduler::QScheduler(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void QScheduler::setAspectManager(QAspectManager *aspectManager)
+{
+ m_aspectManager = aspectManager;
+}
+
+QAspectManager *QScheduler::aspectManager() const
+{
+ return m_aspectManager;
+}
+
+void QScheduler::update(qint64 time)
+{
+ // Get tasks for this frame from each aspect
+ const QList<AbstractAspect *> &aspects = m_aspectManager->aspects();
+ QHash<AbstractAspect::AspectType, QVector<QJobPtr> > jobs;
+ Q_FOREACH (AbstractAspect *aspect, aspects) {
+ QVector<QJobPtr> aspectJobs = aspect->jobsToExecute();
+ jobs.insert(aspect->aspectType(), aspectJobs);
+ }
+
+ // TODO: Set up dependencies between jobs as needed
+ // For now just queue them up as they are with render tasks first
+ QVector<QJobPtr> jobQueue;
+ for (int i = AbstractAspect::AspectRenderer; i <= AbstractAspect::AspectOther; ++i) {
+ AbstractAspect::AspectType aspectType = static_cast<AbstractAspect::AspectType>(i);
+ if (jobs.contains(aspectType))
+ jobQueue += jobs.value(aspectType);
+ }
+
+ m_aspectManager->jobManager()->enqueueJobs(jobQueue);
+
+ // Do any other work here that the aspect thread can usefully be doing
+ // whilst the threadpool works its way through the jobs
+
+ m_aspectManager->jobManager()->waitForAllJobs();
+}
+
+} // namespace Qt3D
diff --git a/src/core/qscheduler.h b/src/core/qscheduler.h
new file mode 100644
index 000000000..24e86ec4a
--- /dev/null
+++ b/src/core/qscheduler.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QSCHEDULER_H
+#define QT3D_QSCHEDULER_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+namespace Qt3D {
+
+class QAspectManager;
+
+class QScheduler : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QScheduler(QObject *parent = 0);
+
+ void setAspectManager(QAspectManager *aspectManager);
+ QAspectManager *aspectManager() const;
+
+ virtual void update(qint64 time);
+
+private:
+ QAspectManager *m_aspectManager;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QSCHEDULER_H
diff --git a/src/core/qt3dcore_global.h b/src/core/qt3dcore_global.h
new file mode 100644
index 000000000..cb4d67321
--- /dev/null
+++ b/src/core/qt3dcore_global.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3DCORE_GLOBAL_H
+#define QT3DCORE_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(QT3DCORE_LIBRARY)
+# define QT3DCORESHARED_EXPORT Q_DECL_EXPORT
+#else
+# define QT3DCORESHARED_EXPORT Q_DECL_IMPORT
+#endif
+
+#endif // QT3DCORE_GLOBAL_H
diff --git a/src/core/qtickclock.cpp b/src/core/qtickclock.cpp
new file mode 100644
index 000000000..fbb9f7d68
--- /dev/null
+++ b/src/core/qtickclock.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qtickclock.h"
+
+#include <QDebug>
+#include <QThread>
+
+namespace Qt3D {
+
+QTickClock::QTickClock(QObject *parent)
+ : QObject(parent)
+ , m_tickInterval(1000000000 / 60) // Nanoseconds
+ , m_time(0)
+{
+}
+
+void QTickClock::setTickFrequency(float frequency)
+{
+ Q_ASSERT(frequency > 0.0f);
+ m_tickInterval = static_cast<qint64>(1000000000 / frequency);
+}
+
+void QTickClock::start()
+{
+ m_timer.start();
+ m_time = m_timer.nsecsElapsed();
+ qDebug() << "tickInterval =" << m_tickInterval << "ns";
+}
+
+void QTickClock::reset()
+{
+ m_time = 0;
+}
+
+qint64 QTickClock::waitForNextTick()
+{
+ qint64 t = m_timer.nsecsElapsed();
+ qint64 dt = t - m_time;
+ qint64 timeToSleep = m_tickInterval - dt;
+
+ // If we are lagging behind don't delay
+ // TODO: Do we want a mode where if we are lagging we instead wait
+ // for the next tick instead?
+ if (timeToSleep < 0) {
+ qDebug() << "Lagging behind desired tick interval";
+ m_time = t;
+ return m_time;
+ }
+
+ unsigned long sleepTimeMicroSeconds = static_cast<unsigned long>(timeToSleep / 1000);
+ //qDebug() << "sleeping for" << sleepTimeMicroSeconds << "us";
+ QThread::usleep(sleepTimeMicroSeconds);
+
+#if defined(QT3D_DEBUG_TICKCLOCK)
+ qint64 expectedWakeTime = t + sleepTimeMicroSeconds * 1000;
+ qint64 wakeTime = m_timer.nsecsElapsed();
+ qDebug() << "t =" << t / 1000000 << "timeToSleep =" << timeToSleep / 1000000
+ << "due to wake at =" << expectedWakeTime / 1000000
+ << "actually woke at" << wakeTime / 1000000
+ << "delta =" << (expectedWakeTime - wakeTime) / 1000000;
+#endif
+
+ m_time = m_timer.nsecsElapsed();
+ return m_time;
+}
+
+}
diff --git a/src/core/qtickclock.h b/src/core/qtickclock.h
new file mode 100644
index 000000000..a82cf3f01
--- /dev/null
+++ b/src/core/qtickclock.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QTICKCLOCK_H
+#define QTICKCLOCK_H
+
+#include <QObject>
+#include "qt3dcore_global.h"
+
+#include <QElapsedTimer>
+
+namespace Qt3D {
+
+class QTickClock : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QTickClock(QObject *parent = 0);
+
+ void setTickFrequency(float frequency);
+
+ void start();
+ void reset();
+
+ qint64 waitForNextTick();
+
+private:
+ QElapsedTimer m_timer;
+ qint64 m_tickInterval;
+ qint64 m_time;
+};
+
+} // namespace Qt3D
+
+#endif // QTICKCLOCK_H
diff --git a/src/core/rotatetransform.cpp b/src/core/rotatetransform.cpp
new file mode 100644
index 000000000..410e482fb
--- /dev/null
+++ b/src/core/rotatetransform.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define _USE_MATH_DEFINES // For MSVC
+#include "rotatetransform.h"
+
+#include <cmath>
+
+namespace Qt3D {
+
+RotateTransform::RotateTransform(Node *parent)
+ : AbstractTransform(parent)
+{
+}
+
+float RotateTransform::angleDeg() const
+{
+ return m_angleDeg;
+}
+
+float Qt3D::RotateTransform::angleRad() const
+{
+ return (m_angleDeg / 180.0) * M_PI;
+}
+
+QVector3D RotateTransform::axis() const
+{
+ return m_axis;
+}
+
+QMatrix4x4 RotateTransform::matrix() const
+{
+ QMatrix4x4 m;
+ m.rotate(m_angleDeg, m_axis);
+ return m;
+}
+
+void RotateTransform::setAngleDeg(float arg)
+{
+ if (m_angleDeg != arg) {
+ m_angleDeg = arg;
+ emit angleChanged();
+ }
+}
+
+void RotateTransform::setAngleRad(float arg)
+{
+ float angleDeg = (arg * M_PI) / 180.0f;
+ setAngleDeg(angleDeg);
+}
+
+void RotateTransform::setAxis(const QVector3D& arg)
+{
+ if (m_axis != arg) {
+ m_axis = arg;
+ emit axisChanged();
+ }
+}
+
+} // namespace Qt3D
diff --git a/src/core/rotatetransform.h b/src/core/rotatetransform.h
new file mode 100644
index 000000000..9921c82c4
--- /dev/null
+++ b/src/core/rotatetransform.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_ROTATETRANSFORM_H
+#define QT3D_ROTATETRANSFORM_H
+
+#include "abstracttransform.h"
+#include "qt3dcore_global.h"
+
+#include <QVector3D>
+
+namespace Qt3D {
+
+class RotateTransform : public AbstractTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(float angle READ angleDeg WRITE setAngleDeg NOTIFY angleChanged)
+ Q_PROPERTY(float angleRad READ angleRad WRITE setAngleRad NOTIFY angleChanged)
+
+ Q_PROPERTY(QVector3D axis READ axis WRITE setAxis NOTIFY axisChanged)
+
+public:
+ explicit RotateTransform(Node *parent = 0);
+
+ float angleDeg() const;
+
+ float angleRad() const;
+
+ QVector3D axis() const;
+
+ virtual QMatrix4x4 matrix() const;
+
+public slots:
+ void setAngleDeg(float arg);
+
+ void setAngleRad(float arg);
+
+ void setAxis(const QVector3D& arg);
+
+signals:
+
+ void axisChanged();
+ void angleChanged();
+
+private:
+ float m_angleDeg;
+ QVector3D m_axis;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_ROTATETRANSFORM_H
diff --git a/src/core/scene.cpp b/src/core/scene.cpp
new file mode 100644
index 000000000..f8a1a15cc
--- /dev/null
+++ b/src/core/scene.cpp
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scene.h"
+
+#include <QDebug>
+
+#include <gltfparser.h>
+
+namespace Qt3D
+{
+
+Scene::Scene(Node* parent) :
+ Entity(parent)
+{
+}
+
+QString Scene::source() const
+{
+ return m_source;
+}
+
+QString Scene::sceneId() const
+{
+ return m_sceneId;
+}
+
+Scene *Scene::findInTree(Node *root)
+{
+ if (!root)
+ return NULL;
+
+ Scene* s = qobject_cast<Scene*>(root);
+ if (s)
+ return s;
+
+ // recursive walk down the tree
+ foreach (Node* nd, root->children()) {
+ s = findInTree(nd);
+ if (s)
+ return s;
+ }
+
+ return NULL;
+}
+
+void Scene::clear()
+{
+ removeAllChildren();
+}
+
+void Scene::setSource(QString arg)
+{
+ if (m_source != arg) {
+ m_source = arg;
+ rebuild();
+ emit sourceChanged(arg);
+ }
+}
+
+void Qt3D::Scene::setSceneId(QString arg)
+{
+ if (m_sceneId != arg) {
+ m_sceneId = arg;
+ rebuild();
+ emit sceneIdChanged(arg);
+ }
+}
+
+void Scene::rebuild()
+{
+ if (m_sceneChild) {
+ removeChild(m_sceneChild);
+ m_sceneChild->deleteLater();
+ }
+
+ if (GLTFParser::isGLTFPath(m_source)) {
+ qDebug() << Q_FUNC_INFO << "will load GLTF scene";
+
+ GLTFParser parser;
+ parser.setFilePath(m_source);
+
+ if (!m_sceneId.isEmpty())
+ m_sceneChild = parser.scene(m_sceneId);
+ else
+ m_sceneChild = parser.defaultScene();
+
+ if (m_sceneChild) {
+ addChild(m_sceneChild);
+ }
+ } else {
+
+ }
+}
+
+} // of namespace
diff --git a/src/core/scene.h b/src/core/scene.h
new file mode 100644
index 000000000..2fd67bb6c
--- /dev/null
+++ b/src/core/scene.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_H
+#define SCENE_H
+
+#include "entity.h"
+#include "qt3dcore_global.h"
+
+namespace Qt3D
+{
+
+class Scene : public Entity
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(QString sceneId READ sceneId WRITE setSceneId NOTIFY sceneIdChanged)
+public:
+ explicit Scene(Node *parent = 0);
+
+ QString source() const;
+
+ QString sceneId() const;
+
+ /**
+ * @brief findInTree - given a Node* object rooting a tree, find
+ * the top-most Scene entity within.
+ * @param root - the found Scene or NULL if no Scene was found
+ * @return
+ */
+ static Scene* findInTree(Node* root);
+signals:
+
+ void sourceChanged(QString arg);
+
+ void sceneIdChanged(QString arg);
+
+public slots:
+ void clear();
+
+ void setSource(QString arg);
+
+ void setSceneId(QString arg);
+
+private:
+ void rebuild();
+
+ QString m_source;
+ QString m_sceneId;
+
+ Node* m_sceneChild;
+
+};
+
+} // of namespace
+
+#endif // SCENE_H
diff --git a/src/core/sphere.cpp b/src/core/sphere.cpp
new file mode 100644
index 000000000..3daf3804b
--- /dev/null
+++ b/src/core/sphere.cpp
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "sphere.h"
+
+#include <QPair>
+
+#include <math.h>
+
+namespace {
+
+inline QPair<int, int> findExtremePoints(const QVector<QVector3D> &points)
+{
+ // Find indices of extreme points along x, y, and z axes
+ int xMin = 0, xMax = 0, yMin = 0, yMax = 0, zMin = 0, zMax = 0;
+ for (int i = 1; i < points.size(); ++i) {
+ const QVector3D &p = points.at(i);
+ if (p.x() < points[xMin].x())
+ xMin = i;
+ if (p.x() > points[xMax].x())
+ xMax = i;
+ if (p.y() < points[yMin].y())
+ yMin = i;
+ if (p.y() > points[yMax].y())
+ yMax = i;
+ if (p.z() < points[zMin].z())
+ zMin = i;
+ if (p.z() > points[zMax].z())
+ zMax = i;
+ }
+
+ // Calculate squared distance for the pairs of points
+ const float xDist2 = (points.at(xMax) - points.at(xMin)).lengthSquared();
+ const float yDist2 = (points.at(yMax) - points.at(yMin)).lengthSquared();
+ const float zDist2 = (points.at(zMax) - points.at(zMin)).lengthSquared();
+
+ // Select most distant pair
+ QPair<int, int> extremeIndices(xMin, xMax);
+ if (yDist2 > xDist2 && yDist2 > zDist2)
+ extremeIndices = qMakePair(yMin, yMax);
+ if (zDist2 > xDist2 && zDist2 > yDist2)
+ extremeIndices = qMakePair(zMin, zMax);
+
+ return extremeIndices;
+}
+
+inline void sphereFromExtremePoints(Qt3D::Sphere &s, const QVector<QVector3D> &points)
+{
+ // Find two most separated points on any of the basis vectors
+ QPair<int, int> extremeIndices = findExtremePoints(points);
+
+ // Construct sphere to contain these two points
+ const QVector3D &p = points.at(extremeIndices.first);
+ const QVector3D &q = points.at(extremeIndices.second);
+ const QVector3D c = 0.5f * (p + q);
+ s.setCenter(c);
+ s.setRadius((q - c).length());
+}
+
+inline void constructRitterSphere(Qt3D::Sphere &s, const QVector<QVector3D> &points)
+{
+ // Calculate the sphere encompassing two axially extreme points
+ sphereFromExtremePoints(s, points);
+
+ // Now make sure the sphere bounds all points by growing if needed
+ s.expandToContain(points);
+}
+
+} // anonymous namespace
+
+namespace Qt3D {
+
+const float Sphere::ms_epsilon = 1.0e-7;
+
+Sphere Sphere::fromPoints(const QVector<QVector3D> &points)
+{
+ Sphere s;
+ s.initializeFromPoints(points);
+ return s;
+}
+
+void Sphere::initializeFromPoints(const QVector<QVector3D> &points)
+{
+ constructRitterSphere(*this, points);
+}
+
+void Sphere::expandToContain(const QVector3D &p)
+{
+ const QVector3D d = p - m_center;
+ const float dist2 = d.lengthSquared();
+
+ if (dist2 > m_radius * m_radius) {
+ // Expand radius so sphere also contains p
+ const float dist = sqrt(dist2);
+ const float newRadius = 0.5f * (m_radius + dist);
+ const float k = (newRadius - m_radius) / dist;
+ m_radius = newRadius;
+ m_center += k * d;
+ }
+}
+
+void Sphere::expandToContain(const Sphere &sphere)
+{
+ const QVector3D d(sphere.m_center - m_center);
+ const float dist2 = d.lengthSquared();
+
+ const float dr = sphere.m_radius - m_radius;
+ if (dr * dr >= dist2) {
+ // Larger sphere encloses the smaller. Set our size to the larger
+ if (m_radius > sphere.m_radius)
+ return;
+ else
+ *this = sphere;
+ } else {
+ // The spheres are overlapping or disjoint
+ const float dist = sqrt(dist2);
+ const float newRadius = 0.5f * (dist + m_radius + sphere.m_radius);
+ if (dist > ms_epsilon)
+ m_center += d * (newRadius - m_radius) / dist;
+ }
+}
+
+Sphere Sphere::transformed(const QMatrix4x4 &mat)
+{
+ // Transform extremities in x, y, and z directions to find extremities
+ // of the resulting ellipsoid
+ QVector3D x = mat.mapVector(m_center + QVector3D(m_radius, 0.0f, 0.0f));
+ QVector3D y = mat.mapVector(m_center + QVector3D(0.0f, m_radius, 0.0f));
+ QVector3D z = mat.mapVector(m_center + QVector3D(0.0f, 0.0f, m_radius));
+
+ // Transform center and find maximum radius of ellipsoid
+ QVector3D c = mat.mapVector(m_center);
+ float rSquared = qMax(qMax((x - c).lengthSquared(), (y - c).lengthSquared()), (z - c).lengthSquared());
+ return Sphere(c, sqrt(rSquared));
+}
+
+}
diff --git a/src/core/sphere.h b/src/core/sphere.h
new file mode 100644
index 000000000..6a46fce04
--- /dev/null
+++ b/src/core/sphere.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SPHERE_H
+#define SPHERE_H
+
+#include "qt3dcore_global.h"
+
+#include <QMatrix4x4>
+#include <QVector3D>
+
+namespace Qt3D {
+
+class QT3DCORESHARED_EXPORT Sphere
+{
+public:
+ inline Sphere()
+ : m_center(),
+ m_radius(0.0f)
+ {}
+
+ inline Sphere(const QVector3D &c, float r)
+ : m_center(c),
+ m_radius(r)
+ {}
+
+ void setCenter(const QVector3D &center);
+ QVector3D center() const;
+
+ void setRadius(float radius);
+ float radius() const;
+
+ void clear();
+ void initializeFromPoints(const QVector<QVector3D> &points);
+ void expandToContain(const QVector3D &point);
+ inline void expandToContain(const QVector<QVector3D> &points)
+ {
+ Q_FOREACH (const QVector3D &p, points)
+ expandToContain(p);
+ }
+
+ void expandToContain(const Sphere &sphere);
+
+ Sphere transformed(const QMatrix4x4 &mat);
+ inline Sphere &transform(const QMatrix4x4 &mat)
+ {
+ *this = transformed(mat);
+ return *this;
+ }
+
+ static Sphere fromPoints(const QVector<QVector3D> &points);
+
+private:
+ QVector3D m_center;
+ float m_radius;
+
+ static const float ms_epsilon;
+};
+
+inline void Sphere::setCenter(const QVector3D &center)
+{
+ m_center = center;
+}
+
+inline QVector3D Sphere::center() const
+{
+ return m_center;
+}
+
+inline void Sphere::setRadius(float radius)
+{
+ m_radius = radius;
+}
+
+inline float Sphere::radius() const
+{
+ return m_radius;
+}
+
+inline void Sphere::clear()
+{
+ m_center = QVector3D();
+ m_radius = 0.0f;
+}
+
+inline bool intersects(const Sphere &a, const Sphere &b)
+{
+ // Calculate squared distance between sphere centers
+ const QVector3D d = a.center() - b.center();
+ const float distSq = QVector3D::dotProduct(d, d);
+
+ // Spheres intersect if squared distance is less than squared
+ // sum of radii
+ const float sumRadii = a.radius() + b.radius();
+ return distSq <= sumRadii * sumRadii;
+}
+
+}
+
+#endif // SPHERE_H
diff --git a/src/core/translatetransform.cpp b/src/core/translatetransform.cpp
new file mode 100644
index 000000000..faf65ca9f
--- /dev/null
+++ b/src/core/translatetransform.cpp
@@ -0,0 +1,110 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "translatetransform.h"
+
+namespace Qt3D {
+
+TranslateTransform::TranslateTransform(Node *parent)
+ : AbstractTransform(parent)
+{
+}
+
+float TranslateTransform::dx() const
+{
+ return m_translation.x();
+}
+
+float TranslateTransform::dy() const
+{
+ return m_translation.y();
+}
+
+float TranslateTransform::dz() const
+{
+ return m_translation.z();
+}
+
+QVector3D TranslateTransform::translation() const
+{
+ return m_translation;
+}
+
+QMatrix4x4 TranslateTransform::matrix() const
+{
+ QMatrix4x4 r;
+ r.translate(m_translation);
+ return r;
+}
+
+void TranslateTransform::setDx(float arg)
+{
+ if (arg != m_translation.x()) {
+ m_translation.setX(arg);
+ emit translateChanged();
+ }
+}
+
+void TranslateTransform::setDy(float arg)
+{
+ if (arg != m_translation.y()) {
+ m_translation.setY(arg);
+ emit translateChanged();
+ }
+}
+
+void TranslateTransform::setDz(float arg)
+{
+ if (arg != m_translation.z()) {
+ m_translation.setZ(arg);
+ emit translateChanged();
+ }
+}
+
+void TranslateTransform::setTranslation(QVector3D arg)
+{
+ if (m_translation != arg) {
+ m_translation = arg;
+ emit translateChanged();
+ }
+}
+
+} // namespace Qt3D
diff --git a/src/core/translatetransform.h b/src/core/translatetransform.h
new file mode 100644
index 000000000..9dd1fb7cb
--- /dev/null
+++ b/src/core/translatetransform.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_TRANSLATETRANSFORM_H
+#define QT3D_TRANSLATETRANSFORM_H
+
+#include "abstracttransform.h"
+#include "qt3dcore_global.h"
+
+#include <QVector3D>
+
+namespace Qt3D {
+
+class TranslateTransform : public AbstractTransform
+{
+ Q_OBJECT
+
+ Q_PROPERTY(float dx READ dx WRITE setDx NOTIFY translateChanged)
+ Q_PROPERTY(float dy READ dy WRITE setDy NOTIFY translateChanged)
+ Q_PROPERTY(float dz READ dz WRITE setDz NOTIFY translateChanged)
+ Q_PROPERTY(QVector3D t READ translation WRITE setTranslation NOTIFY translateChanged)
+
+public:
+ explicit TranslateTransform(Node *parent = 0);
+
+ float dx() const;
+ float dy() const;
+ float dz() const;
+
+ QVector3D translation() const;
+
+ virtual QMatrix4x4 matrix() const;
+
+public slots:
+ void setDx(float arg);
+ void setDy(float arg);
+ void setDz(float arg);
+
+ void setTranslation(QVector3D arg);
+
+signals:
+ void translateChanged();
+
+private:
+ QVector3D m_translation;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_TRANSLATETRANSFORM_H
diff --git a/src/core/window.cpp b/src/core/window.cpp
new file mode 100644
index 000000000..7aee2b7cb
--- /dev/null
+++ b/src/core/window.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "window.h"
+
+#include <QDebug>
+#include <QQmlComponent>
+#include <QTimer>
+#include <QKeyEvent>
+#include <QMouseEvent>
+#include <QGuiApplication>
+
+#include "node.h"
+#include "camera.h"
+#include "entity.h"
+#include <qaspectengine.h>
+
+#include "cameracontroller.h"
+
+namespace Qt3D {
+
+Window::Window(QScreen *screen)
+ : QWindow(screen)
+ , m_engine(new QQmlEngine)
+ , m_aspectEngine(new QAspectEngine(this))
+ , m_camera(NULL)
+ , m_controller(NULL)
+
+{
+ setSurfaceType(QSurface::OpenGLSurface);
+
+ resize(1024, 768);
+
+ QSurfaceFormat format;
+ format.setVersion(4, 3);
+ format.setDepthBufferSize( 24 );
+ format.setProfile(QSurfaceFormat::CoreProfile);
+ setFormat(format);
+
+ m_aspectEngine->initialize();
+ m_aspectEngine->setWindow(this);
+
+ m_controller = new CameraController;
+
+ m_updateTimer = new QTimer(this);
+ m_updateTimer->setInterval(16);
+ connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(onUpdate()));
+}
+
+Window::~Window()
+{
+ m_aspectEngine->shutdown();
+ delete m_aspectEngine;
+}
+
+Window::Status Window::status() const
+{
+ if (!m_engine)
+ return Error;
+
+ if (!m_component)
+ return Null;
+
+ return Status(m_component->status());
+}
+
+void Window::setSource( const QUrl& source )
+{
+ if (!m_engine) {
+ qWarning() << "Window: invalid qml engine.";
+ return;
+ }
+
+ if (m_root) {
+ m_aspectEngine->shutdown();
+ m_aspectEngine->setRoot(0);
+ m_root = QSharedPointer<QObject>();
+ }
+
+ if (m_component)
+ m_component = QSharedPointer<QQmlComponent>();
+
+ if (!source.isEmpty()) {
+ m_component = QSharedPointer<QQmlComponent>(new QQmlComponent(m_engine.data(), source, this));
+ if (!m_component->isLoading()) {
+ continueExecute();
+ } else {
+ QObject::connect(m_component.data(), SIGNAL(statusChanged(QQmlComponent::Status)),
+ this, SLOT(continueExecute()));
+ }
+ }
+}
+
+void Window::continueExecute()
+{
+ qDebug() << Q_FUNC_INFO;
+
+ disconnect(m_component.data(), SIGNAL(statusChanged(QQmlComponent::Status)),
+ this, SLOT(continueExecute()));
+
+ if (m_component->isError()) {
+ QList<QQmlError> errorList = m_component->errors();
+ Q_FOREACH ( const QQmlError& error, errorList ) {
+ QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning()
+ << error;
+ }
+ emit statusChanged(status());
+ return;
+ }
+
+ QObject* obj = m_component->create();
+
+ if (m_component->isError()) {
+ QList<QQmlError> errorList = m_component->errors();
+ Q_FOREACH ( const QQmlError& error, errorList ) {
+ QMessageLogger(error.url().toString().toLatin1().constData(), error.line(), 0).warning()
+ << error;
+ }
+ emit statusChanged(status());
+ return;
+ }
+
+ setRootObject(obj);
+ emit statusChanged(status());
+}
+
+void Window::onUpdate()
+{
+ m_controller->update(1.0 / 60.0);
+}
+
+void Window::setRootObject( QObject* obj )
+{
+ if (m_root == obj)
+ return;
+
+ if (obj) {
+ obj->setParent( this );
+ m_root = QSharedPointer<QObject>(obj);
+ }
+
+ m_aspectEngine->setRoot(obj);
+
+ // Hook up controller input to camera
+ // TODO: Do this more generically as we may want keyboard ot control an Entity etc
+ m_camera = Entity::findComponentInTree<Camera>(qobject_cast<Node *>(m_root.data()));
+ if (m_camera) {
+ qDebug() << "found a camera in the scene";
+ m_controller->setCamera(m_camera);
+ m_updateTimer->start();
+ }
+
+//
+// Entity *ball = node->findChild<Entity *>(QStringLiteral("ball"));
+// if (ball) {
+// QList<Component *> components = ball->components();
+// qDebug() << components;
+// }
+
+ //Node *node = qobject_cast<Node *>(m_root.data());
+ //if (node)
+ //node->dump();
+}
+
+void Window::resizeEvent( QResizeEvent* e )
+{
+ Q_UNUSED( e );
+
+}
+
+void Window::keyPressEvent( QKeyEvent* e )
+{
+ if (m_controller->keyPressEvent(e))
+ return;
+
+ switch ( e->key() )
+ {
+ case Qt::Key_Escape:
+ QGuiApplication::quit();
+ break;
+
+ default:
+ QWindow::keyPressEvent( e );
+ }
+}
+
+void Window::keyReleaseEvent( QKeyEvent* e )
+{
+ if (m_controller->keyReleaseEvent(e))
+ return;
+
+ QWindow::keyReleaseEvent(e);
+}
+
+void Window::mousePressEvent( QMouseEvent* e )
+{
+ m_controller->mousePressEvent(e);
+}
+
+void Window::mouseReleaseEvent( QMouseEvent* e )
+{
+ m_controller->mouseReleaseEvent(e);
+}
+
+void Window::mouseMoveEvent( QMouseEvent* e )
+{
+ m_controller->mouseMoveEvent(e);
+}
+
+
+} // namespace Qt3D
diff --git a/src/core/window.h b/src/core/window.h
new file mode 100644
index 000000000..7ded46973
--- /dev/null
+++ b/src/core/window.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_WINDOW_H
+#define QT3D_WINDOW_H
+
+#include <QWindow>
+#include "qt3dcore_global.h"
+
+#include <QQmlEngine>
+
+class QTimer;
+
+namespace Qt3D {
+
+class AbstractAspect;
+class QAspectEngine;
+class Camera;
+
+// temporary solution to get control over camera
+class CameraController;
+
+class Window : public QWindow
+{
+ Q_OBJECT
+public:
+ explicit Window(QScreen *screen = 0);
+ ~Window();
+
+ void setSource( const QUrl& url );
+
+ enum Status { Null, Ready, Loading, Error };
+ Status status() const;
+
+ QSharedPointer<QObject> rootObject() { return m_root; }
+
+signals:
+ void statusChanged( Qt3D::Window::Status );
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent( QKeyEvent* e );
+
+ virtual void mousePressEvent( QMouseEvent* e );
+ virtual void mouseReleaseEvent( QMouseEvent* e );
+ virtual void mouseMoveEvent( QMouseEvent* e );
+ virtual void resizeEvent(QResizeEvent *e);
+
+private slots:
+ void continueExecute();
+
+ void onUpdate();
+
+private:
+ void setRootObject( QObject* obj );
+
+ QScopedPointer<QQmlEngine> m_engine;
+ QSharedPointer<QObject> m_root;
+ QSharedPointer<QQmlComponent> m_component;
+
+ // The various aspects (subsystems) that will be interested in (parts)
+ // of the objects in the object tree.
+ QAspectEngine *m_aspectEngine;
+
+ QList<Qt3D::AbstractAspect*> m_aspects;
+
+ Camera* m_camera;
+
+ // temporary, borrowed from training material
+ CameraController* m_controller;
+
+ QTimer* m_updateTimer;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_WINDOW_H
diff --git a/src/render/backend/drawable.cpp b/src/render/backend/drawable.cpp
new file mode 100644
index 000000000..4690a6b78
--- /dev/null
+++ b/src/render/backend/drawable.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "drawable.h"
+
+namespace Qt3D {
+
+Drawable::Drawable()
+{
+
+}
+
+Drawable::~Drawable()
+{
+
+}
+
+DrawStateSet *Drawable::stateSet()
+{
+ return NULL;
+}
+
+void Drawable::initializeGL(QGraphicsContext* dc)
+{
+ Q_UNUSED(dc);
+}
+
+void Drawable::releaseGL()
+{
+
+}
+
+#if 0
+RenderNode *Drawable::node() const
+{
+ return m_node;
+}
+#endif
+
+} // of namespace
+
diff --git a/src/render/backend/drawable.h b/src/render/backend/drawable.h
new file mode 100644
index 000000000..980891b91
--- /dev/null
+++ b/src/render/backend/drawable.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_DRAWABLE_H
+#define QT3D_DRAWABLE_H
+
+#include <QObject>
+
+#include <axisalignedboundingbox.h>
+
+namespace Qt3D {
+
+class QGraphicsContext;
+class RenderShader;
+class DrawStateSet;
+
+class Drawable
+{
+public:
+ Drawable();
+
+ virtual ~Drawable();
+
+ // RenderNode* node() const;
+
+ /**
+ * @brief make OpenGL drawing commands for this drawable.
+ *
+ * The correct context and shader will already be defined,
+ * along with the transformation state. This method will
+ * be run from the rendering thread, and hence should take
+ * care if using mutable buffer data.
+ *
+ */
+ virtual void sendDrawingCommands( QGraphicsContext* gc ) = 0;
+
+ /**
+ * @brief shader
+ * @return
+ */
+ virtual RenderShader* shader() = 0;
+
+
+ virtual DrawStateSet* stateSet();
+
+ /**
+ * @brief Called by render thread to initialize resources
+ *
+ * This will be called in the context of the renderer thread
+ * once it has a fully created OpenGL context. The shader program for
+ * this drawable will be active (so attribute data can be bound)
+ */
+ virtual void initializeGL(QGraphicsContext* dc);
+
+ virtual void releaseGL();
+
+ virtual AxisAlignedBoundingBox boundingBox() const = 0;
+
+protected:
+
+};
+
+}
+
+#endif // of QT3D_DRAWABLE_H
diff --git a/src/render/backend/drawstate.cpp b/src/render/backend/drawstate.cpp
new file mode 100644
index 000000000..08b87f961
--- /dev/null
+++ b/src/render/backend/drawstate.cpp
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "drawstate.h"
+
+#include <bitset>
+
+#include <QDebug>
+#include <QOpenGLContext>
+
+#include "qgraphicscontext.h"
+
+#include "states/blendstate.h"
+
+namespace Qt3D {
+
+DrawStateSet::DrawStateSet()
+{
+
+}
+
+void DrawStateSet::addState(DrawState *ds)
+{
+ Q_ASSERT(ds);
+ m_states.insert(ds);
+ m_stateMask |= ds->mask();
+}
+
+int DrawStateSet::changeCost(DrawStateSet *previousState)
+{
+ if (previousState == this)
+ return 0;
+
+ int cost = 0;
+
+// first, find cost of any resets
+ StateMaskSet invOurState = ~stateMask();
+ StateMaskSet stateToReset = previousState->stateMask() & invOurState;
+
+ std::bitset<64> bs(stateToReset);
+ cost += bs.count();
+
+// now, find out how many states we're changing
+ foreach (DrawState* ds, m_states) {
+ // if the other state contains matching, then doesn't
+ // contribute to cost at all
+ if (previousState->contains(ds)) {
+ continue;
+ }
+
+ // flat cost for now; could be replaced with a cost() method on
+ // DrawState
+ cost += 2;
+ }
+
+ return cost;
+}
+
+void DrawStateSet::apply(QGraphicsContext *gc)
+{
+ DrawStateSet* previousStates = gc->currentStateSet();
+
+ StateMaskSet invOurState = ~stateMask();
+ // generate a mask for each set bit in previous, where we do not have
+ // the corresponding bit set.
+ StateMaskSet stateToReset = 0;
+ if (previousStates)
+ stateToReset = previousStates->stateMask() & invOurState;
+
+ resetMasked(stateToReset, gc);
+
+ if (previousStates == m_cachedPrevious) {
+ // state-change cache hit
+ foreach (DrawState* ds, m_cachedDeltaStates) {
+ ds->apply(gc);
+ }
+ } else {
+ // compute deltas and cache for next frame
+ m_cachedDeltaStates.clear();
+ m_cachedPrevious = previousStates;
+
+ foreach (DrawState* ds, m_states) {
+ if (previousStates && previousStates->contains(ds)) {
+ continue;
+ }
+
+ m_cachedDeltaStates.append(ds);
+ ds->apply(gc);
+ }
+ }
+}
+
+StateMaskSet DrawStateSet::stateMask() const
+{
+ return m_stateMask;
+}
+
+void DrawStateSet::resetMasked(StateMaskSet maskOfStatesToReset, QGraphicsContext *gc)
+{
+ Q_UNUSED(gc);
+
+ if (maskOfStatesToReset & ScissorStateMask) {
+ glDisable(GL_SCISSOR_TEST);
+ }
+
+ if (maskOfStatesToReset & BlendStateMask) {
+ glDisable(GL_BLEND);
+ }
+
+ if (maskOfStatesToReset & StencilWriteStateMask) {
+ glStencilMask(0);
+ }
+
+ if (maskOfStatesToReset & StencilTestStateMask) {
+ glDisable(GL_STENCIL_TEST);
+ }
+
+ if (maskOfStatesToReset & DepthTestStateMask) {
+ glDisable(GL_DEPTH_TEST);
+ }
+
+ if (maskOfStatesToReset & DepthWriteStateMask) {
+ glDepthMask(GL_TRUE); // reset to default
+ }
+
+ if (maskOfStatesToReset & FrontFaceStateMask) {
+ glFrontFace(GL_CCW); // reset to default
+ }
+
+ if (maskOfStatesToReset & CullFaceStateMask) {
+ glDisable(GL_CULL_FACE);
+ }
+}
+
+bool DrawStateSet::contains(DrawState *ds) const
+{
+ // trivial reject using the state mask bits
+ if (!(ds->mask() & stateMask()))
+ return false;
+
+ return m_states.contains(ds);
+}
+
+} // namespace Qt3D
diff --git a/src/render/backend/drawstate.h b/src/render/backend/drawstate.h
new file mode 100644
index 000000000..bd7bc26ca
--- /dev/null
+++ b/src/render/backend/drawstate.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_DRAWSTATE_H
+#define QT3D_DRAWSTATE_H
+
+#include <QList>
+#include <QSet>
+
+namespace Qt3D {
+
+class QGraphicsContext;
+
+enum StateMask
+{
+ BlendStateMask = 1 << 0,
+ StencilWriteStateMask = 1 << 1,
+ StencilTestStateMask = 1 << 2,
+ ScissorStateMask = 1 << 3,
+ DepthTestStateMask = 1 << 4,
+ DepthWriteStateMask = 1 << 5,
+ CullFaceStateMask = 1 << 6,
+ AlphaTestMask = 1 << 7,
+ FrontFaceStateMask = 1 << 8
+};
+
+typedef quint64 StateMaskSet;
+
+// winuser.h has a #define called DrawState. Let's get rid of it
+#if defined(DrawState)
+#undef DrawState
+#endif
+
+class DrawState
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const = 0;
+
+ virtual StateMaskSet mask() const = 0;
+
+protected:
+};
+
+class DrawStateSet
+{
+public:
+ DrawStateSet();
+
+ void addState(DrawState* ds);
+
+ /**
+ * @brief changeCost - metric of cost to change to this state-set from
+ * a candidate previous state-set. This is used to find an optimal
+ * ordering of state-sets when sending draw commands.
+ * @param previousState
+ * @return
+ */
+ int changeCost(DrawStateSet* previousState);
+
+ void apply(QGraphicsContext* gc);
+
+ StateMaskSet stateMask() const;
+
+ void resetMasked(StateMaskSet maskOfStatesToReset, QGraphicsContext* gc);
+private:
+ /**
+ * @brief contains - check if this set contains a matching piece of state
+ * @param ds
+ * @return
+ */
+ bool contains(DrawState* ds) const;
+
+ QSet<DrawState*> m_states;
+
+ StateMaskSet m_stateMask;
+
+ DrawStateSet* m_cachedPrevious;
+ QList<DrawState*> m_cachedDeltaStates;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_DRAWSTATE_H
diff --git a/src/render/backend/framegraph/cameraselectornode.cpp b/src/render/backend/framegraph/cameraselectornode.cpp
new file mode 100644
index 000000000..d1d1bfac0
--- /dev/null
+++ b/src/render/backend/framegraph/cameraselectornode.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cameraselectornode.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+CameraSelector::CameraSelector(FrameGraphNode *parent)
+ : FrameGraphNode(parent)
+{
+}
+
+void CameraSelector::apply()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void CameraSelector::revert()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+}
+}
diff --git a/src/render/backend/framegraph/cameraselectornode.h b/src/render/backend/framegraph/cameraselectornode.h
new file mode 100644
index 000000000..326ba600b
--- /dev/null
+++ b/src/render/backend/framegraph/cameraselectornode.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CAMERASELECTOR_H
+#define CAMERASELECTOR_H
+
+#include "framegraphnode.h"
+
+namespace Qt3D {
+
+class Camera;
+
+namespace Render {
+
+class CameraSelector : public FrameGraphNode
+{
+public:
+ CameraSelector(FrameGraphNode *parent = 0);
+
+ void apply() Q_DECL_OVERRIDE;
+ void revert() Q_DECL_OVERRIDE;
+
+//private:
+ Camera *m_camera;
+};
+
+}
+}
+
+#endif // CAMERASELECTOR_H
diff --git a/src/render/backend/framegraph/framegraph.pri b/src/render/backend/framegraph/framegraph.pri
new file mode 100644
index 000000000..c04191dc5
--- /dev/null
+++ b/src/render/backend/framegraph/framegraph.pri
@@ -0,0 +1,15 @@
+HEADERS += \
+ $$PWD/cameraselectornode.h \
+ $$PWD/framegraphnode.h \
+ $$PWD/framegraphvisitor.h \
+ $$PWD/renderpassfilternode.h \
+ $$PWD/techniquefilternode.h \
+ $$PWD/viewportnode.h
+
+SOURCES += \
+ $$PWD/cameraselectornode.cpp \
+ $$PWD/framegraphnode.cpp \
+ $$PWD/framegraphvisitor.cpp \
+ $$PWD/renderpassfilternode.cpp \
+ $$PWD/techniquefilternode.cpp \
+ $$PWD/viewportnode.cpp
diff --git a/src/render/backend/framegraph/framegraphnode.cpp b/src/render/backend/framegraph/framegraphnode.cpp
new file mode 100644
index 000000000..b6b80afce
--- /dev/null
+++ b/src/render/backend/framegraph/framegraphnode.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "framegraphnode.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+FrameGraphNode::FrameGraphNode(FrameGraphNode *parent)
+ : m_parent(parent)
+ , m_enabled(true)
+{
+ if (parent)
+ parent->m_children.append(this);
+}
+
+FrameGraphNode::~FrameGraphNode()
+{
+}
+
+void FrameGraphNode::apply()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void FrameGraphNode::revert()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/framegraph/framegraphnode.h b/src/render/backend/framegraph/framegraphnode.h
new file mode 100644
index 000000000..0fd0a2e3f
--- /dev/null
+++ b/src/render/backend/framegraph/framegraphnode.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_FRAMEGRAPHNODE_H
+#define QT3D_RENDER_FRAMEGRAPHNODE_H
+
+#include <QVector>
+
+namespace Qt3D {
+namespace Render {
+
+class FrameGraphNode
+{
+public:
+ FrameGraphNode(FrameGraphNode *parent = 0);
+ virtual ~FrameGraphNode();
+
+ FrameGraphNode *parent() const { return m_parent; }
+
+ int childCount() const { return m_children.count(); }
+ FrameGraphNode * child(int index) const { return m_children.at(index); }
+
+ void setEnabled(bool enabled) { m_enabled = enabled; }
+ bool isEnabled() const { return m_enabled; }
+
+protected:
+ virtual void apply();
+ virtual void revert();
+
+private:
+ FrameGraphNode *m_parent;
+ QVector<FrameGraphNode *> m_children;
+
+ bool m_enabled;
+
+ friend class FrameGraphVisitor;
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_FRAMEGRAPHNODE_H
diff --git a/src/render/backend/framegraph/framegraphvisitor.cpp b/src/render/backend/framegraph/framegraphvisitor.cpp
new file mode 100644
index 000000000..b74a77873
--- /dev/null
+++ b/src/render/backend/framegraph/framegraphvisitor.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "framegraphvisitor.h"
+
+#include "framegraphnode.h"
+#include "renderer.h"
+
+namespace Qt3D {
+namespace Render {
+
+FrameGraphVisitor::FrameGraphVisitor()
+{
+}
+
+void FrameGraphVisitor::traverse(FrameGraphNode *root, Renderer *renderer)
+{
+ m_renderer = renderer;
+
+ // Kick off the traversal
+ FrameGraphNode *node = root;
+ visit(node);
+}
+
+void FrameGraphVisitor::visit(FrameGraphNode *node)
+{
+ // Apply the state from this node
+ node->apply();
+
+ // Recurse to children (if we have any), otherwise if this is a leaf node,
+ // initiate a rendering from the current camera
+ if (node->childCount()) {
+ for (int i = 0; i < node->childCount(); ++i) {
+ FrameGraphNode *n = node->child(i);
+ visit(n);
+ }
+ } else {
+ // Leaf node. All state is applied and renderer context configured.
+ // Go render something
+ m_renderer->doRender();
+ }
+
+ // Undo the applied state as we exit this node
+ node->revert();
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/framegraph/framegraphvisitor.h b/src/render/backend/framegraph/framegraphvisitor.h
new file mode 100644
index 000000000..174a90bdf
--- /dev/null
+++ b/src/render/backend/framegraph/framegraphvisitor.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDERER_FRAMEGRAPHVISITOR_H
+#define QT3D_RENDERER_FRAMEGRAPHVISITOR_H
+
+namespace Qt3D {
+namespace Render {
+
+class FrameGraphNode;
+class Renderer;
+
+class FrameGraphVisitor
+{
+public:
+ FrameGraphVisitor();
+
+ void traverse(FrameGraphNode *root, Renderer *renderer);
+
+private:
+ void visit(FrameGraphNode *node);
+
+ Renderer *m_renderer;
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDERER_FRAMEGRAPHVISITOR_H
diff --git a/src/render/backend/framegraph/renderpassfilternode.cpp b/src/render/backend/framegraph/renderpassfilternode.cpp
new file mode 100644
index 000000000..89b3d4e0c
--- /dev/null
+++ b/src/render/backend/framegraph/renderpassfilternode.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderpassfilternode.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+RenderPassFilter::RenderPassFilter(FrameGraphNode *parent)
+ : FrameGraphNode(parent)
+{
+}
+
+void RenderPassFilter::apply()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void RenderPassFilter::revert()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+}
+}
diff --git a/src/render/backend/framegraph/renderpassfilternode.h b/src/render/backend/framegraph/renderpassfilternode.h
new file mode 100644
index 000000000..ed05e6b5c
--- /dev/null
+++ b/src/render/backend/framegraph/renderpassfilternode.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERPASSFILTER_H
+#define RENDERPASSFILTER_H
+
+#include "framegraphnode.h"
+
+#include <QStringList>
+
+namespace Qt3D {
+namespace Render {
+
+class RenderPassFilter : public FrameGraphNode
+{
+public:
+ RenderPassFilter(FrameGraphNode *parent = 0);
+
+ void apply() Q_DECL_OVERRIDE;
+ void revert() Q_DECL_OVERRIDE;
+
+//private:
+ QStringList m_filters;
+};
+
+}
+
+}
+
+#endif // RENDERPASSFILTER_H
diff --git a/src/render/backend/framegraph/techniquefilternode.cpp b/src/render/backend/framegraph/techniquefilternode.cpp
new file mode 100644
index 000000000..3c021c77c
--- /dev/null
+++ b/src/render/backend/framegraph/techniquefilternode.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "techniquefilternode.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+TechniqueFilter::TechniqueFilter(FrameGraphNode *parent)
+ : FrameGraphNode(parent)
+{
+}
+
+void TechniqueFilter::apply()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void TechniqueFilter::revert()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+}
+}
diff --git a/src/render/backend/framegraph/techniquefilternode.h b/src/render/backend/framegraph/techniquefilternode.h
new file mode 100644
index 000000000..f6c801019
--- /dev/null
+++ b/src/render/backend/framegraph/techniquefilternode.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TECHNIQUEFILTER_H
+#define TECHNIQUEFILTER_H
+
+#include "framegraphnode.h"
+
+#include <QHash>
+#include <QString>
+#include <QVariant>
+
+namespace Qt3D {
+namespace Render {
+
+class TechniqueFilter : public FrameGraphNode
+{
+public:
+ TechniqueFilter(FrameGraphNode *parent = 0);
+
+ void apply() Q_DECL_OVERRIDE;
+ void revert() Q_DECL_OVERRIDE;
+
+//private:
+ QHash<QString, QVariant> m_filters;
+};
+
+}
+}
+
+#endif // TECHNIQUEFILTER_H
diff --git a/src/render/backend/framegraph/viewportnode.cpp b/src/render/backend/framegraph/viewportnode.cpp
new file mode 100644
index 000000000..bac967975
--- /dev/null
+++ b/src/render/backend/framegraph/viewportnode.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "viewportnode.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+ViewportNode::ViewportNode(FrameGraphNode *parent)
+ : FrameGraphNode(parent)
+ , m_xMin(0.0f)
+ , m_yMin(0.0f)
+ , m_xMax(1.0f)
+ , m_yMax(1.0f)
+{
+}
+
+void ViewportNode::apply()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void ViewportNode::revert()
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+}
+}
diff --git a/src/render/backend/framegraph/viewportnode.h b/src/render/backend/framegraph/viewportnode.h
new file mode 100644
index 000000000..6d1b643a5
--- /dev/null
+++ b/src/render/backend/framegraph/viewportnode.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEWPORT_H
+#define VIEWPORT_H
+
+#include "framegraphnode.h"
+
+namespace Qt3D {
+namespace Render {
+
+class ViewportNode : public FrameGraphNode
+{
+public:
+ ViewportNode(FrameGraphNode *parent = 0);
+
+ void apply() Q_DECL_OVERRIDE;
+ void revert() Q_DECL_OVERRIDE;
+
+//private:
+ float m_xMin;
+ float m_yMin;
+ float m_xMax;
+ float m_yMax;
+};
+
+}
+}
+
+#endif // VIEWPORT_H
diff --git a/src/render/backend/genericstate.h b/src/render/backend/genericstate.h
new file mode 100644
index 000000000..c95a6af4d
--- /dev/null
+++ b/src/render/backend/genericstate.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef STATE_IMPLS_H
+#define STATE_IMPLS_H
+
+#include <QList>
+
+#include "drawstate.h"
+
+// winuser.h has a #define called DrawState. Let's get rid of it
+#if defined(DrawState)
+#undef DrawState
+#endif
+
+namespace Qt3D
+{
+
+template <typename Derived, typename T>
+class GenericState1 : public DrawState
+{
+public:
+
+ bool isEqual(const Derived& i) const
+ { return (m_1 == i.m_1); }
+
+
+protected:
+ GenericState1(T t) :
+ m_1(t)
+ {}
+
+ T m_1;
+
+};
+
+template <typename Derived, typename T, typename S>
+class GenericState2 : public DrawState
+{
+public:
+ bool isEqual(const Derived& i) const
+ { return (m_1 == i.m_1) && (m_2 == i.m_2); }
+protected:
+ GenericState2(T t, S s) :
+ m_1(t),
+ m_2(s)
+ {}
+
+
+ T m_1;
+ S m_2;
+};
+
+template <typename Derived, typename T, typename S, typename U>
+class GenericState3
+{
+public:
+ bool isEqual(const Derived& i) const
+ { return (m_1 == i.m_1) && (m_2 == i.m_2) && (m_3 == i.m_3); }
+
+protected:
+ GenericState3(T t, S s, U u) :
+ m_1(t),
+ m_2(s),
+ m_3(u)
+ {}
+
+ T m_1;
+ S m_2;
+ U m_3;
+
+};
+
+} // of namespace
+
+#endif // STATE_IMPLS_H
diff --git a/src/render/backend/jobs/jobs.pri b/src/render/backend/jobs/jobs.pri
new file mode 100644
index 000000000..85e350fdd
--- /dev/null
+++ b/src/render/backend/jobs/jobs.pri
@@ -0,0 +1,11 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/updateworldtransformjob.h \
+ $$PWD/updateboundingvolumejob.h \
+ $$PWD/loadmeshdatajob.h
+
+SOURCES += \
+ $$PWD/updateworldtransformjob.cpp \
+ $$PWD/updateboundingvolumejob.cpp \
+ $$PWD/loadmeshdatajob.cpp \ No newline at end of file
diff --git a/src/render/backend/jobs/loadmeshdatajob.cpp b/src/render/backend/jobs/loadmeshdatajob.cpp
new file mode 100644
index 000000000..29a6047c7
--- /dev/null
+++ b/src/render/backend/jobs/loadmeshdatajob.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "loadmeshdatajob.h"
+
+#include <objloader.h>
+#include <sphere.h>
+
+#include <QDebug>
+#include <QThread>
+
+namespace Qt3D {
+namespace Render {
+
+LoadMeshDataJob::LoadMeshDataJob(const QString &source, const MeshDataPtr &meshData)
+ : QJob()
+ , m_source(source)
+ , m_meshData(meshData)
+{
+}
+
+void LoadMeshDataJob::run()
+{
+ qDebug() << "Entering" << Q_FUNC_INFO << QThread::currentThread();
+
+ // Load the mesh from disk (or wherever)
+ qDebug() << "Loading mesh from" << m_source;
+
+ ObjLoader loader;
+ loader.setLoadTextureCoordinatesEnabled(true);
+
+ if (loader.load(m_source)) {
+ qDebug() << "Loaded OBJ ok";
+ *m_meshData = *(loader.mesh());
+ } else {
+ qWarning() << Q_FUNC_INFO << "OBJ load failure for:" << m_source;
+ }
+
+ AttributePtr attr = m_meshData->attributeByName("position");
+ if (!attr) {
+ qWarning() << Q_FUNC_INFO << "unknown attribute: position";
+ return;
+ }
+
+ Qt3D::Sphere sphere = Qt3D::Sphere::fromPoints(loader.vertices());
+
+ qDebug() << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/jobs/loadmeshdatajob.h b/src/render/backend/jobs/loadmeshdatajob.h
new file mode 100644
index 000000000..e9f155e35
--- /dev/null
+++ b/src/render/backend/jobs/loadmeshdatajob.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_LOADMESHDATAJOB_H
+#define QT3D_RENDER_LOADMESHDATAJOB_H
+
+#include <qjob.h>
+
+#include <meshdata.h>
+
+#include <QSharedPointer>
+
+namespace Qt3D {
+namespace Render {
+
+class LoadMeshDataJob : public Qt3D::QJob
+{
+public:
+ LoadMeshDataJob(const QString &source,
+ const Qt3D::MeshDataPtr &meshData);
+
+protected:
+ void run() Q_DECL_OVERRIDE;
+
+private:
+ QString m_source;
+ Qt3D::MeshDataPtr m_meshData;
+};
+
+typedef QSharedPointer<LoadMeshDataJob> LoadMeshDataJobPtr;
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_LOADMESHDATAJOB_H
diff --git a/src/render/backend/jobs/updateboundingvolumejob.cpp b/src/render/backend/jobs/updateboundingvolumejob.cpp
new file mode 100644
index 000000000..0d5752ff1
--- /dev/null
+++ b/src/render/backend/jobs/updateboundingvolumejob.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "updateboundingvolumejob.h"
+
+#include <rendernode.h>
+#include <sphere.h>
+
+#include <QDebug>
+#include <QElapsedTimer>
+#include <QStack>
+#include <QThread>
+
+static void expandWorldBoundingVolume(Qt3D::Render::RenderNode *node)
+{
+ Qt3D::Render::RenderNode *currentNode = node;
+ QStack<int> childIndexStack;
+ forever {
+ // Find left most leaf node of currentNode
+ while (!currentNode->m_children.isEmpty()) {
+ childIndexStack.push(1);
+ currentNode = node->m_children.first();
+ }
+
+ if (!currentNode->m_parent)
+ return;
+
+ // Initialize parent bounding volume to be equal to that of the first child
+ Qt3D::Render::RenderNode *parentNode = currentNode->m_parent;
+ Qt3D::Sphere *parentBoundingVolume = parentNode->m_worldBoundingVolume;
+ *(parentBoundingVolume) = *(currentNode->m_worldBoundingVolume);
+
+ // Expand the parent bounding volume by each of remaining the siblings
+ const int siblingCount = parentNode->m_children.count();
+ for (int i = 1; i < siblingCount; ++i) {
+ Qt3D::Sphere *siblingBoundingVolume = parentNode->m_children.at(i)->m_worldBoundingVolume;
+ parentBoundingVolume->expandToContain(*siblingBoundingVolume);
+ }
+
+ // Move to parent's next sibling
+ childIndexStack.pop();
+ const int nextSiblingIndex = childIndexStack.top()++;
+ currentNode = parentNode->m_parent->m_children.at(nextSiblingIndex);
+ }
+}
+
+namespace Qt3D {
+namespace Render {
+
+UpdateBoundingVolumeJob::UpdateBoundingVolumeJob(RenderNode *node)
+ : m_node(node)
+{
+}
+
+void UpdateBoundingVolumeJob::run()
+{
+ // Expand the bounding volumes of each node that has children by the
+ // bounding volumes of the children
+
+ // TODO: Implement this using a parallel_for
+ qDebug() << "Entering" << Q_FUNC_INFO << QThread::currentThread();
+ expandWorldBoundingVolume(m_node);
+ qDebug() << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/jobs/updateboundingvolumejob.h b/src/render/backend/jobs/updateboundingvolumejob.h
new file mode 100644
index 000000000..81353a6c0
--- /dev/null
+++ b/src/render/backend/jobs/updateboundingvolumejob.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_UPDATEBOUNDINGVOLUMEJOB_H
+#define QT3D_RENDER_UPDATEBOUNDINGVOLUMEJOB_H
+
+#include <qjob.h>
+
+#include <QSharedPointer>
+
+namespace Qt3D {
+namespace Render {
+
+class RenderNode;
+
+class UpdateBoundingVolumeJob : public Qt3D::QJob
+{
+public:
+ explicit UpdateBoundingVolumeJob(RenderNode *m_node);
+
+protected:
+ void run() Q_DECL_OVERRIDE;
+
+private:
+ RenderNode *m_node;
+};
+
+typedef QSharedPointer<UpdateBoundingVolumeJob> UpdateBoundingVolumeJobPtr;
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_UPDATEBOUNDINGVOLUMEJOB_H
diff --git a/src/render/backend/jobs/updateworldtransformjob.cpp b/src/render/backend/jobs/updateworldtransformjob.cpp
new file mode 100644
index 000000000..04f09f9a0
--- /dev/null
+++ b/src/render/backend/jobs/updateworldtransformjob.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "updateworldtransformjob.h"
+
+#include <renderer.h>
+#include <rendernode.h>
+#include <sphere.h>
+
+#include <QDebug>
+#include <QThread>
+
+static void updateWorldTransformAndBounds(Qt3D::Render::RenderNode *node)
+{
+ QMatrix4x4 parentTransform;
+ if (node->m_parent)
+ parentTransform = *(node->m_parent->m_worldTransform);
+
+ *(node->m_worldTransform) = parentTransform * *(node->m_localTransform);
+ *(node->m_worldBoundingVolume) = node->m_localBoundingVolume->transformed(*(node->m_worldTransform));
+
+ Q_FOREACH (Qt3D::Render::RenderNode *child, node->m_children)
+ updateWorldTransformAndBounds(child);
+}
+
+namespace Qt3D {
+namespace Render {
+
+UpdateWorldTransformJob::UpdateWorldTransformJob(RenderNode *node)
+ : Qt3D::QJob()
+ , m_node(node)
+{
+}
+
+void UpdateWorldTransformJob::run()
+{
+ // Iterate over each level of hierarchy in our scene
+ // and update each node's world transform from its
+ // local transform and its parent's world transform
+
+ // TODO: Parallelise this on each level using a parallel_for
+ // implementation.
+
+ qDebug() << "Entering" << Q_FUNC_INFO << QThread::currentThread();
+ updateWorldTransformAndBounds(m_node);
+ qDebug() << "Exiting" << Q_FUNC_INFO << QThread::currentThread();
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/jobs/updateworldtransformjob.h b/src/render/backend/jobs/updateworldtransformjob.h
new file mode 100644
index 000000000..64117e893
--- /dev/null
+++ b/src/render/backend/jobs/updateworldtransformjob.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_UPDATEWORLDTRANSFORMJOB_H
+#define QT3D_RENDER_UPDATEWORLDTRANSFORMJOB_H
+
+#include <qjob.h>
+
+#include <QSharedPointer>
+
+namespace Qt3D {
+namespace Render {
+
+class RenderNode;
+
+class UpdateWorldTransformJob : public QJob
+{
+public:
+ explicit UpdateWorldTransformJob(RenderNode *node);
+
+protected:
+ void run() Q_DECL_OVERRIDE;
+
+private:
+ RenderNode *m_node;
+};
+
+typedef QSharedPointer<UpdateWorldTransformJob> UpdateWorldTransformJobPtr;
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_UPDATEWORLDTRANSFORMJOB_H
diff --git a/src/render/backend/meshmanager.cpp b/src/render/backend/meshmanager.cpp
new file mode 100644
index 000000000..8c8e2f741
--- /dev/null
+++ b/src/render/backend/meshmanager.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "meshmanager.h"
+
+namespace Qt3D {
+namespace Render {
+
+MeshManager::MeshManager(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void MeshManager::addMesh(Qt3D::Mesh *frontEndMesh)
+{
+ MeshDataPtr meshData(new MeshData);
+ m_meshesByPeer.insert(frontEndMesh, meshData);
+
+ // TODO: Protect access to front end data
+ m_meshesBySource.insert(frontEndMesh->source(), meshData);
+
+ m_meshesPending.append(qMakePair(frontEndMesh->source(), meshData));
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/meshmanager.h b/src/render/backend/meshmanager.h
new file mode 100644
index 000000000..93379a18e
--- /dev/null
+++ b/src/render/backend/meshmanager.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_MESHMANAGER_H
+#define QT3D_RENDER_MESHMANAGER_H
+
+#include <QObject>
+
+#include <mesh.h>
+#include <meshdata.h>
+
+#include <QHash>
+#include <QPair>
+#include <QString>
+
+namespace Qt3D {
+namespace Render {
+
+class MeshManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit MeshManager(QObject *parent = 0);
+
+ void addMesh(Qt3D::Mesh *frontEndMesh);
+
+ QList< QPair<QString, MeshDataPtr> > meshesPending() const { return m_meshesPending; }
+ void clearMeshesPending() { m_meshesPending.clear(); }
+
+private:
+ // TODO What unique id do we want to index by?
+ QHash<QString, Qt3D::MeshDataPtr> m_meshesBySource;
+ QHash<Qt3D::Mesh *, Qt3D::MeshDataPtr> m_meshesByPeer;
+
+ // List of meshes that we need to schedule jobs to load
+ // and calculate bounds for.
+ QList< QPair<QString,MeshDataPtr> > m_meshesPending;
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_MESHMANAGER_H
diff --git a/src/render/backend/qgraphicscontext.cpp b/src/render/backend/qgraphicscontext.cpp
new file mode 100644
index 000000000..03469fe0c
--- /dev/null
+++ b/src/render/backend/qgraphicscontext.cpp
@@ -0,0 +1,466 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qgraphicscontext.h"
+
+#include "rendercamera.h"
+#include "rendershader.h"
+#include "rendermaterial.h"
+#include "rendertexture.h"
+
+#include <QDebug>
+#include <QOpenGLShaderProgram>
+#include <QOpenGLFunctions_3_3_Core>
+#include <QSurface>
+#include <QOpenGLTexture>
+
+namespace Qt3D
+{
+
+static QHash<unsigned int, QGraphicsContext*> static_contexts;
+
+unsigned int nextFreeContextId()
+{
+ for (unsigned int i=0; i < 0xffff; ++i) {
+ if (!static_contexts.contains(i))
+ return i;
+ }
+
+ qFatal("Couldn't find free context ID");
+ return 0;
+}
+
+QGraphicsContext::QGraphicsContext()
+ : m_initialized(false)
+ , m_id(nextFreeContextId())
+ , m_surface(0)
+ , m_funcs(0)
+ , m_activeShader(0)
+ , m_camera(0)
+ , m_material(0)
+ , m_stateSet(0)
+{
+ static_contexts[m_id] = this;
+}
+
+QGraphicsContext::~QGraphicsContext()
+{
+ releaseOpenGL();
+
+ Q_ASSERT(static_contexts[m_id] == this);
+ static_contexts.remove(m_id);
+}
+
+void QGraphicsContext::setSurface(QSurface *s)
+{
+ m_surface = s;
+}
+
+void QGraphicsContext::initialize()
+{
+ m_initialized = true;
+
+ Q_ASSERT(m_gl);
+
+ GLint numTexUnits;
+ glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &numTexUnits);
+ qDebug() << "context supports" << numTexUnits << "texture units";
+
+ m_pinnedTextureUnits = QBitArray(numTexUnits);
+ m_activeTextures.resize(numTexUnits);
+ m_textureScopes.resize(numTexUnits);
+}
+
+void QGraphicsContext::beginDrawing()
+{
+ if (!m_gl || !m_surface) {
+ qWarning() << Q_FUNC_INFO << "no content or surface provided";
+ return;
+ }
+
+ bool ok = m_gl->makeCurrent(m_surface);
+ if (!ok) {
+ qWarning() << Q_FUNC_INFO << "make current failed";
+ }
+
+ GLint err = glGetError();
+ if (err != 0) {
+ qWarning() << Q_FUNC_INFO << "glGetError:" << err;
+ }
+
+ if (!m_initialized) {
+ initialize();
+ }
+
+ QVector4D cc = m_camera->clearColor();
+ glClearColor(cc[0], cc[1], cc[2], cc[3]);
+ glClear(m_camera->clearMask());
+
+ QRectF vp(m_camera->viewport());
+ // default to the entire surface
+ if (vp.isEmpty())
+ vp = QRectF(QPointF(0,0), m_surface->size());
+ glViewport(vp.x(), vp.y(), vp.width(), vp.height());
+
+ if (m_activeShader)
+ m_activeShader = NULL;
+}
+
+void QGraphicsContext::endDrawing()
+{
+ m_gl->doneCurrent();
+ m_gl->swapBuffers(m_surface);
+
+ decayTextureScores();
+}
+
+void QGraphicsContext::setCamera(RenderCamera *rcam)
+{
+ m_camera = rcam;
+}
+
+RenderCamera *QGraphicsContext::camera() const
+{
+ return m_camera;
+}
+
+
+QMatrix4x4 QGraphicsContext::projectionMatrix() const
+{
+ return m_camera->projection();
+}
+
+QMatrix4x4 QGraphicsContext::viewMatrix() const
+{
+ return m_camera->view();
+}
+
+void QGraphicsContext::releaseOpenGL()
+{
+ // m_shaderHash.clear
+ m_bufferHash.clear();
+}
+
+void QGraphicsContext::setOpenGLContext(QOpenGLContext* ctx)
+{
+ releaseOpenGL();
+ m_gl = ctx;
+ // m_gl->setParent(this);
+
+ m_funcs = m_gl->versionFunctions<QOpenGLFunctions_3_3_Core>();
+ if (m_funcs)
+ m_funcs->initializeOpenGLFunctions();
+}
+
+void QGraphicsContext::activateShader(RenderShader *shader)
+{
+ if (shader == NULL) {
+ m_activeShader = NULL;
+ m_material = NULL;
+ m_funcs->glUseProgram(0);
+ return;
+ }
+
+ if (!m_shaderHash.contains(shader)) {
+ QOpenGLShaderProgram* prog = shader->getOrCreateProgram();
+ Q_ASSERT(prog);
+ m_shaderHash[shader] = prog;
+ m_activeShader = NULL;
+ }
+
+ if (m_activeShader == shader) {
+ // no op
+ } else {
+ m_activeShader = shader;
+ QOpenGLShaderProgram* prog = m_shaderHash[shader];
+ prog->bind();
+
+ // ensure material uniforms are re-applied
+ m_material = NULL;
+ }
+}
+
+void QGraphicsContext::setActiveMaterial(RenderMaterial *rmat)
+{
+ if (m_material == rmat)
+ return;
+
+ deactivateTexturesWithScope(TextureScopeMaterial);
+ m_material = rmat;
+}
+
+void QGraphicsContext::setModelMatrix(const QMatrix4x4& modelMat)
+{
+ const QVector<int>& locs(m_activeShader->standardUniformLocations());
+ QOpenGLShaderProgram* prog = activeShader();
+
+ GLint progId;
+ glGetIntegerv(GL_CURRENT_PROGRAM, &progId);
+ if (progId != (int) prog->programId()) {
+ qWarning() << "current program mismatch, very bad:" << progId << prog->programId();
+ return;
+ }
+
+ int sz = locs.size();
+ for (int i=0; i<sz; ++i) {
+ Parameter::StandardUniform su = static_cast<Parameter::StandardUniform>(i);
+ int loc = locs.at(i);
+ if (loc == -1)
+ continue;
+
+ switch (su) {
+ case Parameter::None: break;
+
+ case Parameter::ModelMatrix:
+ prog->setUniformValue(loc, modelMat); break;
+
+ case Parameter::ViewMatrix:
+ prog->setUniformValue(loc, viewMatrix()); break;
+
+ case Parameter::ProjectionMatrix:
+ prog->setUniformValue(loc, projectionMatrix()); break;
+
+ case Parameter::ModelView:
+ prog->setUniformValue(loc, viewMatrix() * modelMat); break;
+
+ case Parameter::ModelViewProjection:
+ prog->setUniformValue(loc, projectionMatrix() * viewMatrix() * modelMat); break;
+
+ case Parameter::ModelInverse:
+ prog->setUniformValue(loc, modelMat.inverted()); break;
+
+ case Parameter::ViewInverse:
+ prog->setUniformValue(loc, viewMatrix().inverted()); break;
+
+ case Parameter::ProjectionInverse:
+ prog->setUniformValue(loc, projectionMatrix().inverted()); break;
+
+ case Parameter::ModelViewInverse:
+ prog->setUniformValue(loc, (viewMatrix() * modelMat).inverted()); break;
+
+ case Parameter::ModelViewProjectionInverse:
+ prog->setUniformValue(loc, (projectionMatrix() * viewMatrix() * modelMat).inverted());
+ break;
+
+ case Parameter::ModelNormal:
+ prog->setUniformValue(loc, modelMat.normalMatrix());
+ break;
+
+ case Parameter::ModelViewNormal:
+ prog->setUniformValue(loc, (viewMatrix() * modelMat).normalMatrix());
+ break;
+ }
+
+ int err = glGetError();
+ if (err)
+ qWarning() << "GL error after setting matrix" << QString::number(err, 16) << i << loc;
+
+ } // of standard uniforms
+}
+
+int QGraphicsContext::activateTexture(TextureScope scope, RenderTexture *tex, int onUnit)
+{
+ if (onUnit == -1) {
+ onUnit = assignUnitForTexture(tex);
+
+ // check we didn't overflow the available units
+ if (onUnit == -1)
+ return onUnit;
+ }
+
+ // actually re-bind if required
+ if (m_activeTextures[onUnit] != tex) {
+ QOpenGLTexture* glTex = tex->getOrCreateGLTexture();
+ glTex->bind(onUnit);
+ }
+
+ int err = glGetError();
+ if (err)
+ qWarning() << "GL error after activating texture" << QString::number(err, 16)
+ << tex->textureId() << "on unit" << onUnit;
+
+ m_textureScores[tex] = 200;
+ m_pinnedTextureUnits[onUnit] = true;
+ m_textureScopes[onUnit] = scope;
+
+ return onUnit;
+}
+
+void QGraphicsContext::deactivateTexturesWithScope(TextureScope ts)
+{
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (!m_pinnedTextureUnits[u])
+ continue; // inactive, ignore
+
+ if (m_textureScopes[u] == ts) {
+ m_pinnedTextureUnits[u] = false;
+ }
+ } // of units iteration
+}
+
+void QGraphicsContext::deactivateTexture(RenderTexture* tex)
+{
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (m_activeTextures[u] == tex) {
+ Q_ASSERT(m_pinnedTextureUnits[u]);
+ m_pinnedTextureUnits[u] = false;
+ return;
+ }
+ } // of units iteration
+
+ qWarning() << Q_FUNC_INFO << "texture not active:" << tex;
+}
+
+void QGraphicsContext::setCurrentStateSet(DrawStateSet *ss)
+{
+ if (ss == m_stateSet)
+ return;
+
+ ss->apply(this);
+ m_stateSet = ss;
+}
+
+DrawStateSet *QGraphicsContext::currentStateSet() const
+{
+ return m_stateSet;
+}
+
+GLint QGraphicsContext::assignUnitForTexture(RenderTexture *tex)
+{
+ int lowestScoredUnit = -1;
+ int lowestScore = 0xfffffff;
+
+ for (int u=0; u<m_activeTextures.size(); ++u) {
+ if (m_activeTextures[u] == tex) {
+ return u;
+ }
+
+ if (!m_pinnedTextureUnits[u]) {
+ int score = m_textureScores[tex];
+ if (score < lowestScore) {
+ lowestScore = score;
+ lowestScoredUnit = u;
+ }
+ }
+ } // of units iteration
+
+ if (lowestScoredUnit == -1) {
+ qWarning() << Q_FUNC_INFO << "NO free texture units!";
+ return GL_INVALID_VALUE;
+ }
+
+ return lowestScoredUnit;
+}
+
+void QGraphicsContext::decayTextureScores()
+{
+ // FIXME - very inefficient use of QHash here, both for
+ // traversal coherency and subsequent modification.
+ Q_FOREACH (RenderTexture* t, m_textureScores.keys()) {
+ if ((m_textureScores[t]--) <= 0) {
+ qDebug() << "removing inactive texture" << t;
+ m_textureScores.remove((t));
+ }
+ }
+}
+
+QOpenGLShaderProgram* QGraphicsContext::activeShader()
+{
+ Q_ASSERT(m_activeShader);
+ return m_shaderHash[m_activeShader];
+}
+
+
+void QGraphicsContext::specifyAttribute(QString nm, AttributePtr attr)
+{
+ QOpenGLBuffer buf = glBufferFor(attr->buffer());
+ buf.bind();
+
+ QOpenGLShaderProgram* prog = activeShader();
+ int location = prog->attributeLocation(nm);
+ if (location < 0) {
+ qWarning() << "failed to resolve location for attribute:" << nm;
+ return;
+ }
+
+ prog->enableAttributeArray(location);
+ prog->setAttributeBuffer(location,
+ elementType(attr->type()),
+ attr->byteOffset(),
+ tupleSizeFromType(attr->type()),
+ attr->byteStride());
+
+ if (attr->divisor() != 0) {
+ // TODO - only if supported!
+ m_funcs->glVertexAttribDivisor(location, attr->divisor());
+ }
+
+ buf.release();
+}
+
+void QGraphicsContext::specifyIndices(AttributePtr attr)
+{
+ if (attr->buffer()->type() != QOpenGLBuffer::IndexBuffer) {
+ qWarning() << Q_FUNC_INFO << "provided buffer is not correct type";
+ return;
+ }
+
+ QOpenGLBuffer buf = glBufferFor(attr->buffer());
+ if (!buf.bind())
+ qWarning() << Q_FUNC_INFO << "binding index buffer failed";
+
+ // bind within the current VAO
+}
+
+QOpenGLBuffer QGraphicsContext::glBufferFor(BufferPtr buf)
+{
+ if (m_bufferHash.contains(buf))
+ return m_bufferHash.value(buf);
+
+ QOpenGLBuffer glbuf = buf->createGL();
+ m_bufferHash[buf] = glbuf;
+ buf->upload(glbuf);
+
+ return glbuf;
+}
+
+} // of namespace
+
diff --git a/src/render/backend/qgraphicscontext.h b/src/render/backend/qgraphicscontext.h
new file mode 100644
index 000000000..f79695d7b
--- /dev/null
+++ b/src/render/backend/qgraphicscontext.h
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGRAPHICSCONTEXT_H
+#define QGRAPHICSCONTEXT_H
+
+#include <QOpenGLContext>
+#include <QOpenGLBuffer>
+#include <QOpenGLVertexArrayObject>
+#include <QHash>
+#include <QMatrix4x4>
+#include <QBitArray>
+
+#include <rendercamera.h>
+#include <meshdata.h>
+
+class QOpenGLShaderProgram;
+class QOpenGLFunctions_3_3_Core;
+
+namespace Qt3D
+{
+
+class RenderShader;
+class RenderCamera;
+class RenderMaterial;
+class RenderTexture;
+class DrawStateSet;
+
+enum TextureScope
+{
+ TextureScopeMaterial = 0,
+ TextureScopeTechnique
+ // per-pass for deferred rendering?
+};
+
+class QGraphicsContext
+{
+public:
+ QGraphicsContext();
+ ~QGraphicsContext();
+
+ void setSurface(QSurface* s);
+
+ int id() const; // unique, small integer ID of this context
+
+ void beginDrawing();
+
+ void endDrawing();
+
+ void setCamera(RenderCamera* rcam);
+ RenderCamera* camera() const;
+
+ QMatrix4x4 projectionMatrix() const;
+ QMatrix4x4 viewMatrix() const;
+
+ /**
+ * @brief releaseGL - release all OpenGL objects associated with
+ * this context
+ */
+ void releaseOpenGL();
+ void setOpenGLContext(QOpenGLContext* ctx);
+ QOpenGLContext *openGLContext() { return m_gl; }
+
+ void activateShader(RenderShader* shader);
+
+ RenderMaterial* activeMaterial() const
+ { return m_material; }
+
+ void setActiveMaterial(RenderMaterial* rmat);
+
+ /**
+ * @brief activeShader
+ * @return
+ */
+ QOpenGLShaderProgram* activeShader();
+
+ void specifyAttribute(QString nm, AttributePtr attr);
+
+ void specifyIndices(AttributePtr attr);
+
+ /**
+ * @brief glBufferFor - given a client-side (CPU) buffer, provide the
+ * context-specific object. Initial call will create the buffer.
+ * @param buf
+ * @return
+ */
+ QOpenGLBuffer glBufferFor(BufferPtr buf);
+
+ void setModelMatrix(const QMatrix4x4 &modelMat);
+
+ /**
+ * @brief activateTexture - make a texture active on a hardware unit
+ * @param tex - the texture to activate
+ * @param onUnit - option, specify the explicit unit to activate on
+ * @return - the unit the texture was activated on
+ */
+ int activateTexture(TextureScope scope, RenderTexture* tex, int onUnit = -1);
+
+ void deactivateTexture(RenderTexture *tex);
+
+ void setCurrentStateSet(DrawStateSet* ss);
+ DrawStateSet* currentStateSet() const;
+private:
+ void initialize();
+
+ void decayTextureScores();
+
+ GLint assignUnitForTexture(RenderTexture* tex);
+ void deactivateTexturesWithScope(TextureScope ts);
+
+
+ bool m_initialized;
+ const unsigned int m_id;
+ QOpenGLContext* m_gl;
+ QSurface* m_surface;
+
+ QOpenGLFunctions_3_3_Core *m_funcs;
+ RenderShader* m_activeShader;
+ QHash<RenderShader*, QOpenGLShaderProgram*> m_shaderHash;
+ QHash<BufferPtr,QOpenGLBuffer> m_bufferHash;
+
+ // active textures, indexed by texture unit
+ QVector<RenderTexture*> m_activeTextures;
+ QBitArray m_pinnedTextureUnits;
+ QVector<TextureScope> m_textureScopes;
+
+ // recency score for all render-textures we've seen. Higher scores
+ // mean more recently used.
+ QHash<RenderTexture*, int> m_textureScores;
+
+ RenderCamera* m_camera;
+ RenderMaterial* m_material;
+
+ DrawStateSet* m_stateSet;
+};
+
+}
+
+#endif // QGRAPHICSCONTEXT_H
diff --git a/src/render/backend/quniformvalue.cpp b/src/render/backend/quniformvalue.cpp
new file mode 100644
index 000000000..8c88b62a6
--- /dev/null
+++ b/src/render/backend/quniformvalue.cpp
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "quniformvalue.h"
+
+#include "qgraphicscontext.h"
+#include "rendertexture.h"
+
+#include <QOpenGLShaderProgram>
+#include <QDebug>
+#include <QColor>
+#include <QQuaternion>
+
+namespace Qt3D { namespace Render {
+
+QUniformValue::QUniformValue() :
+ m_type(Invalid),
+ m_count(-1),
+ m_tupleSize(0)
+{
+}
+
+QUniformValue::QUniformValue(Type type, QVariant value) :
+ m_type(type),
+ m_count(-1),
+ m_tupleSize(0)
+{
+ fromVariant(value);
+ Q_ASSERT((m_tupleSize >= 1) && (m_tupleSize <= 4));
+}
+
+QUniformValue::QUniformValue(const QVector4D &f) :
+ m_type(Float)
+{
+ m_var = QVariant(f);
+ QVector4D v(f); // need to make a local copy to take the address
+ setRawFromFloats(&v[0], 1, 4);
+}
+
+void QUniformValue::fromVariant(QVariant v)
+{
+ if (!v.isValid())
+ return;
+
+ if (m_var == v)
+ return;
+ m_var = v;
+
+ switch (m_type) {
+ case Int:
+ case UInt:
+ fromVariantToInt(v);
+ break;
+
+ case Float:
+ fromVariantToFloat(v);
+ break;
+
+ // doubles, if the extension is present
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported internal type" << m_type;
+ }
+}
+
+void QUniformValue::fromVariantToInt(QVariant v)
+{
+ switch (v.type()) {
+ case QVariant::Int:
+ case QVariant::UInt:
+ case QVariant::Double: {
+ qint32 i = static_cast<qint32>(v.toInt());
+ setRawFromInts(&i, 1, 1);
+ break;
+ }
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported type" << v;
+ }
+}
+
+void QUniformValue::fromVariantToFloat(QVariant v)
+{
+ float* bufPtr = NULL;
+
+ switch (v.type()) {
+ case QVariant::Int:
+ case QVariant::UInt:
+ case QVariant::Double: {
+ float f = static_cast<float>(v.toDouble());
+ setRawFromFloats(&f, 1, 1);
+ break;
+ }
+
+ case QVariant::Vector2D: {
+ QVector2D v2 = v.value<QVector2D>();
+ setRawFromFloats(&v2[0], 1, 2);
+ break;
+ }
+
+ case QVariant::Vector3D: {
+ QVector3D v3 = v.value<QVector3D>();
+ setRawFromFloats(&v3[0], 1, 3);
+ break;
+ }
+
+ case QVariant::Vector4D: {
+ QVector4D v4 = v.value<QVector4D>();
+ setRawFromFloats(&v4[0], 1, 4);
+ break;
+ }
+
+ case QVariant::Matrix4x4: {
+ QMatrix4x4 m = v.value<QMatrix4x4>();
+ setRawFromFloats(m.constData(), 4, 4);
+ break;
+ }
+
+ case QVariant::Color: {
+ qDebug() << "XXXXXXX setting from" << v;
+ m_bytes.resize(sizeof(float) * 4);
+ m_count = 1;
+ m_tupleSize = 4;
+ QColor c = v.value<QColor>();
+ *bufPtr++ = c.redF();
+ *bufPtr++ = c.greenF();
+ *bufPtr++ = c.blueF();
+ *bufPtr++ = c.alphaF();
+ break;
+ }
+
+ case QVariant::Quaternion: {
+ QVector4D qv = v.value<QQuaternion>().toVector4D();
+ setRawFromFloats(&qv[0], 1, 4);
+ break;
+ }
+
+ case QVariant::List: {
+ QVariantList vl = v.toList();
+
+ // implement me ...
+
+ break;
+ }
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported QVariant type";
+ }
+}
+
+void QUniformValue::setRawFromFloats(const float* ptr, unsigned int count, unsigned int tupleSize)
+{
+ m_bytes.resize(sizeof(float) * count * tupleSize);
+ memcpy(m_bytes.data(), ptr, m_bytes.size());
+ m_count = count;
+ m_tupleSize = tupleSize;
+}
+
+void QUniformValue::setRawFromInts(const qint32* ptr, unsigned int count, unsigned int tupleSize)
+{
+ m_bytes.resize(sizeof(qint32) * count * tupleSize);
+ memcpy(m_bytes.data(), ptr, m_bytes.size());
+ m_count = count;
+ m_tupleSize = tupleSize;
+}
+
+void QUniformValue::apply(QGraphicsContext *gc, int location, QString nm) const
+{
+ switch (m_type) {
+#if 0
+ case Int:
+ switch (m_tupleSize) {
+
+ }
+
+ gc->activeShader()->setUniformValueArray(location,
+ reinterpret_cast<const GLint*>(m_bytes.constData()),
+ m_count * m_tupleSize);
+ glUni
+
+ break;
+
+ case UInt:
+ gc->activeShader()->setUniformValueArray(location,
+ reinterpret_cast<const GLuint*>(m_bytes.constData()),
+ m_count * m_tupleSize);
+ break;
+#endif
+
+ case Float:
+ gc->activeShader()->setUniformValueArray(location,
+ reinterpret_cast<const GLfloat*>(m_bytes.constData()),
+ m_count, m_tupleSize);
+ break;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported type:" << m_type;
+ }
+
+ int err = glGetError();
+ if (err) {
+ qWarning() << "error after setting uniform" << m_count << location << m_tupleSize << nm;
+ }
+}
+
+void QUniformValue::convertToBytes() const
+{
+ if (!m_bytes.isEmpty())
+ return; // use cahced conversion
+}
+
+void QUniformPack::setUniform(QString glslName, QUniformValue val)
+{
+ for (int u=0; u<m_uniforms.size(); ++u) {
+ if (m_uniforms[u].glslName != glslName) {
+ continue;
+ }
+
+ m_uniforms[u].uval = val;
+ return;
+ }
+
+ NamedUniform nu;
+ nu.glslName = glslName;
+ nu.uval = val;
+ m_uniforms.append(nu);
+}
+
+void QUniformPack::setTexture(QString glslName, RenderTexturePtr tex)
+{
+ for (int t=0; t<m_textures.size(); ++t) {
+ if (m_textures[t].glslName != glslName) {
+ continue;
+ }
+
+ m_textures[t].tex = tex;
+ return;
+ }
+
+ m_textures.append(NamedTexture(glslName, tex));
+}
+
+void QUniformPack::apply(QGraphicsContext *gc)
+{
+ for (int u=0; u<m_uniforms.size(); ++u) {
+ int loc = m_uniforms[u].location;
+ if (loc == -1) {
+ loc = gc->activeShader()->uniformLocation(m_uniforms[u].glslName);
+ m_uniforms[u].location = loc;
+ }
+
+ m_uniforms[u].uval.apply(gc, loc, m_uniforms[u].glslName);
+ } // of uniforms iteration
+
+ for (int t=0; t<m_textures.size(); ++t) {
+ int loc = m_textures[t].location;
+ if (loc == -1) {
+ loc = gc->activeShader()->uniformLocation(m_textures[t].glslName);
+ m_textures[t].location = loc;
+ }
+
+ int unit = gc->activateTexture(TextureScopeMaterial, m_textures[t].tex.data());
+ gc->activeShader()->setUniformValue(loc, unit);
+ } // of textures iteration
+}
+
+} } // of namespace Qt3D::Render
+
diff --git a/src/render/backend/quniformvalue.h b/src/render/backend/quniformvalue.h
new file mode 100644
index 000000000..eb642e950
--- /dev/null
+++ b/src/render/backend/quniformvalue.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUNIFORMVALUE_H
+#define QUNIFORMVALUE_H
+
+#include <QVariant>
+#include <QByteArray>
+#include <QVector>
+
+// for RenderTexturePtr
+#include <rendertextureprovider.h>
+
+namespace Qt3D {
+
+class QGraphicsContext;
+
+namespace Render {
+
+/**
+ * @brief The QUniformValue class - immutable storage of uniform value
+ * in the rendering backend.
+ */
+class QUniformValue
+{
+public:
+ enum Type {
+ Invalid = 0,
+ Int = 1,
+ UInt = 2,
+ Float = 3,
+ Double = 4,
+ Bool
+ };
+
+ QUniformValue();
+
+ QUniformValue(Type type, QVariant value);
+
+ // explicit construction from various types without going through
+ // QVariant boxing + unboxing. Add as needed if this proves useful
+ explicit QUniformValue(const QVector4D& foo);
+
+ void apply(QGraphicsContext* gc, int location, QString nm) const;
+
+private:
+ void convertToBytes() const;
+
+ Type m_type;
+ int m_count;
+ unsigned int m_tupleSize;
+
+ QVariant m_var;
+ // value as data suitable for passing to glUniformfv/iv
+ mutable QByteArray m_bytes;
+
+ void fromVariant(QVariant v);
+ void fromVariantToInt(QVariant v);
+ void fromVariantToFloat(QVariant v);
+
+ void setRawFromFloats(const float *ptr, unsigned int count, unsigned int tupleSize);
+ void setRawFromInts(const qint32 *ptr, unsigned int count, unsigned int tupleSize);
+};
+
+class QUniformPack
+{
+public:
+ void setUniform(QString glslName, QUniformValue val);
+
+ void setTexture(QString glslName, RenderTexturePtr tex);
+
+ void apply(QGraphicsContext* gc);
+private:
+
+ struct NamedUniform {
+ NamedUniform() : location(-1) { }
+
+ QString glslName;
+ int location;
+ QUniformValue uval;
+ };
+
+ QVector<NamedUniform> m_uniforms;
+
+ struct NamedTexture {
+ NamedTexture() : location(-1) {}
+
+ NamedTexture(QString nm, RenderTexturePtr t) :
+ glslName(nm),
+ location(-1),
+ tex(t)
+ { }
+
+ QString glslName;
+ int location;
+ RenderTexturePtr tex;
+ };
+
+ QVector<NamedTexture> m_textures;
+};
+
+}} // of namespace Qt3D::Render
+
+#endif // QUNIFORMVALUE_H
diff --git a/src/render/backend/render-backend.pri b/src/render/backend/render-backend.pri
new file mode 100644
index 000000000..468f03c9d
--- /dev/null
+++ b/src/render/backend/render-backend.pri
@@ -0,0 +1,52 @@
+INCLUDEPATH += $$PWD
+
+include("framegraph/framegraph.pri")
+include("jobs/jobs.pri")
+
+HEADERS += \
+ $$PWD/rendereraspect.h \
+ $$PWD/renderthread.h \
+ $$PWD/renderconfiguration.h \
+ $$PWD/renderdevice.h \
+ $$PWD/renderer.h \
+ $$PWD/rendermaterial.h \
+ $$PWD/drawable.h \
+ $$PWD/rendermesh.h \
+ $$PWD/qgraphicscontext.h \
+ $$PWD/renderbin.h \
+ $$PWD/rendershader.h \
+ $$PWD/rendertechnique.h \
+ $$PWD/rendercamera.h \
+ $$PWD/quniformvalue.h \
+ $$PWD/rendernode.h \
+ $$PWD/renderscenebuilder.h \
+ $$PWD/rendertexture.h \
+ $$PWD/rendertextureprovider.h \
+ $$PWD/meshmanager.h \
+ $$PWD/drawstate.h \
+ $$PWD/states/blendstate.h \
+ $$PWD/genericstate.h
+
+
+SOURCES += \
+ $$PWD/rendereraspect.cpp \
+ $$PWD/renderthread.cpp \
+ $$PWD/renderconfiguration.cpp \
+ $$PWD/renderdevice.cpp \
+ $$PWD/renderer.cpp \
+ $$PWD/rendermaterial.cpp \
+ $$PWD/drawable.cpp \
+ $$PWD/rendermesh.cpp \
+ $$PWD/qgraphicscontext.cpp \
+ $$PWD/renderbin.cpp \
+ $$PWD/rendershader.cpp \
+ $$PWD/rendertechnique.cpp \
+ $$PWD/rendercamera.cpp \
+ $$PWD/quniformvalue.cpp \
+ $$PWD/rendernode.cpp \
+ $$PWD/renderscenebuilder.cpp \
+ $$PWD/rendertexture.cpp \
+ $$PWD/rendertextureprovider.cpp \
+ $$PWD/meshmanager.cpp \
+ $$PWD/drawstate.cpp \
+ $$PWD/states/blendstate.cpp
diff --git a/src/render/backend/renderbin.cpp b/src/render/backend/renderbin.cpp
new file mode 100644
index 000000000..62adede68
--- /dev/null
+++ b/src/render/backend/renderbin.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderbin.h"
+
+#include "drawable.h"
+#include "qgraphicscontext.h"
+#include "rendershader.h"
+#include "drawstate.h"
+
+//#define QT3D_STATE_CHANGE_DEBUG
+
+namespace Qt3D
+{
+
+
+void OpaqueBin::sendDrawingCommands(QGraphicsContext *gc)
+{
+ int shaderChangeCount = 0,
+ stateSetChangeCount = 0,
+ batchSize = 0;
+ bool resetBatch = false;
+
+ RenderShader* sh = NULL;
+ DrawStateSet* ss = NULL;
+
+ foreach (Drawable* d, m_drawables) {
+ resetBatch = false;
+
+ if (sh != d->shader()) {
+ sh = d->shader();
+ gc->activateShader(sh);
+ ++shaderChangeCount;
+ #if defined(QT3D_STATE_CHANGE_DEBUG)
+ qDebug() << "did shader change to" << sh->name();
+ #endif
+ resetBatch = true;
+ }
+
+ if (ss != d->stateSet()) {
+ ss = d->stateSet();
+ gc->setCurrentStateSet(ss);
+ ++stateSetChangeCount;
+ #if defined(QT3D_STATE_CHANGE_DEBUG)
+ qDebug() << "did state change";
+ #endif
+ resetBatch = true;
+ }
+
+ if (resetBatch && (batchSize > 0)) {
+ #if defined(QT3D_STATE_CHANGE_DEBUG)
+ qDebug() << "previous batch was " << batchSize;
+ #endif
+ batchSize = 1;
+ } else {
+ ++batchSize;
+ }
+
+ d->sendDrawingCommands(gc);
+ }
+
+#if defined(QT3D_STATE_CHANGE_DEBUG)
+ qDebug() << "final batch:" << batchSize;
+#endif
+}
+
+void OpaqueBin::addDrawable(Drawable *dr)
+{
+ Q_CHECK_PTR(dr);
+ RenderShader* sh = dr->shader();
+ DrawStateSet* ss = dr->stateSet();
+
+ int shaderStartIndex = 0;
+ for (; shaderStartIndex <m_drawables.size(); ++ shaderStartIndex) {
+ if (m_drawables.at(shaderStartIndex)->shader() == sh) {
+ break;
+ }
+ }
+
+ if (shaderStartIndex >= m_drawables.size()) {
+ // no matching shader found, simply append
+ m_drawables.append(dr);
+ return;
+ }
+
+// find last drawable using the shader. Also check for a matching
+// DrawStateSet in case it exists (then we just insert beside)
+ int shaderEndIndex = shaderStartIndex;
+ QVector<DrawStateSet*> ssList;
+
+ for (; shaderEndIndex < m_drawables.size(); ++shaderEndIndex) {
+ if (m_drawables.at(shaderEndIndex)->shader() != sh)
+ break; // found first drawable with different shader
+
+ DrawStateSet* currentSS = m_drawables.at(shaderEndIndex)->stateSet();
+ // record each distinct state-set applicable to this shader.
+ if (ssList.empty() || ssList.back() != currentSS) {
+ ssList.append(currentSS);
+
+ // check cost delta is non-zero; if it is, the state-sets are
+ // equivalent and we can simply merge
+ if (ss->changeCost(currentSS) == 0) {
+ m_drawables.insert(shaderEndIndex, dr);
+ return;
+ }
+ }
+ } // of same-shader range-iteration
+
+ insertDrawableInRange(dr, shaderStartIndex, shaderEndIndex, ssList);
+}
+
+// select position in the (shaderStartIndex .. shaderEndIndex]
+// range based on lowest cost StateSet transition. We already know the state-sets
+// are distinct since we checked for changeCost() == 0 in the loop above
+
+void OpaqueBin::insertDrawableInRange(Drawable *dr,
+ int startIndex, int endIndex,
+ const QVector<DrawStateSet*> ssList)
+{
+ qDebug() << "inserting drawable with different state-set";
+
+// special case where there is only one existing state set
+ if (ssList.size() == 1) {
+ m_drawables.insert(endIndex, dr);
+ return;
+ }
+
+ DrawStateSet* ss = dr->stateSet();
+ DrawStateSet* prevSS = ssList.front();
+ // default to appending
+ int lowestCostIncrease = ss->changeCost(ssList.back());
+ DrawStateSet* insertBeforeSS = NULL;
+
+ // see if we can do better than appending
+ for (int i=1; i<ssList.size(); ++i) {
+ int oldCost = ssList.at(i)->changeCost(prevSS);
+ int newCost = ss->changeCost(prevSS) + ssList.at(i)->changeCost(ss);
+ int costIncrease = newCost - oldCost;
+
+ if (costIncrease < lowestCostIncrease) {
+ lowestCostIncrease = costIncrease;
+ insertBeforeSS = ssList.at(i);
+ }
+ } // of distinct state-sets iteration
+
+ if (insertBeforeSS) {
+ for (int i=startIndex; i<endIndex; ++i) {
+ if (m_drawables.at(i)->stateSet() == insertBeforeSS) {
+ m_drawables.insert(i, dr);
+ break;
+ }
+ }
+ } else {
+ // simply append
+ m_drawables.insert(endIndex, dr);
+ }
+}
+
+void OpaqueBin::removeDrawable(Drawable *dr)
+{
+ Q_CHECK_PTR(dr);
+ m_drawables.removeOne(dr);
+}
+
+
+} // of namespace
diff --git a/src/render/backend/renderbin.h b/src/render/backend/renderbin.h
new file mode 100644
index 000000000..b21c5adf0
--- /dev/null
+++ b/src/render/backend/renderbin.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERBIN_H
+#define RENDERBIN_H
+
+#include <QList>
+#include <QMap>
+
+namespace Qt3D
+{
+
+class Drawable;
+class QGraphicsContext;
+class RenderShader;
+class DrawStateSet;
+
+class RenderBin
+{
+public:
+
+ virtual void sendDrawingCommands(QGraphicsContext* gc) = 0;
+ virtual void addDrawable(Drawable* dr) = 0;
+ virtual void removeDrawable(Drawable* dr) = 0;
+
+private:
+
+};
+
+class OpaqueBin : public RenderBin
+{
+public:
+
+ virtual void sendDrawingCommands(QGraphicsContext* gc);
+
+ virtual void addDrawable(Drawable* dr);
+ virtual void removeDrawable(Drawable* dr);
+
+private:
+ QList<Drawable*> m_drawables;
+
+ void insertDrawableInRange(Drawable *dr,
+ int startIndex, int endIndex,
+ const QVector<DrawStateSet *> ssList);
+};
+
+class DepthSortedBin : public RenderBin
+{
+public:
+
+private:
+};
+
+} // of namespace
+
+#endif // RENDERBIN_H
diff --git a/src/render/backend/rendercamera.cpp b/src/render/backend/rendercamera.cpp
new file mode 100644
index 000000000..20126b9bc
--- /dev/null
+++ b/src/render/backend/rendercamera.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendercamera.h"
+#include "rendereraspect.h"
+
+#include <camera.h>
+
+#include <entity.h>
+#include <qaspectmanager.h>
+
+#include <QOpenGLContext>
+
+namespace Qt3D
+{
+
+RenderCamera::RenderCamera(RendererAspect *rendererAspect)
+ : m_rendererAspect(rendererAspect)
+ , m_peer(0)
+{
+ m_clearColor = QVector4D(0.5, 0.5, 1.0, 1.0);
+}
+
+void RenderCamera::setPeer(Camera *peer)
+{
+ m_peer = peer;
+
+ // Register for changes
+ QChangeArbiter *arbiter = m_rendererAspect->aspectManager()->changeArbiter();
+ arbiter->registerObserver(this, m_peer, MaterialParameter);
+}
+
+void RenderCamera::sync()
+{
+ // TODO Move the view matrix out of Camera and instead
+ // use the Entity's transformation (and later the Transform component).
+ Entity* e = m_peer->parentNode()->asEntity();
+
+ // HACK - in absence of an update pass
+ e->update();
+
+ // transform from world -> eye, so invert
+ m_view = e->sceneMatrix().inverted();
+}
+
+unsigned int RenderCamera::clearMask() const
+{
+ return GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+}
+
+void RenderCamera::setProjection(const QMatrix4x4 &projection)
+{
+ m_projection = projection;
+}
+
+QMatrix4x4 RenderCamera::projection() const
+{
+ return m_projection;
+}
+
+QMatrix4x4 RenderCamera::view() const
+{
+ return m_view;
+}
+
+void RenderCamera::sceneChangeEvent(const QSceneChangePtr &e)
+{
+ switch (e->m_type) {
+ case CameraProjectionMatrix: {
+ QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e);
+ QVariant propertyValue = propertyChange->m_value;
+ QMatrix4x4 viewMatrix = propertyValue.value<QMatrix4x4>();
+ m_projection = viewMatrix;
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+} // of namespace
+
diff --git a/src/render/backend/rendercamera.h b/src/render/backend/rendercamera.h
new file mode 100644
index 000000000..937076597
--- /dev/null
+++ b/src/render/backend/rendercamera.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERCAMERA_H
+#define RENDERCAMERA_H
+
+#include <qchangearbiter.h>
+
+#include <QMatrix4x4>
+#include <QRectF>
+
+namespace Qt3D
+{
+
+class Camera;
+class RendererAspect;
+
+class RenderCamera : public QObserverInterface
+{
+public:
+ RenderCamera(RendererAspect *rendererAspect);
+
+ void setPeer(Camera *peer);
+
+ // manually sync state with the peer, for the moment
+ void sync();
+
+ QVector4D clearColor() const { return m_clearColor; }
+
+ unsigned int clearMask() const;
+
+ QRectF viewport() const { return m_viewport; }
+
+ void setProjection(const QMatrix4x4 &projection);
+ QMatrix4x4 projection() const;
+
+ QMatrix4x4 view() const;
+
+ void sceneChangeEvent(const QSceneChangePtr &e) Q_DECL_OVERRIDE;
+
+private:
+ RendererAspect *m_rendererAspect;
+ Camera *m_peer;
+
+ // clip plane data
+ // ? m_zNear, m_zFar;
+
+
+ QVector4D m_clearColor;
+
+ QMatrix4x4 m_projection;
+ QMatrix4x4 m_view;
+ QRectF m_viewport;
+};
+
+}
+
+#endif // RENDERCAMERA_H
diff --git a/src/render/backend/renderconfiguration.cpp b/src/render/backend/renderconfiguration.cpp
new file mode 100644
index 000000000..ae2437461
--- /dev/null
+++ b/src/render/backend/renderconfiguration.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderconfiguration.h"
+
+namespace Qt3D {
+namespace Render {
+
+RenderConfiguration::RenderConfiguration()
+{
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/renderconfiguration.h b/src/render/backend/renderconfiguration.h
new file mode 100644
index 000000000..76a47f760
--- /dev/null
+++ b/src/render/backend/renderconfiguration.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_RENDERCONFIGURATION_H
+#define QT3D_RENDER_RENDERCONFIGURATION_H
+
+namespace Qt3D {
+namespace Render {
+
+class RenderConfiguration
+{
+public:
+ RenderConfiguration();
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_RENDERCONFIGURATION_H
diff --git a/src/render/backend/renderdevice.cpp b/src/render/backend/renderdevice.cpp
new file mode 100644
index 000000000..4648932e7
--- /dev/null
+++ b/src/render/backend/renderdevice.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderdevice.h"
+
+namespace Qt3D {
+namespace Render {
+
+RenderDevice::RenderDevice()
+{
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/renderdevice.h b/src/render/backend/renderdevice.h
new file mode 100644
index 000000000..c854eee29
--- /dev/null
+++ b/src/render/backend/renderdevice.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_RENDERDEVICE_H
+#define QT3D_RENDER_RENDERDEVICE_H
+
+namespace Qt3D {
+namespace Render {
+
+class RenderDevice
+{
+public:
+ RenderDevice();
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_RENDERDEVICE_H
diff --git a/src/render/backend/renderer.cpp b/src/render/backend/renderer.cpp
new file mode 100644
index 000000000..84ded8ebb
--- /dev/null
+++ b/src/render/backend/renderer.cpp
@@ -0,0 +1,524 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderer.h"
+
+#include <nodevisitor.h>
+#include <entity.h>
+#include <scene.h>
+
+#include "framegraph/framegraphnode.h"
+#include "framegraph/framegraphvisitor.h"
+
+#include <material.h>
+#include <mesh.h>
+#include <effect.h>
+#include <technique.h>
+#include <shaderprogram.h>
+#include <renderpass.h>
+#include <camera.h>
+#include <shape.h>
+
+#include <meshmanager.h>
+#include <rendermesh.h>
+#include <renderbin.h>
+#include <rendermaterial.h>
+#include <rendernode.h>
+#include <rendertechnique.h>
+#include <renderscenebuilder.h>
+#include <rendershader.h>
+#include <qgraphicscontext.h>
+#include <rendercamera.h>
+#include <rendertextureprovider.h>
+#include <drawstate.h>
+#include <states/blendstate.h>
+
+#include <QStack>
+#include <QDebug>
+#include <QSurface>
+
+namespace Qt3D {
+
+namespace {
+
+class TemporaryBackendBuilder : public NodeVisitor
+{
+public:
+ TemporaryBackendBuilder(Render::Renderer* r) :
+ m_renderer(r)
+ {
+
+ }
+
+protected:
+ virtual void visitEntity(Entity* ent)
+ {
+ ent->update();
+
+ bool haveMaterial = false;
+ QList<Material*> mats = ent->componentsOfType<Material>();
+ if (!mats.empty()) {
+ haveMaterial = true;
+ m_materialStack.push(mats.front());
+ }
+
+
+ foreach (Mesh* mesh, ent->componentsOfType<Mesh>()) {
+ Material* mat = m_materialStack.empty() ? NULL : m_materialStack.top();
+ m_renderer->buildMeshes(mesh, mat, ent->sceneMatrix());
+ }
+
+ foreach (Shape* shape, ent->componentsOfType<Shape>()) {
+ Material* mat = m_materialStack.empty() ? NULL : m_materialStack.top();
+ m_renderer->buildShape(shape, mat, ent->sceneMatrix());
+ }
+
+ foreach (Camera* cam, ent->componentsOfType<Camera>()) {
+ m_renderer->foundCamera(cam, ent->sceneMatrix());
+ }
+
+ NodeVisitor::visitEntity(ent);
+
+ if (haveMaterial)
+ m_materialStack.pop();
+ }
+
+private:
+ QStack<Material*> m_materialStack;
+ Render::Renderer* m_renderer;
+};
+
+} // anonymous namespace
+
+namespace Render {
+
+Renderer::Renderer()
+ : m_rendererAspect(0)
+ , m_frameGraphRoot(0)
+ , m_camera(0)
+ , m_renderCamera(0)
+ , m_meshManager(new MeshManager(this))
+{
+ m_temporaryAllBin = NULL;
+ m_graphicsContext = new QGraphicsContext;
+ m_graphicsContext->setOpenGLContext(new QOpenGLContext);
+
+ m_frameTimer = new QTimer(this);
+ connect(m_frameTimer, SIGNAL(timeout()), this, SLOT(onFrame()));
+ m_frameTimer->setInterval(16);
+
+ m_textureProvider = new RenderTextureProvider;
+
+ buildDefaultTechnique();
+ buildDefaultMaterial();
+}
+
+void Renderer::buildDefaultTechnique()
+{
+ m_defaultTechnique = new Technique;
+ m_defaultTechnique->setObjectName("default-technique");
+
+ ShaderProgram* defaultShader = new ShaderProgram;
+ defaultShader->setVertexSourceFile(":/shaders/diffuse.vert");
+ defaultShader->setFragmentSourceFile(":/shaders/diffuse.frag");
+ defaultShader->setObjectName("DefaultShader");
+
+ RenderPass* basicPass = new RenderPass;
+ basicPass->setShaderProgram(defaultShader);
+
+ DrawStateSet* ss = new DrawStateSet;
+ ss->addState(DepthTest::getOrCreate(GL_LESS));
+ ss->addState(CullFace::getOrCreate(GL_BACK));
+ basicPass->setStateSet(ss);
+
+ m_defaultTechnique->addPass(basicPass);
+
+ Parameter* vp = new Parameter(m_defaultTechnique, "position", GL_FLOAT_VEC3);
+ vp->setMeshAttributeName("position");
+ m_defaultTechnique->addParameter(vp);
+ basicPass->addAttributeBinding(vp, "vertexPosition");
+
+ Parameter* np = new Parameter(m_defaultTechnique, "normal", GL_FLOAT_VEC3);
+ np->setMeshAttributeName("normal");
+ m_defaultTechnique->addParameter(np);
+ basicPass->addAttributeBinding(np, "vertexNormal");
+
+// matrix uniforms from standard
+ Parameter* mvMat = new Parameter(m_defaultTechnique, "modelView", GL_FLOAT_MAT4);
+ mvMat->setStandardUniform(Parameter::ModelView);
+ m_defaultTechnique->addParameter(mvMat);
+ basicPass->addUniformBinding(mvMat, "modelViewMatrix");
+
+ Parameter* nMat = new Parameter(m_defaultTechnique, "normalMat", GL_FLOAT_MAT3);
+ nMat->setStandardUniform(Parameter::ModelViewNormal);
+ m_defaultTechnique->addParameter(nMat);
+ basicPass->addUniformBinding(nMat, "normalMatrix");
+
+ Parameter* mvpMat = new Parameter(m_defaultTechnique, "mvp", GL_FLOAT_MAT4);
+ mvpMat->setStandardUniform(Parameter::ModelViewProjection);
+ m_defaultTechnique->addParameter(mvpMat);
+ basicPass->addUniformBinding(mvpMat, "mvp");
+
+// diffuse lighting uniforms
+ Parameter* lightPos = new Parameter(m_defaultTechnique, "lightPos", GL_FLOAT_VEC4);
+ m_defaultTechnique->addParameter(lightPos);
+ basicPass->addUniformBinding(lightPos, "lightPosition");
+
+ Parameter* lightIntensity = new Parameter(m_defaultTechnique, "lightIntensity", GL_FLOAT_VEC3);
+ m_defaultTechnique->addParameter(lightIntensity);
+ basicPass->addUniformBinding(lightIntensity, "lightIntensity");
+
+ Parameter* kd = new Parameter(m_defaultTechnique, "kd", GL_FLOAT_VEC3);
+ m_defaultTechnique->addParameter(kd);
+ basicPass->addUniformBinding(kd, "kd");
+
+ Parameter* ka = new Parameter(m_defaultTechnique, "ka", GL_FLOAT_VEC3);
+ m_defaultTechnique->addParameter(ka);
+ basicPass->addUniformBinding(ka, "ka");
+}
+
+void Renderer::buildDefaultMaterial()
+{
+ m_defaultMaterial = new Material;
+ m_defaultMaterial->setObjectName("DefaultMaterial");
+ m_defaultMaterial->setParameter("lightPos", QVector4D(10.0f, 10.0f, 0.0f, 1.0f));
+ m_defaultMaterial->setParameter("lightIntensity", QVector3D(0.5f, 0.5f, 0.5f));
+ m_defaultMaterial->setParameter("ka", QVector3D(0.2f, 0.2f, 0.2f));
+ m_defaultMaterial->setParameter("kd", QVector3D(1.0f, 0.5f, 0.0f));
+
+ Effect* defEff = new Effect;
+ defEff->addTechnique(m_defaultTechnique);
+ m_defaultMaterial->setEffect(defEff);
+}
+
+Renderer::~Renderer()
+{
+ delete m_graphicsContext;
+ delete m_textureProvider;
+}
+
+void Renderer::initialize()
+{
+
+}
+
+void Renderer::setFrameGraphRoot(FrameGraphNode *fgRoot)
+{
+ qDebug() << Q_FUNC_INFO;
+ m_frameGraphRoot = fgRoot;
+}
+
+FrameGraphNode *Renderer::frameGraphRoot() const
+{
+ return m_frameGraphRoot;
+}
+
+void Renderer::setSceneObject(Qt3D::Node *obj)
+{
+ Scene* sc = Scene::findInTree(obj);
+ if (sc) {
+ setSceneGraphRoot(sc);
+ } else
+ qWarning() << Q_FUNC_INFO << "couldn't find Scene object";
+}
+
+void Renderer::onFrame()
+{
+ render();
+}
+
+void Renderer::setSceneGraphRoot(Node *sgRoot)
+{
+ Q_ASSERT(sgRoot);
+
+ // TODO: Unify this to one root node and scene builder
+ Scene *scene = Scene::findInTree(sgRoot);
+ if (scene) {
+ qDebug() << "building temporary backend";
+ m_sceneGraphRoot = scene;
+ TemporaryBackendBuilder tbb(this);
+ tbb.traverse(m_sceneGraphRoot);
+ qDebug() << "done building backend";
+
+ QMetaObject::invokeMethod(m_frameTimer, "start");
+ } else {
+ // Test new scene builder
+ m_sceneGraphRoot = sgRoot;
+
+ RenderSceneBuilder builder(this);
+ builder.traverse(m_sceneGraphRoot);
+ RenderNode *root = builder.rootNode();
+ if (!root)
+ qWarning() << "Failed to build render scene";
+ m_renderSceneRoot = root;
+
+ root->dump();
+
+ // Queue up jobs to do initial full updates of
+ // - Mesh loading + bounding volume calculation
+ // - Local bounding volumes
+ // - World transforms
+ // - World bounding volumes
+ }
+}
+
+Node *Renderer::sceneGraphRoot() const
+{
+ return m_sceneGraphRoot;
+}
+
+void Renderer::setCamera(Camera *cam)
+{
+ m_camera = cam;
+ m_renderCamera = new RenderCamera(m_rendererAspect);
+ m_renderCamera->setPeer(cam);
+ m_renderCamera->setProjection(cam->projectionMatrix());
+
+ m_graphicsContext->setCamera(m_renderCamera);
+}
+
+void Renderer::setSurface(QSurface* s)
+{
+ qDebug() << Q_FUNC_INFO;
+ m_graphicsContext->setSurface(s);
+
+ QSurfaceFormat sf = s->format();
+
+ QOpenGLContext* ctx = new QOpenGLContext;
+ ctx->setFormat(sf);
+ if (!ctx->create()) {
+ qWarning() << Q_FUNC_INFO << "OpenGL context creation failed";
+ }
+
+ m_graphicsContext->setOpenGLContext(ctx);
+}
+
+void Renderer::setDefaultTechnique(Technique *t)
+{
+ Effect* defEff = m_defaultMaterial->effect();
+ bool materialWasUsing = (defEff->techniques().front() ==
+ m_defaultTechnique);
+
+ m_defaultTechnique = t;
+ if (materialWasUsing) {
+ defEff->clearTechniques();
+ defEff->addTechnique(t);
+ }
+}
+
+void Renderer::setDefaultMaterial(Material *mat)
+{
+ m_defaultMaterial = mat;
+}
+
+void Renderer::render()
+{
+ // Traverse the framegraph
+ // FrameGraphVisitor visitor;
+ // visitor.traverse(m_frameGraphRoot, this);
+
+ // begin hack renderer
+
+ if (!m_renderCamera)
+ return;
+
+ m_renderCamera->sync();
+
+ m_graphicsContext->beginDrawing();
+
+ foreach (Drawable* dr, m_initList)
+ dr->initializeGL(m_graphicsContext);
+ m_initList.clear();
+
+ int err = glGetError();
+ if (err)
+ qWarning() << "GL error before submitting bins:" << err;
+
+ m_temporaryAllBin->sendDrawingCommands(m_graphicsContext);
+
+ m_graphicsContext->endDrawing();
+
+ // end hack renderer
+}
+
+void Renderer::doRender()
+{
+ // Render using current device state and renderer configuration
+ qDebug() << Q_FUNC_INFO;
+}
+
+RenderTechnique* Renderer::techniqueForMaterial(Material* mat)
+{
+ Effect* eff = mat->effect();
+ Technique *tech;
+ if (eff) {
+ Q_ASSERT(!eff->techniques().empty());
+
+ // FIXME - technique selection happens in here, now we know
+ // the renderer characteristics
+ tech = eff->techniques().front();
+ } else {
+ tech = m_defaultTechnique;
+ }
+
+ if (!m_techniqueHash.contains(tech)) {
+ RenderTechnique* rtech = createTechnique(tech);
+ m_techniqueHash[tech] = rtech;
+ }
+
+ return m_techniqueHash.value(tech);
+}
+
+RenderShader* Renderer::getOrCreateShader(ShaderProgram* sp)
+{
+ if (!m_shaderHash.contains(sp)) {
+ RenderShader* rs = new RenderShader(sp);
+ m_shaderHash[sp] = rs;
+ }
+
+ return m_shaderHash.value(sp);
+}
+
+RenderBin* Renderer::getOrCreateBinForPass(Technique* t, RenderPass* p)
+{
+ Q_UNUSED(t);
+ Q_UNUSED(p);
+
+ // TODO - select bins by priority
+
+ if (!m_temporaryAllBin)
+ m_temporaryAllBin = new OpaqueBin;
+
+ return m_temporaryAllBin;
+}
+
+RenderTechnique* Renderer::createTechnique(Technique* tech)
+{
+ RenderTechnique* rt = new RenderTechnique(tech);
+ for (unsigned int p=0; p<rt->passCount(); ++p) {
+ RenderPass* frontendPass = tech->renderPasses().at(p);
+ RenderShader* rshader = getOrCreateShader(frontendPass->shaderProgram());
+ rt->setShaderForPass(p, rshader);
+
+ RenderBin* bin = getOrCreateBinForPass(tech, frontendPass);
+ rt->setBinForPass(p, bin);
+ }
+
+ return rt;
+}
+
+RenderMaterial* Renderer::getOrCreateMaterial(Material* mat)
+{
+ if (!m_materialHash.contains(mat)) {
+ qDebug() << "creating render material for mat:" << mat->objectName();
+
+ RenderMaterial* rmat = new RenderMaterial(m_rendererAspect);
+ rmat->setPeer(mat);
+ rmat->setTextureProvider(m_textureProvider);
+ m_materialHash[mat] = rmat;
+
+ // specifying technique will make the material sync parameter
+ // state from its peeer material.
+ rmat->setTechnique(techniqueForMaterial(mat));
+ }
+
+ return m_materialHash.value(mat);
+}
+
+void Renderer::buildMeshes(Mesh* mesh, Material* mat, const QMatrix4x4& mm)
+{
+ if (mat == NULL) {
+ mat = m_defaultMaterial;
+ }
+
+ RenderMaterial* rmat = getOrCreateMaterial(mat);
+ RenderTechnique* t = rmat->technique();
+
+ for (unsigned int p=0; p<t->passCount(); ++p) {
+ RenderBin* bin = t->binForPass(p);
+
+ RenderMesh* rmesh = new RenderMesh(mesh);
+ rmesh->setData(mesh->data());
+ rmesh->setTechniqueAndPass(t, p);
+ rmesh->setModelMatrix(mm);
+ rmesh->setMaterial(rmat);
+
+ m_initList.push_back(rmesh);
+ bin->addDrawable(rmesh);
+
+ } // of technique pass iteration
+}
+
+void Renderer::buildShape(Shape* shape, Material* mat, const QMatrix4x4& mm)
+{
+ if (mat == NULL) {
+ mat = m_defaultMaterial;
+ }
+
+ MeshDataPtr shapeMeshData = shape->data();
+ RenderMaterial* rmat = getOrCreateMaterial(mat);
+ RenderTechnique* t = rmat->technique();
+
+ for (unsigned int p=0; p<t->passCount(); ++p) {
+ RenderBin* bin = t->binForPass(p);
+
+ RenderMesh* rmesh = new RenderMesh(NULL);
+ rmesh->setData(shapeMeshData);
+ rmesh->setTechniqueAndPass(t, p);
+ rmesh->setModelMatrix(mm);
+ rmesh->setMaterial(rmat);
+
+ m_initList.push_back(rmesh);
+ bin->addDrawable(rmesh);
+
+ } // of technique pass iteration
+}
+
+
+void Renderer::foundCamera(Camera *cam, const QMatrix4x4 &mm)
+{
+ Q_UNUSED(mm);
+ cam->setViewMatrix(mm.inverted());
+ setCamera(cam);
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/renderer.h b/src/render/backend/renderer.h
new file mode 100644
index 000000000..40bc3eefa
--- /dev/null
+++ b/src/render/backend/renderer.h
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_RENDERER_H
+#define QT3D_RENDER_RENDERER_H
+
+#include <technique.h>
+
+#include <QHash>
+#include <QMatrix4x4>
+#include <QObject>
+#include <QTimer>
+
+#include <QOpenGLShaderProgram>
+#include <QOpenGLVertexArrayObject>
+#include <QOpenGLBuffer>
+
+class QSurface;
+
+namespace Qt3D {
+
+class Camera;
+class Entity;
+class RenderBin;
+class Material;
+class RenderMaterial;
+class RenderTechnique;
+class ShaderProgram;
+class RenderShader;
+class Mesh;
+class RenderPass;
+class QGraphicsContext;
+class RenderCamera;
+class Drawable;
+class RenderTextureProvider;
+class Shape;
+class RendererAspect;
+
+namespace Render {
+
+class FrameGraphNode;
+class RenderNode;
+class MeshManager;
+
+class Renderer : public QObject
+{
+ Q_OBJECT
+public:
+ Renderer();
+ ~Renderer();
+
+ void setRendererAspect(RendererAspect *rendererAspect) { m_rendererAspect = rendererAspect; }
+ RendererAspect *rendererAspect() const { return m_rendererAspect; }
+
+ void setFrameGraphRoot(FrameGraphNode *fgRoot);
+ FrameGraphNode *frameGraphRoot() const;
+
+ void setSceneObject(Qt3D::Node *obj);
+ void setSceneGraphRoot(Qt3D::Node *sgRoot);
+ Qt3D::Node *sceneGraphRoot() const;
+
+ RenderNode *renderSceneRoot() const { return m_renderSceneRoot; }
+
+ void setCamera(Camera* cam);
+
+ void render();
+ void doRender();
+
+ MeshManager *meshManager() const { return m_meshManager; }
+
+ // temporary!
+
+ RenderTechnique* techniqueForMaterial(Material* mat);
+
+ void buildMeshes(Mesh *mesh, Material *mat, const QMatrix4x4& mm);
+ void buildShape(Shape *shape, Material *mat, const QMatrix4x4 &mm);
+
+ void foundCamera(Camera* cam, const QMatrix4x4& mm);
+
+ Q_INVOKABLE void setSurface(QSurface *s);
+
+ void setDefaultTechnique(Technique* t);
+ void setDefaultMaterial(Material* mat);
+
+protected:
+ Q_INVOKABLE void initialize();
+
+private slots:
+ void onFrame();
+
+private:
+ RendererAspect *m_rendererAspect;
+
+ // Frame graph root
+ FrameGraphNode *m_frameGraphRoot;
+
+ Qt3D::Node *m_sceneGraphRoot;
+ RenderNode *m_renderSceneRoot;
+
+ Camera *m_camera;
+ RenderCamera* m_renderCamera;
+
+ QHash<Material*, RenderMaterial*> m_materialHash;
+ QHash<Technique *, RenderTechnique*> m_techniqueHash;
+ QHash<ShaderProgram*, RenderShader*> m_shaderHash;
+
+ RenderBin *getOrCreateBinForPass(Technique *t, RenderPass *p);
+
+ RenderTechnique *createTechnique(Technique *tech);
+ RenderShader *getOrCreateShader(ShaderProgram *sp);
+ RenderMaterial *getOrCreateMaterial(Material *mat);
+
+ Material* m_defaultMaterial;
+ Technique* m_defaultTechnique;
+
+ QGraphicsContext* m_graphicsContext;
+ RenderBin* m_temporaryAllBin;
+ RenderTextureProvider* m_textureProvider;
+ MeshManager *m_meshManager;
+
+ QTimer* m_frameTimer;
+
+ /// list of drawables to be initialized next frame
+ QList<Drawable*> m_initList;
+
+ void buildDefaultMaterial();
+ void buildDefaultTechnique();
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_RENDERER_H
diff --git a/src/render/backend/rendereraspect.cpp b/src/render/backend/rendereraspect.cpp
new file mode 100644
index 000000000..0d63a7c0f
--- /dev/null
+++ b/src/render/backend/rendereraspect.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendereraspect.h"
+
+#include "meshmanager.h"
+#include "renderer.h"
+#include "renderthread.h"
+
+#include <jobs/loadmeshdatajob.h>
+#include <jobs/updateworldtransformjob.h>
+#include <jobs/updateboundingvolumejob.h>
+
+#include <node.h>
+
+#include <QDebug>
+#include <QThread>
+#include <QWindow>
+
+namespace Qt3D {
+
+RendererAspect::RendererAspect(QObject *parent)
+ : AbstractAspect(AbstractAspect::AspectRenderer, parent)
+ , m_renderThread(new RenderThread)
+{
+ qRegisterMetaType<QSurface*>("QSurface*");
+ qRegisterMetaType< QSharedPointer<QObject> >("QObjectPtr");
+ m_renderThread->waitForStart();
+ m_renderThread->renderer()->setRendererAspect(this);
+}
+
+void RendererAspect::setWindow(QWindow *window)
+{
+ Q_ASSERT(window);
+ QSurface* surface = window;
+
+ Render::Renderer *renderer = m_renderThread->renderer();
+ QMetaObject::invokeMethod(renderer, "setSurface", Q_ARG(QSurface*, surface));
+}
+
+QVector<QJobPtr> RendererAspect::jobsToExecute()
+{
+ // Create jobs that will get exectued by the threadpool
+ QVector<QJobPtr> jobs;
+
+// Render::UpdateWorldTransformJobPtr worldTransformJob(new Render::UpdateWorldTransformJob(m_renderThread->renderer()->renderSceneRoot()));
+// Render::UpdateBoundingVolumeJobPtr boundingVolumeJob(new Render::UpdateBoundingVolumeJob(m_renderThread->renderer()));
+
+// // We can only update bounding volumes once all world transforms are known
+// boundingVolumeJob->addDependency(worldTransformJob);
+
+// // Add all jobs to queue
+// jobs.append(worldTransformJob);
+// jobs.append(boundingVolumeJob);
+
+ // Create jobs to load in any meshes that are pending
+ QList< QPair<QString,MeshDataPtr> > meshes = m_renderThread->renderer()->meshManager()->meshesPending();
+ for (int i = 0; i < meshes.size(); ++i ) {
+ const QPair<QString, MeshDataPtr> &meshDataInfo = meshes.at(i);
+ Render::LoadMeshDataJobPtr loadMeshJob(new Render::LoadMeshDataJob(meshDataInfo.first, meshDataInfo.second));
+ jobs.append(loadMeshJob);
+ }
+ m_renderThread->renderer()->meshManager()->clearMeshesPending();
+
+ return jobs;
+}
+
+void RendererAspect::registerAspectHelper(Node *rootObject)
+{
+ Render::Renderer *renderer = m_renderThread->renderer();
+ renderer->setSceneGraphRoot(rootObject);
+}
+
+void RendererAspect::unregisterAspectHelper(Node *rootObject)
+{
+}
+
+void RendererAspect::initializeHelper(QAspectManager *aspectManager)
+{
+ Q_UNUSED(aspectManager);
+ Render::Renderer *renderer = m_renderThread->renderer();
+ QMetaObject::invokeMethod(renderer, "initialize");
+}
+
+void RendererAspect::cleanupHelper()
+{
+ Render::Renderer *renderer = m_renderThread->renderer();
+ //QMetaObject::invokeMethod(renderer, "cleanup");
+}
+
+}
diff --git a/src/render/backend/rendereraspect.h b/src/render/backend/rendereraspect.h
new file mode 100644
index 000000000..3fd04744f
--- /dev/null
+++ b/src/render/backend/rendereraspect.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERERASPECT_H
+#define RENDERERASPECT_H
+
+#include "abstractaspect.h"
+
+namespace Qt3D {
+class RenderThread;
+}
+
+class QWindow;
+
+namespace Qt3D {
+
+class RendererAspect : public AbstractAspect
+{
+ Q_OBJECT
+public:
+ explicit RendererAspect(QObject *parent = 0);
+
+ virtual void setWindow(QWindow *window);
+
+ QVector<QJobPtr> jobsToExecute() Q_DECL_OVERRIDE;
+
+protected:
+ void registerAspectHelper(Node *rootObject) Q_DECL_OVERRIDE;
+ void unregisterAspectHelper(Node *rootObject) Q_DECL_OVERRIDE;
+
+ void initializeHelper(QAspectManager *aspectManager);
+ void cleanupHelper();
+
+private:
+ RenderThread* m_renderThread;
+};
+
+}
+
+#endif // RENDERERASPECT_H
diff --git a/src/render/backend/rendermaterial.cpp b/src/render/backend/rendermaterial.cpp
new file mode 100644
index 000000000..b74bf5954
--- /dev/null
+++ b/src/render/backend/rendermaterial.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendermaterial.h"
+
+#include "rendereraspect.h"
+#include "qgraphicscontext.h"
+#include "rendertechnique.h"
+#include "rendertextureprovider.h"
+
+#include <technique.h> // for Parameter
+#include <material.h>
+
+#include <qaspectmanager.h>
+
+#include <QOpenGLShaderProgram>
+
+namespace Qt3D
+{
+
+RenderMaterial::RenderMaterial(RendererAspect *rendererAspect)
+ : m_rendererAspect(rendererAspect)
+ , m_textureProvider(NULL)
+{
+}
+
+RenderMaterial::~RenderMaterial()
+{
+ qDeleteAll(m_packs);
+ m_packs.clear();
+}
+
+void RenderMaterial::setTextureProvider(RenderTextureProvider* rtp)
+{
+ m_textureProvider = rtp;
+}
+
+void RenderMaterial::setPeer(Material *mat)
+{
+ m_peer = mat;
+
+ // Register for changes
+ QChangeArbiter *arbiter = m_rendererAspect->aspectManager()->changeArbiter();
+ arbiter->registerObserver(this, m_peer, MaterialParameter);
+}
+
+void RenderMaterial::setEffectName(QString nm)
+{
+ Q_UNUSED(nm);
+}
+
+void RenderMaterial::setParameter(QString paramName, QVariant varVal)
+{
+ Parameter* param = m_technique->parameterByName(paramName);
+ if (!param) {
+ return;
+ }
+
+ if (param->isTextureType()) {
+ // handle samplers separately
+ return;
+ }
+
+ if (param->isStandardUniform()) {
+ qWarning() << Q_FUNC_INFO << "setting standard uniform explicit for" << paramName;
+ return;
+ }
+
+ Render::QUniformValue uval(param->uniformType(), varVal);
+
+ QStringList names(m_technique->glslNamesForUniformParameter(paramName));
+ Q_ASSERT(names.count() == (int) m_technique->passCount());
+
+ for (unsigned int p=0; p<m_technique->passCount(); ++p) {
+ if (names.at(p).isEmpty())
+ continue; // not set in this pass
+
+ m_packs.at(p)->setUniform(names.at(p), uval);
+ } // of pass iteration
+}
+
+void RenderMaterial::setTextureParameter(QString paramName, RenderTexturePtr tex)
+{
+ Q_ASSERT(tex);
+ Parameter* param = m_technique->parameterByName(paramName);
+ if (!param)
+ return;
+
+ Q_ASSERT(param->isTextureType());
+
+ QStringList names(m_technique->glslNamesForUniformParameter(paramName));
+ Q_ASSERT(names.count() == (int) m_technique->passCount());
+
+ for (unsigned int p=0; p<m_technique->passCount(); ++p) {
+ if (names.at(p).isEmpty())
+ continue; // not set in this pass
+
+ m_packs.at(p)->setTexture(names.at(p), tex);
+ } // of pass iteration
+}
+
+void RenderMaterial::syncParametersFromPeer()
+{
+ Q_ASSERT(m_peer);
+ foreach (QString nm, m_peer->parameterValues().keys()) {
+ QVariant val = m_peer->parameterValues().value(nm);
+ if (!val.isValid()) {
+ qWarning() << Q_FUNC_INFO << "bad value:" << val << "for parameter" << nm;
+ continue;
+ }
+ setParameter(nm, val);
+ }
+
+ // FIXME - should do this on demand, otherwise we're re-uploading
+ // for no good reason
+ foreach (QString nm, m_peer->textureValues().keys()) {
+ Texture* t = m_peer->textureValues().value(nm);
+ setTextureParameter(nm, m_textureProvider->get(t));
+ }
+}
+
+void RenderMaterial::setTechnique(RenderTechnique *rt)
+{
+ m_technique = rt;
+
+ // could re-use packs, but techniques don't change often
+ qDeleteAll(m_packs);
+ m_packs.clear();
+
+ // allocate pack per pass - or should we do this lazily?
+ for (unsigned int p=0; p<rt->passCount(); ++p)
+ m_packs.append(new Render::QUniformPack);
+
+ if (m_peer)
+ syncParametersFromPeer();
+}
+
+RenderTechnique *RenderMaterial::technique() const
+{
+ return m_technique;
+}
+
+void RenderMaterial::setUniformsForPass(unsigned int pass, QGraphicsContext *gc)
+{
+ Q_ASSERT((int) pass < m_packs.size());
+ m_packs.at(pass)->apply(gc);
+}
+
+void RenderMaterial::sceneChangeEvent(const QSceneChangePtr &e)
+{
+ switch (e->m_type) {
+ case MaterialParameter: {
+ QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e);
+ QString propertyName = propertyChange->m_propertyName;
+ QVariant propertyValue = propertyChange->m_value;
+ setParameter(propertyName, propertyValue);
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+} // of namespace Qt3D
+
diff --git a/src/render/backend/rendermaterial.h b/src/render/backend/rendermaterial.h
new file mode 100644
index 000000000..d216bdec1
--- /dev/null
+++ b/src/render/backend/rendermaterial.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERMATERIAL_H
+#define RENDERMATERIAL_H
+
+#include <QVariant>
+
+#include <qchangearbiter.h>
+
+#include <quniformvalue.h>
+#include <rendertextureprovider.h>
+
+namespace Qt3D
+{
+
+class Material;
+class RenderTechnique;
+class QGraphicsContext;
+class RendererAspect;
+
+class RenderMaterial : public QObserverInterface
+{
+public:
+ RenderMaterial(RendererAspect *rendererAspect);
+ ~RenderMaterial();
+
+ void setPeer(Material* mat);
+
+ void setEffectName(QString nm);
+
+ void setParameter(QString paramName, QVariant value);
+
+ void setTextureParameter(QString paramName, RenderTexturePtr tex);
+
+ void syncParametersFromPeer();
+
+ /**
+ * @brief setTechnique - specify the effect technique to use for
+ * rendering this material.
+ * @param rt
+ */
+ void setTechnique(RenderTechnique* rt);
+ RenderTechnique* technique() const;
+
+ void setUniformsForPass(unsigned int pass, QGraphicsContext* gc);
+
+ void setTextureProvider(RenderTextureProvider *rtp);
+
+ void sceneChangeEvent(const QSceneChangePtr &e) Q_DECL_OVERRIDE;
+
+private:
+ RendererAspect *m_rendererAspect;
+ Material* m_peer;
+ QString m_effectName;
+ RenderTechnique* m_technique;
+ RenderTextureProvider* m_textureProvider;
+
+ QVector<Render::QUniformPack*> m_packs;
+};
+
+}
+
+#endif // RENDERMATERIAL_H
diff --git a/src/render/backend/rendermesh.cpp b/src/render/backend/rendermesh.cpp
new file mode 100644
index 000000000..b7e3252c6
--- /dev/null
+++ b/src/render/backend/rendermesh.cpp
@@ -0,0 +1,333 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendermesh.h"
+
+#include "rendertechnique.h"
+#include "rendermaterial.h"
+
+#include "qgraphicscontext.h"
+#include <meshdata.h>
+#include <technique.h>
+
+#include <QOpenGLContext>
+#include <QOpenGLFunctions_3_3_Core>
+#include <QOpenGLShaderProgram>
+
+namespace Qt3D {
+
+RenderMesh::RenderMesh(Mesh* peer)
+ : Drawable( ),
+ m_peer(peer),
+ m_technique(0),
+ m_pass(0),
+ m_material(0),
+ m_instanceCount( 0 ),
+ m_funcs(0)
+{
+}
+
+void RenderMesh::setData(MeshDataPtr mesh)
+{
+ m_meshData = mesh;
+ m_meshDirty = true;
+ // clear bounding box?
+}
+
+void RenderMesh::setTechniqueAndPass(RenderTechnique* tech, unsigned int pass)
+{
+ m_technique = tech;
+ m_pass = pass;
+}
+
+void RenderMesh::setMaterial(RenderMaterial *rmat)
+{
+ m_material = rmat;
+}
+
+void RenderMesh::setInstanceCount(unsigned int count)
+{
+ m_instanceCount = count;
+}
+
+void RenderMesh::setModelMatrix(const QMatrix4x4 &mm)
+{
+ m_modelMatrix = mm;
+}
+
+DrawStateSet *RenderMesh::stateSet()
+{
+ return m_technique->stateSetForPass(m_pass);
+}
+
+
+void RenderMesh::initializeGL(QGraphicsContext* gc)
+{
+ m_vao.create();
+ m_vao.bind();
+
+ gc->activateShader(m_technique->shaderForPass(m_pass));
+
+ foreach (QString nm, m_meshData->attributeNames()) {
+ AttributePtr attr(m_meshData->attributeByName(nm));
+ QString glsl = m_technique->glslNameForMeshAttribute(m_pass, nm);
+ if (glsl.isEmpty())
+ continue; // not used in this pass
+ gc->specifyAttribute(glsl, attr);
+ }
+
+ m_drawIndexed = (m_meshData->indexAttr() != NULL);
+ if (m_drawIndexed) {
+ gc->specifyIndices(m_meshData->indexAttr());
+ }
+
+ m_vao.release();
+
+ // TODO Be careful about where we do this OpenGL work
+ QOpenGLContext* ctx = QOpenGLContext::currentContext();
+ m_funcs = ctx->versionFunctions<QOpenGLFunctions_3_3_Core>();
+ if ( m_funcs )
+ m_funcs->initializeOpenGLFunctions();
+ else
+ qWarning() << Q_FUNC_INFO << "couldn't resolve 3.3 core functions";
+};
+
+void RenderMesh::releaseGL()
+{
+ m_vao.destroy();
+}
+
+void RenderMesh::sendDrawingCommands(QGraphicsContext* gc)
+{
+ if (gc->activeMaterial() != m_material) {
+ gc->setActiveMaterial(m_material);
+ m_material->setUniformsForPass(m_pass, gc);
+ }
+
+ gc->setModelMatrix(m_modelMatrix);
+
+ m_vao.bind();
+ GLint primType = m_meshData->primitiveType();
+ GLint primCount = m_meshData->primitiveCount();
+ GLint indexType = m_drawIndexed ? m_meshData->indexAttr()->type() : 0;
+
+ if (m_instanceCount > 0) {
+ if ( m_drawIndexed ) {
+ m_funcs->glDrawElementsInstanced(primType, primType, indexType, 0, m_instanceCount);
+ } else {
+ m_funcs->glDrawArraysInstanced(primType, 0, primCount, m_instanceCount);
+ }
+ } else {
+ if ( m_drawIndexed ) {
+ m_funcs->glDrawElements(primType, primCount, indexType,
+ reinterpret_cast<void*>(m_meshData->indexAttr()->byteOffset()));
+ } else {
+ m_funcs->glDrawArrays(primType, 0, primCount);
+ }
+ } // non-instanced drawing
+
+ int err = glGetError();
+ if (err)
+ qWarning() << "GL error after drawing mesh:" << QString::number(err, 16);
+
+
+ m_vao.release();
+}
+
+RenderShader *RenderMesh::shader()
+{
+ return m_technique->shaderForPass(m_pass);
+}
+
+AxisAlignedBoundingBox RenderMesh::boundingBox() const
+{
+ if (!m_meshData)
+ return AxisAlignedBoundingBox();
+
+ return m_meshData->boundingBox();
+}
+
+#if 0
+static bool areIndicesShort( const QVector<unsigned int>& indices )
+{
+ // optimization; check the last index first, since it is often
+ // (but not always) going to be the larger index values
+ if (indices.back() > 0xffff) {
+ return false;
+ }
+
+ for (int i=0; i<indices.size(); ++i) {
+ if (indices.at(i) > 0xffff) {
+ return false;
+ }
+ } // of indices iteration
+
+ return true;
+}
+
+void RenderMesh::setMeshData( DrawContext& dc )
+{
+ // Construct buffers for the vertices, normals, texCoord, tangents and indices
+ QVector<QVector3D> points = m_loader->vertices();
+ QVector<QVector3D> normals = m_loader->normals();
+ QVector<QVector2D> texCoords = m_loader->textureCoordinates();
+ QVector<QVector4D> tangents = m_loader->tangents();
+
+ int vertexCount = points.size();
+ QVector<unsigned int> elements = m_loader->indices();
+ m_drawCount = elements.size();
+ int faces = elements.size() / 3;
+
+ bool shortIndices = areIndicesShort(elements);
+
+ /** \todo Use QScopedPointers or try reinterpret_cast on the
+ * QVector<> objects.
+ */
+ float* v = new float[3 * vertexCount];
+ float* n = new float[3 * vertexCount];
+ float* tc = 0;
+ float* tang = 0;
+
+ if ( !texCoords.isEmpty() )
+ {
+ tc = new float[ 2 * vertexCount ];
+ if ( !tangents.isEmpty() )
+ tang = new float[ 4 * vertexCount ];
+ }
+
+ int idx = 0, tcIdx = 0, tangIdx = 0;
+ for ( int i = 0; i < vertexCount; ++i )
+ {
+ v[idx] = points[i].x();
+ v[idx+1] = points[i].y();
+ v[idx+2] = points[i].z();
+ n[idx] = normals[i].x();
+ n[idx+1] = normals[i].y();
+ n[idx+2] = normals[i].z();
+ idx += 3;
+ if ( tc != 0 )
+ {
+ tc[tcIdx] = texCoords[i].x();
+ tc[tcIdx+1] = texCoords[i].y();
+ tcIdx += 2;
+ }
+ if ( tang != 0 )
+ {
+ tang[tangIdx] = tangents[i].x();
+ tang[tangIdx+1] = tangents[i].y();
+ tang[tangIdx+2] = tangents[i].z();
+ tang[tangIdx+3] = tangents[i].w();
+ tangIdx += 4;
+ }
+ }
+
+ m_mode = GL_TRIANGLES;
+
+ // Create and populate the buffer objects
+ m_positionBuffer.create();
+ m_positionBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_positionBuffer.bind();
+ m_positionBuffer.allocate( v, 3 * vertexCount * sizeof( float ) );
+
+ m_normalBuffer.create();
+ m_normalBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_normalBuffer.bind();
+ m_normalBuffer.allocate( n, 3 * vertexCount * sizeof( float ) );
+
+ if ( tc )
+ {
+ m_textureCoordBuffer.create();
+ m_textureCoordBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_textureCoordBuffer.bind();
+ m_textureCoordBuffer.allocate( tc, 2 * vertexCount * sizeof( float ) );
+ }
+
+ if ( tang )
+ {
+ m_tangentBuffer.create();
+ m_tangentBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_tangentBuffer.bind();
+ m_tangentBuffer.allocate( tang, 4 * vertexCount * sizeof( float ) );
+ }
+
+ if ( shortIndices ) {
+ unsigned short* el = new unsigned short[elements.size()];
+ for ( int i = 0; i < elements.size(); ++i )
+ el[i] = static_cast<unsigned short>(elements[i]);
+
+ m_indexBuffer.create();
+ m_indexBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_indexBuffer.bind();
+ m_indexBuffer.allocate( el, 3 * faces * sizeof( unsigned short ) );
+ m_indexType = GL_UNSIGNED_SHORT;
+ delete[] el;
+ } else {
+ unsigned int* el = new unsigned int[elements.size()];
+ for ( int i = 0; i < elements.size(); ++i )
+ el[i] = elements[i];
+
+ m_indexBuffer.create();
+ m_indexBuffer.setUsagePattern( QOpenGLBuffer::StaticDraw );
+ m_indexBuffer.bind();
+ m_indexBuffer.allocate( el, 3 * faces * sizeof( unsigned int ) );
+ m_indexType = GL_UNSIGNED_INT;
+
+ delete[] el;
+ }
+
+ // Calculate the bounding volume
+ // m_boundingVolume->update( points );
+
+ // Clean up
+ delete[] v;
+ delete[] n;
+ if ( tc != NULL )
+ delete[] tc;
+ if ( tang != NULL )
+ delete[] tang;
+
+ m_loader.reset();
+
+ setupVertexArrayObject( dc );
+}
+#endif
+
+}
diff --git a/src/render/backend/rendermesh.h b/src/render/backend/rendermesh.h
new file mode 100644
index 000000000..5f2c0cdf8
--- /dev/null
+++ b/src/render/backend/rendermesh.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERMESH_H
+#define RENDERMESH_H
+
+#include "drawable.h"
+
+#include <meshdata.h>
+#include <axisalignedboundingbox.h>
+
+#include <QOpenGLVertexArrayObject>
+#include <QMatrix4x4>
+
+class QOpenGLFunctions_3_3_Core;
+
+namespace Qt3D {
+
+class Mesh;
+class RenderNode;
+class RenderPass;
+class RenderMaterial;
+class RenderTechnique;
+
+class RenderMesh : public Drawable
+{
+public:
+ explicit RenderMesh(Mesh* peer);
+
+ void setPeer(Mesh* peer);
+
+ void setData(MeshDataPtr mesh);
+
+ void setTechniqueAndPass(RenderTechnique* tech, unsigned int pass);
+
+ void setMaterial(RenderMaterial* rmat);
+
+ void setInstanceCount(unsigned int count);
+
+ void setModelMatrix(const QMatrix4x4& mm);
+
+ virtual DrawStateSet* stateSet();
+
+ /**
+ * @brief mapAttributeNames - resolve mapping of mesh-data attribute
+ * names to parameters.
+ * @param t
+ */
+ void mapAttributeNames();
+
+ virtual void initializeGL(QGraphicsContext* dc);
+
+ virtual void releaseGL();
+
+protected:
+ virtual void sendDrawingCommands( QGraphicsContext* dc );
+
+ virtual RenderShader* shader();
+
+ virtual AxisAlignedBoundingBox boundingBox() const;
+
+private:
+
+
+ Mesh* m_peer;
+
+ MeshDataPtr m_meshData;
+
+ RenderTechnique* m_technique;
+ unsigned int m_pass;
+
+ RenderMaterial* m_material;
+
+ bool m_drawIndexed;
+ bool m_meshDirty;
+ unsigned int m_instanceCount;
+
+ QOpenGLVertexArrayObject m_vao;
+
+ QOpenGLFunctions_3_3_Core *m_funcs;
+
+ QMatrix4x4 m_modelMatrix;
+};
+
+}
+
+#endif // RENDERMESH_H
diff --git a/src/render/backend/rendernode.cpp b/src/render/backend/rendernode.cpp
new file mode 100644
index 000000000..d9feb14f0
--- /dev/null
+++ b/src/render/backend/rendernode.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendernode.h"
+#include "rendereraspect.h"
+
+#include <transform.h>
+
+#include <qaspectmanager.h>
+#include <sphere.h>
+#include <entity.h>
+
+#include <QMatrix4x4>
+#include <QString>
+#include <QDebug>
+
+namespace Qt3D {
+namespace Render {
+
+// TODO: Create custom allocators for each of the matrices and
+// bounding volumes to that they end up in contiguous arrays.
+
+RenderNode::RenderNode(RendererAspect *rendererAspect, RenderNode *parent)
+ : m_rendererAspect(rendererAspect)
+ , m_parent(parent)
+ , m_localTransform(new QMatrix4x4)
+ , m_worldTransform(new QMatrix4x4)
+ , m_localBoundingVolume(new Qt3D::Sphere)
+ , m_worldBoundingVolume(new Qt3D::Sphere)
+ , m_frontEndPeer(0)
+{
+ if (parent)
+ parent->m_children.append(this);
+}
+
+void RenderNode::setPeer(Transform *transform)
+{
+ m_peer = transform;
+
+ // Register for changes
+ QChangeArbiter *arbiter = m_rendererAspect->aspectManager()->changeArbiter();
+ arbiter->registerObserver(this, m_peer, LocalTransform);
+}
+
+void RenderNode::sceneChangeEvent(const QSceneChangePtr &e)
+{
+ switch (e->m_type) {
+ case LocalTransform: {
+ QScenePropertyChangePtr propertyChange = qSharedPointerCast<QScenePropertyChange>(e);
+ *m_localTransform = propertyChange->m_value.value<QMatrix4x4>();
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void RenderNode::dump() const
+{
+ static int depth = 0;
+ QString indent(2 * depth++, QChar::fromLatin1(' '));
+ qDebug() << indent + m_frontEndPeer->objectName();
+ foreach (const RenderNode *child, m_children)
+ child->dump();
+ --depth;
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/rendernode.h b/src/render/backend/rendernode.h
new file mode 100644
index 000000000..480c8b3ed
--- /dev/null
+++ b/src/render/backend/rendernode.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_RENDERNODE_H
+#define QT3D_RENDER_RENDERNODE_H
+
+#include <qchangearbiter.h>
+
+#include <QVector>
+
+class QMatrix4x4;
+
+namespace Qt3D {
+
+class RendererAspect;
+class Sphere;
+class Node;
+class Transform;
+
+namespace Render {
+
+class RenderNode : public QObserverInterface
+{
+public:
+ explicit RenderNode(RendererAspect *rendererAspect, RenderNode *parent = 0);
+
+ void setPeer(Transform *transform);
+ void sceneChangeEvent(const QSceneChangePtr &e) Q_DECL_OVERRIDE;
+
+ void dump() const;
+
+//private:
+ RendererAspect *m_rendererAspect;
+ Transform *m_peer;
+ RenderNode *m_parent;
+ QVector<RenderNode *> m_children;
+ QMatrix4x4 *m_localTransform;
+ QMatrix4x4 *m_worldTransform;
+ Sphere *m_localBoundingVolume;
+ Sphere *m_worldBoundingVolume;
+
+ // TODO: Do we want to force this to be an Entity?
+ // That would mean forcing an Entity for the root on the main thread's scene
+ Node *m_frontEndPeer;
+
+ // TODO: Add pointer to Drawable or references to VBO's and other info needed to draw
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_RENDERNODE_H
diff --git a/src/render/backend/renderscenebuilder.cpp b/src/render/backend/renderscenebuilder.cpp
new file mode 100644
index 000000000..9e861d65f
--- /dev/null
+++ b/src/render/backend/renderscenebuilder.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderscenebuilder.h"
+
+#include "meshmanager.h"
+#include "renderer.h"
+#include "rendernode.h"
+
+#include <camera.h>
+#include <material.h>
+#include <mesh.h>
+#include <transform.h>
+
+#include <entity.h>
+
+namespace Qt3D {
+namespace Render {
+
+RenderSceneBuilder::RenderSceneBuilder(Renderer *renderer)
+ : Qt3D::NodeVisitor()
+ , m_renderer(renderer)
+ , m_rootNode(0)
+{
+}
+
+void RenderSceneBuilder::visitNode(Qt3D::Node *node)
+{
+ if (!m_rootNode) {
+ m_rootNode = new RenderNode(m_renderer->rendererAspect());
+ m_rootNode->m_frontEndPeer = node;
+ m_nodeStack.push(m_rootNode);
+ }
+
+ Qt3D::NodeVisitor::visitNode(node);
+}
+
+void RenderSceneBuilder::visitEntity(Qt3D::Entity *entity)
+{
+ // Create a RenderNode corresponding to the Entity. Most data will
+ // be calculated later by jobs
+ RenderNode *renderNode = new RenderNode(m_renderer->rendererAspect(), m_nodeStack.top());
+ renderNode->m_frontEndPeer = entity;
+ *(renderNode->m_localTransform) = entity->matrix();
+ m_nodeStack.push(renderNode);
+
+ // Look for a transform component
+ QList<Transform *> transforms = entity->componentsOfType<Transform>();
+ if (!transforms.isEmpty())
+ renderNode->setPeer(transforms.first());
+
+// QList<Material *> materials = entity->componentsOfType<Material>();
+// Material *material = 0;
+// if (!materials.isEmpty())
+// material = materials.first();
+
+ // We'll update matrices in a job later. In fact should the matrix be decoupled from the mesh?
+ foreach (Mesh *mesh, entity->componentsOfType<Mesh>()) {
+ m_renderer->meshManager()->addMesh(mesh);
+ //m_renderer->buildMeshes(mesh, material, QMatrix4x4());
+ }
+
+ //foreach (Camera *camera, entity->componentsOfType<Camera>())
+ // m_renderer->foundCamera(camera, entity->sceneMatrix());
+
+ NodeVisitor::visitEntity(entity);
+
+ // Coming back up the tree
+ m_nodeStack.pop();
+}
+
+} // namespace Render
+} // namespace Qt3D
diff --git a/src/render/backend/renderscenebuilder.h b/src/render/backend/renderscenebuilder.h
new file mode 100644
index 000000000..2f3812f26
--- /dev/null
+++ b/src/render/backend/renderscenebuilder.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDER_RENDERSCENEBUILDER_H
+#define QT3D_RENDER_RENDERSCENEBUILDER_H
+
+#include <nodevisitor.h>
+
+#include <QStack>
+
+namespace Qt3D {
+namespace Render {
+
+class Renderer;
+class RenderNode;
+
+class RenderSceneBuilder : public Qt3D::NodeVisitor
+{
+public:
+ explicit RenderSceneBuilder(Renderer *renderer);
+
+ RenderNode *rootNode() const { return m_rootNode; }
+
+protected:
+ void visitNode(Qt3D::Node *node) Q_DECL_OVERRIDE;
+ void visitEntity(Qt3D::Entity *entity) Q_DECL_OVERRIDE;
+
+private:
+ Renderer *m_renderer;
+ RenderNode *m_rootNode;
+ QStack<RenderNode *> m_nodeStack;
+};
+
+} // namespace Render
+} // namespace Qt3D
+
+#endif // QT3D_RENDER_RENDERSCENEBUILDER_H
diff --git a/src/render/backend/rendershader.cpp b/src/render/backend/rendershader.cpp
new file mode 100644
index 000000000..243cf4ffa
--- /dev/null
+++ b/src/render/backend/rendershader.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendershader.h"
+
+#include <QDebug>
+#include <QOpenGLContext>
+#include <QOpenGLShaderProgram>
+
+#include <shaderprogram.h>
+
+namespace Qt3D
+{
+
+RenderShader::RenderShader(ShaderProgram *peer) :
+ m_program(NULL),
+ m_peer(peer)
+{
+ Q_ASSERT(peer);
+}
+
+QOpenGLShaderProgram *RenderShader::getOrCreateProgram()
+{
+ if (!m_program) {
+ // waiting for shader source to be loaded
+ if (!m_peer->isLoaded()) {
+
+ // FIXME - should not be done in the backend!
+ m_peer->load();
+ //return NULL;
+ }
+
+ m_program = createProgram();
+ if (!m_program)
+ m_program = createDefaultProgram();
+ }
+
+ return m_program;
+}
+
+void RenderShader::setStandardUniform(Parameter::StandardUniform su, QString name)
+{
+ Q_ASSERT(su != Parameter::None);
+ Q_ASSERT(!name.isEmpty());
+ int index = static_cast<int>(su);
+ if (index >= m_standardUniformNames.size())
+ m_standardUniformNames.resize(index + 1);
+ m_standardUniformNames[index] = name;
+}
+
+QString RenderShader::name() const
+{
+ return m_peer->objectName();
+}
+
+QOpenGLShaderProgram* RenderShader::createProgram()
+{
+ Q_ASSERT(QOpenGLContext::currentContext());
+ // scoped pointer so early-returns delete automatically
+ QScopedPointer<QOpenGLShaderProgram> p(new QOpenGLShaderProgram);
+ bool ok = p->addShaderFromSourceCode(QOpenGLShader::Vertex,
+ m_peer->vertexSourceCode());
+ if (!ok) {
+ qWarning() << "bad vertex source:" << m_program->log();
+ return NULL;
+ }
+
+ ok = p->addShaderFromSourceCode(QOpenGLShader::Fragment,
+ m_peer->fragmentSourceCode());
+ if (!ok) {
+ qWarning() << "bad fragment source:" << m_program->log();
+ return NULL;
+ }
+
+ ok = p->link();
+ if (!ok) {
+ qWarning() << "program failed to link:" << m_program->log();
+ return NULL;
+ }
+
+ m_standardUniformLocations.resize(m_standardUniformNames.size());
+ for (int i=0; i<m_standardUniformNames.size(); ++i) {
+ QString n = m_standardUniformNames.at(i);
+ if (n.isEmpty()) {
+ m_standardUniformLocations[i] = -1;
+ continue;
+ }
+
+ m_standardUniformLocations[i] = p->uniformLocation(n);
+ // qDebug() << "resolved location" << m_standardUniformLocations[i] <<
+ // "for uniform" << n;
+ }
+
+ // take from scoped-pointer so it doesn't get deleted
+ return p.take();
+}
+
+QOpenGLShaderProgram* RenderShader::createDefaultProgram()
+{
+ QOpenGLShaderProgram* p = new QOpenGLShaderProgram;
+ p->addShaderFromSourceCode(QOpenGLShader::Vertex,
+ "");
+
+ p->addShaderFromSourceCode(QOpenGLShader::Fragment,
+ "");
+
+ p->link();
+
+ return p;
+}
+
+} // of namespace Qt3D
diff --git a/src/render/backend/rendershader.h b/src/render/backend/rendershader.h
new file mode 100644
index 000000000..0b326e02d
--- /dev/null
+++ b/src/render/backend/rendershader.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERSHADER_H
+#define RENDERSHADER_H
+
+#include <QVector>
+
+// for Parameter::StandardUniforms enum - maybe should move to
+// somewhere common to avoid this include?
+#include <technique.h>
+
+class QOpenGLShaderProgram;
+
+namespace Qt3D
+{
+
+class ShaderProgram;
+
+class RenderShader
+{
+public:
+ RenderShader(ShaderProgram* peer);
+
+ /**
+ * @brief getOrCreateProgram
+ * must be called with a valid, current QOpenGLContext
+ * @return
+ */
+ QOpenGLShaderProgram* getOrCreateProgram();
+
+ /**
+ * @brief setStandardUniform - set the program name of a uniform
+ * @param su - the standard uniform
+ * @param loc - the GLSL name corresponding to the uniform
+ */
+ void setStandardUniform(Parameter::StandardUniform su, QString name);
+
+ /**
+ * @brief standardUniformLocations - vecotr of uniform locations
+ * within the compiled program, corresponding to the standard uniforms
+ * [index the vector by the StandardUniform enum]
+ * @return
+ */
+ QVector<int> standardUniformLocations() const
+ {
+ return m_standardUniformLocations;
+ }
+
+ QString name() const;
+private:
+ QOpenGLShaderProgram* m_program;
+ ShaderProgram* m_peer;
+
+ QOpenGLShaderProgram *createProgram();
+ QOpenGLShaderProgram *createDefaultProgram();
+
+ QVector<QString> m_standardUniformNames;
+ QVector<int> m_standardUniformLocations;
+};
+
+}
+
+
+#endif // RENDERSHADER_H
diff --git a/src/render/backend/rendertechnique.cpp b/src/render/backend/rendertechnique.cpp
new file mode 100644
index 000000000..7bac88023
--- /dev/null
+++ b/src/render/backend/rendertechnique.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendertechnique.h"
+#include "rendershader.h"
+
+#include <renderpass.h>
+#include <technique.h>
+
+#include <QDebug>
+
+namespace Qt3D
+{
+
+RenderTechnique::RenderTechnique(Technique* peer) :
+ m_peer(peer)
+{
+ m_passCount = peer->renderPasses().count();
+ m_passBin.resize(m_passCount);
+ m_passShader.resize(m_passCount);
+}
+
+unsigned int RenderTechnique::passCount() const
+{
+ return m_passCount;
+}
+
+void RenderTechnique::setShaderForPass(unsigned int passIndex, RenderShader *s)
+{
+ Q_ASSERT(passIndex < passCount());
+ m_passShader[passIndex] = s;
+
+ // bind standard uniform names
+
+ RenderPass* pass = m_peer->renderPasses().at(passIndex);
+ foreach (Parameter* p, m_peer->parameters()) {
+ if (!p->isStandardUniform())
+ continue;
+
+ QString glslName = pass->glslNameForParameter(p->name());
+ if (glslName.isEmpty())
+ continue;
+
+ s->setStandardUniform(p->standardUniform(), glslName);
+ } // of parameter iteration
+}
+
+RenderShader *RenderTechnique::shaderForPass(unsigned int pass)
+{
+ Q_ASSERT(pass < passCount());
+ return m_passShader.at(pass);
+}
+
+void RenderTechnique::setBinForPass(unsigned int pass, RenderBin *bin)
+{
+ Q_ASSERT(pass < passCount());
+ m_passBin[pass] = bin;
+}
+
+RenderBin *RenderTechnique::binForPass(unsigned int pass) const
+{
+ return m_passBin.at(pass);
+}
+
+DrawStateSet *RenderTechnique::stateSetForPass(unsigned int pass) const
+{
+ return m_peer->renderPasses().at(pass)->stateSet();
+}
+
+QString RenderTechnique::glslNameForMeshAttribute(unsigned int passIndex, QString meshAttributeName)
+{
+ // find the parameter
+ foreach (Parameter* p, m_peer->parameters()) {
+ if (p->meshAttributeName() != meshAttributeName) {
+ continue;
+ }
+
+ Q_ASSERT((int) passIndex < m_peer->renderPasses().count());
+ RenderPass* pass = m_peer->renderPasses().at(passIndex);
+
+ return pass->glslNameForParameter(p->name());
+ } // of parameter iteration
+
+ // mesh attribute is not referenced in this technique
+ return QString();
+}
+
+Parameter *RenderTechnique::parameterByName(QString name) const
+{
+ foreach (Parameter* p, m_peer->parameters()) {
+ if (p->name() == name)
+ return p;
+ }
+
+ qWarning() << Q_FUNC_INFO << "couldn't find parameter:" << name
+ << "in technique" << m_peer->objectName();
+ return NULL;
+}
+
+QStringList RenderTechnique::glslNamesForUniformParameter(QString pName) const
+{
+ QStringList result;
+ Parameter* param = parameterByName(pName);
+ if (!param)
+ return result;
+
+ for (unsigned int p=0; p<m_passCount;++p) {
+ RenderPass* pass = m_peer->renderPasses().at(p);
+ // will return an empty QString if the pass doesn't use the parameter,
+ // but that's what we want so no probem.
+ QString glslName = pass->glslNameForParameter(pName);
+ result.append(glslName);
+ }
+
+ return result;
+}
+
+} // of namespace Qt3D
diff --git a/src/render/backend/rendertechnique.h b/src/render/backend/rendertechnique.h
new file mode 100644
index 000000000..41aab29bb
--- /dev/null
+++ b/src/render/backend/rendertechnique.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERTECHNIQUE_H
+#define RENDERTECHNIQUE_H
+
+#include <QVector>
+#include <QStringList>
+
+namespace Qt3D
+{
+
+class Technique;
+class RenderShader;
+class RenderBin;
+class Parameter;
+class DrawStateSet;
+
+class RenderTechnique
+{
+public:
+ RenderTechnique(Technique* peer);
+
+ unsigned int passCount() const;
+
+ void setShaderForPass(unsigned int pass, RenderShader* s);
+ RenderShader* shaderForPass(unsigned int pass);
+
+ void setBinForPass(unsigned int pas, RenderBin* bin);
+ RenderBin* binForPass(unsigned int pass) const;
+
+ DrawStateSet* stateSetForPass(unsigned int pass) const;
+
+ QString glslNameForMeshAttribute(unsigned int pass, QString meshAttributeName);
+
+ QStringList glslNamesForUniformParameter(QString pName) const;
+
+ // FIXME using front-end classes here, not ideal
+ Parameter* parameterByName(QString name) const;
+private:
+ Technique* m_peer;
+ unsigned int m_passCount;
+
+ // really need more than just the shader here, i.e other
+ // technique state
+ QVector<RenderShader*> m_passShader;
+ QVector<RenderBin*> m_passBin;
+
+
+
+
+};
+
+} // of namespace Qgt3D
+
+#endif // RENDERTECHNIQUE_H
diff --git a/src/render/backend/rendertexture.cpp b/src/render/backend/rendertexture.cpp
new file mode 100644
index 000000000..dbb796669
--- /dev/null
+++ b/src/render/backend/rendertexture.cpp
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendertexture.h"
+
+#include <QDebug>
+#include <QOpenGLTexture>
+#include <QOpenGLPixelTransferOptions>
+
+#include <texturedata.h>
+
+namespace Qt3D {
+
+RenderTexture::RenderTexture(Texture* peer) :
+ m_peer(peer),
+ m_gl(NULL)
+{
+}
+
+QOpenGLTexture *RenderTexture::getOrCreateGLTexture()
+{
+ if (m_gl)
+ return m_gl;
+
+ m_gl = buildGLTexture();
+
+ m_gl->allocateStorage();
+ if (!m_gl->isStorageAllocated()) {
+ qWarning() << Q_FUNC_INFO << "texture storage allocation failed";
+ return NULL;
+ }
+
+ foreach (TexImageDataPtr imgData, m_peer->imageData()) {
+ setToGLTexture(imgData);
+ } // of image data in texture iteration
+
+ if (m_peer->generateMipMaps()) {
+ m_gl->generateMipMaps();
+ }
+
+ int err = glGetError();
+ if (err)
+ qWarning() << Q_FUNC_INFO <<
+ "GL error after generating mip-maps" << QString::number(err, 16);
+
+
+ return m_gl;
+}
+
+QOpenGLTexture *RenderTexture::buildGLTexture()
+{
+ QOpenGLTexture* glTex = new QOpenGLTexture(m_peer->target());
+ glTex->setFormat(m_peer->format());
+ glTex->setSize(m_peer->width(),
+ m_peer->height(),
+ m_peer->depth());
+
+ if (!glTex->create()) {
+ qWarning() << Q_FUNC_INFO << "creating QOpenGLTexture failed";
+ return NULL;
+ }
+
+ glTex->setWrapMode(m_peer->wrapMode());
+ glTex->setMinMagFilters(m_peer->minificationFilter(),
+ m_peer->magnificationFilter());
+
+ // FIXME : make this conditional on Qt version
+ // work-around issue in QOpenGLTexture DSA emulaation which rasies
+ // an Invalid Enum error
+ glGetError();
+
+ return glTex;
+}
+
+void RenderTexture::setToGLTexture(TexImageDataPtr imgData)
+{
+ Q_ASSERT(m_gl && m_gl->isCreated() && m_gl->isStorageAllocated());
+ // ensure we don't accidently cause a detach / copy of the raw bytes
+ const QByteArray& bytes(imgData->data());
+ char* rawPtr = const_cast<char*>(bytes.constData());
+ if (imgData->isCompressed()) {
+ m_gl->setCompressedData(imgData->mipMapLevel(),
+ imgData->layer(),
+ imgData->cubeFace(),
+ bytes.size(),
+ rawPtr);
+ } else {
+ QOpenGLPixelTransferOptions uploadOptions;
+ uploadOptions.setAlignment(1);
+ m_gl->setData(imgData->mipMapLevel(),
+ imgData->layer(),
+ imgData->cubeFace(),
+ imgData->pixelFormat(),
+ imgData->pixelType(),
+ rawPtr,
+ &uploadOptions);
+ }
+
+ // FIXME : make this conditional on Qt version
+ // work-around issue in QOpenGLTexture DSA emulaation which rasies
+ // an Invalid Enum error
+ glGetError();
+}
+
+
+GLint RenderTexture::textureId()
+{
+ return getOrCreateGLTexture()->textureId();
+}
+
+} // namespace Qt3D
diff --git a/src/render/backend/rendertexture.h b/src/render/backend/rendertexture.h
new file mode 100644
index 000000000..ff418be0b
--- /dev/null
+++ b/src/render/backend/rendertexture.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDERTEXTURE_H
+#define QT3D_RENDERTEXTURE_H
+
+#include <QOpenGLContext>
+
+#include <texturedata.h>
+
+// forward decls
+class QOpenGLTexture;
+
+namespace Qt3D {
+
+class RenderTexture
+{
+public:
+ RenderTexture(Texture* peer);
+
+ QOpenGLTexture* getOrCreateGLTexture() ;
+
+ GLint textureId();
+private:
+ Texture* m_peer;
+ QOpenGLTexture* m_gl;
+
+ QOpenGLTexture *buildGLTexture();
+ void setToGLTexture(TexImageDataPtr imgData);
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_RENDERTEXTURE_H
diff --git a/src/render/backend/rendertextureprovider.cpp b/src/render/backend/rendertextureprovider.cpp
new file mode 100644
index 000000000..0727272f4
--- /dev/null
+++ b/src/render/backend/rendertextureprovider.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "rendertextureprovider.h"
+
+#include "rendertexture.h"
+
+namespace Qt3D {
+
+RenderTextureProvider::RenderTextureProvider()
+{
+}
+
+RenderTexturePtr RenderTextureProvider::get(Texture *t)
+{
+ if (m_dict.contains(t))
+ return m_dict.value(t);
+
+ RenderTexturePtr rt(new RenderTexture(t));
+ m_dict[t] = rt;
+
+ return rt;
+}
+
+} // namespace Qt3D
diff --git a/src/render/backend/rendertextureprovider.h b/src/render/backend/rendertextureprovider.h
new file mode 100644
index 000000000..70536dcab
--- /dev/null
+++ b/src/render/backend/rendertextureprovider.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_RENDERTEXTUREPROVIDER_H
+#define QT3D_RENDERTEXTUREPROVIDER_H
+
+#include <QSharedPointer>
+#include <QHash>
+
+namespace Qt3D {
+
+class Texture;
+
+class RenderTexture;
+typedef QSharedPointer<RenderTexture> RenderTexturePtr;
+
+class RenderTextureProvider
+{
+public:
+ RenderTextureProvider();
+
+ RenderTexturePtr get(Texture* t);
+private:
+ QHash<Texture*, RenderTexturePtr> m_dict;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_RENDERTEXTUREPROVIDER_H
diff --git a/src/render/backend/renderthread.cpp b/src/render/backend/renderthread.cpp
new file mode 100644
index 000000000..f679bc2f6
--- /dev/null
+++ b/src/render/backend/renderthread.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderthread.h"
+#include "renderer.h"
+
+#include <QDebug>
+#include <QEventLoop>
+#include <QTime>
+
+namespace Qt3D {
+
+RenderThread::RenderThread( QObject* parent )
+ : QThread( parent ),
+ m_renderer( 0 ),
+ m_eventHandler( 0 )
+{
+}
+
+void RenderThread::waitForStart( Priority priority )
+{
+ qDebug() << "Starting Render thread and then going to sleep until it is ready for us...";
+ m_mutex.lock();
+ start( priority );
+ m_waitCondition.wait( &m_mutex );
+ qDebug() << "Render thread is now ready & calling thread is now awake again";
+}
+
+void RenderThread::run()
+{
+ m_mutex.lock();
+
+// Create worker objects
+ m_renderer = new Render::Renderer;
+ //m_eventHandler = new RenderEventProcessor;
+
+ m_waitCondition.wakeOne();
+ m_mutex.unlock();
+
+ // Enter the render thread event loop
+ exec();
+
+ delete m_renderer;
+}
+
+}
diff --git a/src/render/backend/renderthread.h b/src/render/backend/renderthread.h
new file mode 100644
index 000000000..c1471921e
--- /dev/null
+++ b/src/render/backend/renderthread.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERTHREAD_H
+#define RENDERTHREAD_H
+
+#include <QThread>
+
+#include <QMutex>
+#include <QWaitCondition>
+
+namespace Qt3D {
+namespace Render {
+class Renderer;
+}
+
+class RenderEventProcessor;
+
+class RenderThread : public QThread
+{
+ Q_OBJECT
+public:
+ explicit RenderThread( QObject* parent = 0 );
+
+ void waitForStart( Priority priority = InheritPriority );
+
+ Render::Renderer* renderer() const { return m_renderer; }
+
+ RenderEventProcessor* eventHandler() const { return m_eventHandler; }
+protected:
+ void run();
+
+private:
+ QMutex m_mutex;
+ QWaitCondition m_waitCondition;
+ Render::Renderer* m_renderer;
+ RenderEventProcessor* m_eventHandler;
+};
+
+}
+
+#endif // RENDERTHREAD_H
diff --git a/src/render/backend/states/blendstate.cpp b/src/render/backend/states/blendstate.cpp
new file mode 100644
index 000000000..c15cc56b9
--- /dev/null
+++ b/src/render/backend/states/blendstate.cpp
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "blendstate.h"
+
+#include "qgraphicscontext.h"
+
+#include <QOpenGLFunctions_3_2_Core>
+
+namespace Qt3D {
+
+template <class State>
+State* getOrCreateImpl(const State& data)
+{
+ static QList<State*> static_instances;
+ foreach (State* ext, static_instances) {
+ if (ext->isEqual(data))
+ return ext;
+ }
+
+ State* result = new State(data);
+ static_instances.append(result);
+ return result;
+}
+
+void BlendState::apply(QGraphicsContext* gc) const
+{
+ Q_UNUSED(gc);
+ glEnable(GL_BLEND);
+ glBlendFunc( m_1, m_2 );
+}
+
+StateMaskSet BlendState::mask() const
+{
+ return BlendStateMask;
+}
+
+BlendState *BlendState::getOrCreate(GLenum src, GLenum dst)
+{
+ BlendState bs(src, dst);
+ return getOrCreateImpl(bs);
+}
+
+BlendState::BlendState(GLenum src, GLenum dst) :
+ GenericState2(src, dst)
+{
+}
+
+void BlendEquation::apply(QGraphicsContext *gc) const
+{
+ Q_UNUSED(gc);
+
+ if (!m_funcs) {
+ m_funcs = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_2_Core>();
+ m_funcs->initializeOpenGLFunctions();
+ }
+
+ m_funcs->glBlendEquation(m_1);
+}
+
+BlendEquation *BlendEquation::getOrCreate(GLenum func)
+{
+ return getOrCreateImpl(BlendEquation(func));
+}
+
+BlendEquation::BlendEquation(GLenum func) :
+ GenericState1(func),
+ m_funcs(0)
+{
+}
+
+
+void AlphaFunc::apply(QGraphicsContext* gc) const
+{
+ Q_UNUSED(gc);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc( m_1, m_2 );
+}
+
+AlphaFunc *AlphaFunc::getOrCreate(GLenum func, GLclampf value)
+{
+ AlphaFunc af(func, value);
+ return getOrCreateImpl(af);
+}
+
+AlphaFunc::AlphaFunc(GLenum func, GLclampf value) :
+ GenericState2(func, value)
+{
+}
+
+void DepthTest::apply(QGraphicsContext *gc) const
+{
+ Q_UNUSED(gc);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc( m_1 );
+}
+
+DepthTest *DepthTest::getOrCreate(GLenum func)
+{
+ DepthTest dt(func);
+ return getOrCreateImpl(dt);
+}
+
+DepthTest::DepthTest(GLenum func) :
+ GenericState1(func)
+{
+}
+
+void CullFace::apply(QGraphicsContext *gc) const
+{
+ Q_UNUSED(gc);
+ glEnable(GL_CULL_FACE);
+ glCullFace( m_1 );
+}
+
+CullFace *CullFace::getOrCreate(GLenum func)
+{
+ return getOrCreateImpl(CullFace(func));
+}
+
+CullFace::CullFace(GLenum func) :
+ GenericState1(func)
+{
+}
+
+void FrontFace::apply(QGraphicsContext *gc) const
+{
+ Q_UNUSED(gc);
+ glFrontFace(m_1);
+}
+
+FrontFace *FrontFace::getOrCreate(GLenum func)
+{
+ return getOrCreateImpl(FrontFace(func));
+}
+
+FrontFace::FrontFace(GLenum func) :
+ GenericState1(func)
+{
+}
+
+void DepthMask::apply(QGraphicsContext *gc) const
+{
+ Q_UNUSED(gc)
+ glDepthMask(m_1);
+}
+
+DepthMask *DepthMask::getOrCreate(GLboolean flag)
+{
+ return getOrCreateImpl(DepthMask(flag));
+}
+
+DepthMask::DepthMask(GLboolean flag) :
+ GenericState1(flag)
+{
+}
+
+
+} // of namespace
diff --git a/src/render/backend/states/blendstate.h b/src/render/backend/states/blendstate.h
new file mode 100644
index 000000000..6a294010d
--- /dev/null
+++ b/src/render/backend/states/blendstate.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BLENDSTATE_H
+#define BLENDSTATE_H
+
+#include <drawstate.h>
+#include <genericstate.h>
+
+#include <QOpenGLContext>
+
+class QOpenGLFunctions_3_2_Core;
+
+namespace Qt3D {
+
+class BlendState : public GenericState2<BlendState, GLenum, GLenum>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+ virtual StateMaskSet mask() const;
+
+ static BlendState* getOrCreate(GLenum src, GLenum dst);
+private:
+ BlendState(GLenum src, GLenum dst);
+};
+
+class BlendEquation : public GenericState1<BlendEquation, GLenum>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return BlendStateMask; }
+
+ static BlendEquation* getOrCreate(GLenum func);
+
+private:
+ BlendEquation(GLenum func);
+ mutable QOpenGLFunctions_3_2_Core *m_funcs;
+};
+
+
+class AlphaFunc : public GenericState2<AlphaFunc, GLenum, GLclampf>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return AlphaTestMask; }
+
+ static AlphaFunc* getOrCreate(GLenum func, GLclampf value);
+private:
+ AlphaFunc(GLenum func, GLclampf value);
+};
+
+class DepthTest : public GenericState1<DepthTest, GLenum>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return DepthTestStateMask; }
+
+ static DepthTest* getOrCreate(GLenum func);
+
+private:
+ DepthTest(GLenum func);
+};
+
+class DepthMask : public GenericState1<DepthMask, GLboolean>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return DepthWriteStateMask; }
+
+ static DepthMask* getOrCreate(GLboolean func);
+
+private:
+ DepthMask(GLboolean func);
+};
+
+class CullFace : public GenericState1<CullFace, GLenum>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return CullFaceStateMask; }
+
+ static CullFace* getOrCreate(GLenum func);
+
+private:
+ CullFace(GLenum func);
+};
+
+class FrontFace : public GenericState1<FrontFace, GLenum>
+{
+public:
+ virtual void apply(QGraphicsContext* gc) const;
+
+ virtual StateMaskSet mask() const
+ { return FrontFaceStateMask; }
+
+ static FrontFace* getOrCreate(GLenum func);
+
+private:
+ FrontFace(GLenum func);
+};
+
+
+} // of namespace
+
+#endif // BLENDSTATE_H
diff --git a/src/render/frontend/camera.cpp b/src/render/frontend/camera.cpp
new file mode 100644
index 000000000..b408cae8f
--- /dev/null
+++ b/src/render/frontend/camera.cpp
@@ -0,0 +1,483 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "camera.h"
+#include "camera_p.h"
+
+namespace Qt3D {
+
+Camera::Camera(Node *parent)
+ : Component(parent)
+ , d_ptr(new CameraPrivate(this))
+{
+ qDebug() << Q_FUNC_INFO;
+}
+
+void Camera::setViewMatrix(const QMatrix4x4 &m)
+{
+ Q_D(Camera);
+
+ // derive the position and up vecotr
+
+ bool ok;
+ QMatrix4x4 iv = m.inverted(&ok);
+ if (!ok) {
+ qWarning() << Q_FUNC_INFO << "passed non-invertible matrix";
+ return;
+ }
+
+ // position in eye-coordinates is simple the origin
+ d->m_position = (iv * QVector4D(0,0,0,1)).toVector3D();
+
+ // up vector, w=0 (no translation), positive Y-axis
+ d->m_upVector = (iv * QVector4D(0,1,0,0)).toVector3D();
+
+ // look vector, w=0, positive Z-axis
+ d->m_cameraToCenter = (iv * QVector4D(0,0,1,0)).toVector3D();
+
+ d->m_viewMatrix = m;
+ d->m_syncNeeded = true;
+}
+
+void Camera::setProjectionType(ProjectionType projectionType)
+{
+ Q_D(Camera);
+ if (d->m_projectionType != projectionType) {
+ d->m_projectionType = projectionType;
+ emit projectionTypeChanged();
+ }
+}
+
+Camera::ProjectionType Camera::projectionType() const
+{
+ Q_D(const Camera);
+ return d->m_projectionType;
+}
+
+QVector3D Camera::position() const
+{
+ Q_D(const Camera);
+ return d->m_position;
+}
+
+void Camera::setPosition( const QVector3D& position )
+{
+ Q_D(Camera);
+ d->m_position = position;
+ d->m_cameraToCenter = d->m_viewCenter - position;
+ d->m_viewMatrixDirty = true;
+ d->m_syncNeeded = true;
+}
+
+void Camera::setUpVector( const QVector3D& upVector )
+{
+ Q_D(Camera);
+ d->m_upVector = upVector;
+ d->m_viewMatrixDirty = true;
+ d->m_syncNeeded = true;
+}
+
+QVector3D Camera::upVector() const
+{
+ Q_D(const Camera);
+ return d->m_upVector;
+}
+
+void Camera::setViewCenter( const QVector3D& viewCenter )
+{
+ Q_D(Camera);
+ d->m_viewCenter = viewCenter;
+ d->m_cameraToCenter = viewCenter - d->m_position;
+ d->m_viewMatrixDirty = true;
+ d->m_syncNeeded = true;
+}
+
+QVector3D Camera::viewCenter() const
+{
+ Q_D(const Camera);
+ return d->m_viewCenter;
+}
+
+QVector3D Camera::viewVector() const
+{
+ Q_D(const Camera);
+ return d->m_cameraToCenter;
+}
+
+void Camera::setOrthographicProjection( float left, float right,
+ float bottom, float top,
+ float nearPlane, float farPlane )
+{
+ Q_D(Camera);
+ d->m_left = left;
+ d->m_right = right;
+ d->m_bottom = bottom;
+ d->m_top = top;
+ d->m_nearPlane = nearPlane;
+ d->m_farPlane = farPlane;
+ d->m_projectionType = OrthogonalProjection;
+ d->updateOrthogonalProjection();
+}
+
+void Camera::setPerspectiveProjection( float fieldOfView, float aspectRatio,
+ float nearPlane, float farPlane )
+{
+ Q_D(Camera);
+ d->m_fieldOfView = fieldOfView;
+ d->m_aspectRatio = aspectRatio;
+ d->m_nearPlane = nearPlane;
+ d->m_farPlane = farPlane;
+ d->m_projectionType = PerspectiveProjection;
+ d->updatePerpectiveProjection();
+}
+
+void Camera::setNearPlane(float nearPlane)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_nearPlane, nearPlane))
+ return;
+ d->m_nearPlane = nearPlane;
+ if (d->m_projectionType == PerspectiveProjection)
+ d->updatePerpectiveProjection();
+ emit nearPlaneChanged();
+}
+
+float Camera::nearPlane() const
+{
+ Q_D(const Camera);
+ return d->m_nearPlane;
+}
+
+void Camera::setFarPlane(float farPlane)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_farPlane, farPlane))
+ return;
+ d->m_farPlane = farPlane;
+ if (d->m_projectionType == PerspectiveProjection)
+ d->updatePerpectiveProjection();
+ emit farPlaneChanged();
+}
+
+float Camera::farPlane() const
+{
+ Q_D(const Camera);
+ return d->m_farPlane;
+}
+
+void Camera::setFieldOfView(float fieldOfView)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_fieldOfView, fieldOfView))
+ return;
+ d->m_fieldOfView = fieldOfView;
+ if (d->m_projectionType == PerspectiveProjection)
+ d->updatePerpectiveProjection();
+ emit fieldOfViewChanged();
+}
+
+float Camera::fieldOfView() const
+{
+ Q_D(const Camera);
+ return d->m_fieldOfView;
+}
+
+void Camera::setAspectRatio(float aspectRatio)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_aspectRatio, aspectRatio))
+ return;
+ d->m_aspectRatio = aspectRatio;
+ if (d->m_projectionType == PerspectiveProjection)
+ d->updatePerpectiveProjection();
+ emit aspectRatioChanged();
+}
+
+float Camera::aspectRatio() const
+{
+ Q_D(const Camera);
+ return d->m_aspectRatio;
+}
+
+void Camera::setLeft(float left)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_left, left))
+ return;
+ d->m_left = left;
+ if (d->m_projectionType == OrthogonalProjection)
+ d->updateOrthogonalProjection();
+ emit leftChanged();
+}
+
+float Camera::left() const
+{
+ Q_D(const Camera);
+ return d->m_left;
+}
+
+void Camera::setRight(float right)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_right, right))
+ return;
+ d->m_right = right;
+ if (d->m_projectionType == OrthogonalProjection)
+ d->updateOrthogonalProjection();
+ emit rightChanged();
+}
+
+float Camera::right() const
+{
+ Q_D(const Camera);
+ return d->m_right;
+}
+
+void Camera::setBottom(float bottom)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_bottom, bottom))
+ return;
+ d->m_bottom = bottom;
+ if (d->m_projectionType == OrthogonalProjection)
+ d->updateOrthogonalProjection();
+ emit bottomChanged();
+}
+
+float Camera::bottom() const
+{
+ Q_D(const Camera);
+ return d->m_bottom;
+}
+
+void Camera::setTop(float top)
+{
+ Q_D(Camera);
+ if (qFuzzyCompare(d->m_top, top))
+ return;
+ d->m_top = top;
+ if (d->m_projectionType == OrthogonalProjection)
+ d->updateOrthogonalProjection();
+ emit topChanged();
+}
+
+float Camera::top() const
+{
+ Q_D(const Camera);
+ return d->m_top;
+}
+
+QMatrix4x4 Camera::viewMatrix() const
+{
+ Q_D(const Camera);
+ if ( d->m_viewMatrixDirty )
+ {
+ d->m_viewMatrix.setToIdentity();
+ d->m_viewMatrix.lookAt( d->m_position, d->m_viewCenter, d->m_upVector );
+ d->m_viewMatrixDirty = false;
+ }
+ return d->m_viewMatrix;
+}
+
+QMatrix4x4 Camera::projectionMatrix() const
+{
+ Q_D(const Camera);
+ return d->m_projectionMatrix;
+}
+
+QMatrix4x4 Camera::viewProjectionMatrix() const
+{
+ Q_D(const Camera);
+ if ( d->m_viewMatrixDirty || d->m_viewProjectionMatrixDirty )
+ {
+ d->m_viewProjectionMatrix = d->m_projectionMatrix * viewMatrix();
+ d->m_viewProjectionMatrixDirty = false;
+ }
+ return d->m_viewProjectionMatrix;
+}
+
+void Camera::translate( const QVector3D& vLocal, CameraTranslationOption option )
+{
+ Q_D(Camera);
+
+ // Calculate the amount to move by in world coordinates
+ QVector3D vWorld;
+ if ( !qFuzzyIsNull( vLocal.x() ) )
+ {
+ // Calculate the vector for the local x axis
+ QVector3D x = QVector3D::crossProduct( d->m_cameraToCenter, d->m_upVector ).normalized();
+ vWorld += vLocal.x() * x;
+ }
+
+ if ( !qFuzzyIsNull( vLocal.y() ) )
+ vWorld += vLocal.y() * d->m_upVector;
+
+ if ( !qFuzzyIsNull( vLocal.z() ) )
+ vWorld += vLocal.z() * d->m_cameraToCenter.normalized();
+
+ // Update the camera position using the calculated world vector
+ d->m_position += vWorld;
+
+ // May be also update the view center coordinates
+ if ( option == TranslateViewCenter )
+ d->m_viewCenter += vWorld;
+
+ // Refresh the camera -> view center vector
+ d->m_cameraToCenter = d->m_viewCenter - d->m_position;
+
+ // Calculate a new up vector. We do this by:
+ // 1) Calculate a new local x-direction vector from the cross product of the new
+ // camera to view center vector and the old up vector.
+ // 2) The local x vector is the normal to the plane in which the new up vector
+ // must lay. So we can take the cross product of this normal and the new
+ // x vector. The new normal vector forms the last part of the orthonormal basis
+ QVector3D x = QVector3D::crossProduct( d->m_cameraToCenter, d->m_upVector ).normalized();
+ d->m_upVector = QVector3D::crossProduct( x, d->m_cameraToCenter ).normalized();
+
+ d->m_viewMatrixDirty = true;
+ d->m_viewProjectionMatrixDirty = true;
+}
+
+void Camera::translateWorld(const QVector3D& vWorld , CameraTranslationOption option )
+{
+ Q_D(Camera);
+
+ // Update the camera position using the calculated world vector
+ d->m_position += vWorld;
+
+ // May be also update the view center coordinates
+ if ( option == TranslateViewCenter )
+ d->m_viewCenter += vWorld;
+
+ // Refresh the camera -> view center vector
+ d->m_cameraToCenter = d->m_viewCenter - d->m_position;
+
+ d->m_viewMatrixDirty = true;
+ d->m_viewProjectionMatrixDirty = true;
+}
+
+QQuaternion Camera::tiltRotation(float angle) const
+{
+ Q_D(const Camera);
+ QVector3D xBasis = QVector3D::crossProduct( d->m_upVector, d->m_cameraToCenter.normalized() ).normalized();
+ return QQuaternion::fromAxisAndAngle( xBasis, -angle );
+}
+
+QQuaternion Camera::panRotation(float angle) const
+{
+ Q_D(const Camera);
+ return QQuaternion::fromAxisAndAngle( d->m_upVector, angle );
+}
+
+QQuaternion Camera::rollRotation(float angle) const
+{
+ Q_D(const Camera);
+ return QQuaternion::fromAxisAndAngle( d->m_cameraToCenter, -angle );
+}
+
+void Camera::tilt( const float& angle )
+{
+ QQuaternion q = tiltRotation( angle );
+ rotate( q );
+}
+
+void Camera::pan( const float& angle )
+{
+ QQuaternion q = panRotation( -angle );
+ rotate( q );
+}
+
+void Camera::roll( const float& angle )
+{
+ QQuaternion q = rollRotation( -angle );
+ rotate( q );
+}
+
+void Camera::tiltAboutViewCenter( const float& angle )
+{
+ QQuaternion q = tiltRotation( -angle );
+ rotateAboutViewCenter( q );
+}
+
+void Camera::panAboutViewCenter( const float& angle )
+{
+ QQuaternion q = panRotation( angle );
+ rotateAboutViewCenter( q );
+}
+
+void Camera::rollAboutViewCenter( const float& angle )
+{
+ QQuaternion q = rollRotation( angle );
+ rotateAboutViewCenter( q );
+}
+
+void Camera::rotate( const QQuaternion& q )
+{
+ Q_D(Camera);
+ d->m_upVector = q.rotatedVector( d->m_upVector );
+ d->m_cameraToCenter = q.rotatedVector( d->m_cameraToCenter );
+ d->m_viewCenter = d->m_position + d->m_cameraToCenter;
+ d->m_viewMatrixDirty = true;
+ d->m_viewProjectionMatrixDirty = true;
+ d->m_syncNeeded = true;
+}
+
+void Camera::rotateAboutViewCenter( const QQuaternion& q )
+{
+ Q_D(Camera);
+ d->m_upVector = q.rotatedVector( d->m_upVector );
+ d->m_cameraToCenter = q.rotatedVector( d->m_cameraToCenter );
+ d->m_position = d->m_viewCenter - d->m_cameraToCenter;
+ d->m_viewMatrixDirty = true;
+ d->m_viewProjectionMatrixDirty = true;
+ d->m_syncNeeded = true;
+}
+
+//void Camera::update(UpdateVisitor *)
+//{
+// Q_D(Camera);
+// if (d->m_syncNeeded) {
+// // ...
+// d->m_syncNeeded = false;
+// }
+//}
+
+}
diff --git a/src/render/frontend/camera.h b/src/render/frontend/camera.h
new file mode 100644
index 000000000..7dd91695a
--- /dev/null
+++ b/src/render/frontend/camera.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CAMERA_H
+#define CAMERA_H
+
+#include "component.h"
+
+#include <QMatrix4x4>
+#include <QQuaternion>
+#include <QVector3D>
+
+namespace Qt3D {
+
+class CameraPrivate;
+
+class Camera : public Component
+{
+ Q_OBJECT
+
+ // TODO Move view matrix out of the camera and use Transform component (once it exists)
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition)
+ Q_PROPERTY(QVector3D upVector READ upVector WRITE setUpVector)
+ Q_PROPERTY(QVector3D viewCenter READ viewCenter WRITE setViewCenter)
+
+ Q_PROPERTY(ProjectionType projectionType READ projectionType WRITE setProjectionType NOTIFY projectionTypeChanged)
+ Q_PROPERTY(float nearPlane READ nearPlane WRITE setNearPlane NOTIFY nearPlaneChanged)
+ Q_PROPERTY(float farPlane READ farPlane WRITE setFarPlane NOTIFY farPlaneChanged)
+
+ Q_PROPERTY(float fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged)
+ Q_PROPERTY(float aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged)
+
+ Q_PROPERTY(float left READ left WRITE setLeft NOTIFY leftChanged)
+ Q_PROPERTY(float right READ right WRITE setRight NOTIFY rightChanged)
+ Q_PROPERTY(float bottom READ bottom WRITE setBottom NOTIFY bottomChanged)
+ Q_PROPERTY(float top READ top WRITE setTop NOTIFY topChanged)
+
+ Q_ENUMS( ProjectionType )
+
+public:
+ explicit Camera(Node *parent = 0);
+
+ enum ProjectionType {
+ OrthogonalProjection,
+ PerspectiveProjection
+ };
+
+ enum CameraTranslationOption {
+ TranslateViewCenter,
+ DontTranslateViewCenter
+ };
+
+ void setViewMatrix(const QMatrix4x4& m);
+
+ QVector3D position() const;
+ QVector3D upVector() const;
+ QVector3D viewCenter() const;
+
+ QVector3D viewVector() const;
+
+ void setProjectionType(ProjectionType projectioType);
+ ProjectionType projectionType() const;
+
+ void setNearPlane(float nearPlane);
+ float nearPlane() const;
+
+ void setFarPlane(float nearPlane);
+ float farPlane() const;
+
+ void setFieldOfView(float fieldOfView);
+ float fieldOfView() const;
+
+ void setAspectRatio(float aspectRatio);
+ float aspectRatio() const;
+
+ void setLeft(float left);
+ float left() const;
+
+ void setRight(float right);
+ float right() const;
+
+ void setBottom(float bottom);
+ float bottom() const;
+
+ void setTop(float top);
+ float top() const;
+
+ QMatrix4x4 viewMatrix() const;
+ QMatrix4x4 projectionMatrix() const;
+ QMatrix4x4 viewProjectionMatrix() const;
+
+ QQuaternion tiltRotation(float angle) const;
+ QQuaternion panRotation(float angle) const;
+ QQuaternion rollRotation(float angle) const;
+
+public slots:
+ void setOrthographicProjection(float left, float right,
+ float bottom, float top,
+ float nearPlane, float farPlane);
+
+ void setPerspectiveProjection(float fieldOfView, float aspect,
+ float nearPlane, float farPlane);
+
+ // TODO These slots should likely be on a modifier one layer up
+ void setPosition( const QVector3D& position );
+ void setUpVector( const QVector3D& upVector );
+ void setViewCenter( const QVector3D& viewCenter );
+
+ // Translate relative to camera orientation axes
+ void translate( const QVector3D& vLocal, CameraTranslationOption option = TranslateViewCenter );
+
+ // Translate relative to world axes
+ void translateWorld( const QVector3D& vWorld, CameraTranslationOption option = TranslateViewCenter );
+
+ void tilt( const float& angle );
+ void pan( const float& angle );
+ void roll( const float& angle );
+
+ void tiltAboutViewCenter( const float& angle );
+ void panAboutViewCenter( const float& angle );
+ void rollAboutViewCenter( const float& angle );
+
+ void rotate( const QQuaternion& q );
+ void rotateAboutViewCenter( const QQuaternion& q );
+
+signals:
+ void projectionTypeChanged();
+ void nearPlaneChanged();
+ void farPlaneChanged();
+ void fieldOfViewChanged();
+ void aspectRatioChanged();
+ void leftChanged();
+ void rightChanged();
+ void bottomChanged();
+ void topChanged();
+
+protected:
+ Q_DECLARE_PRIVATE(Camera)
+
+private:
+ CameraPrivate* d_ptr;
+};
+
+}
+
+#endif // CAMERA_H
diff --git a/src/render/frontend/camera_p.h b/src/render/frontend/camera_p.h
new file mode 100644
index 000000000..7f7015735
--- /dev/null
+++ b/src/render/frontend/camera_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef CAMERA_P_H
+#define CAMERA_P_H
+
+#include <QMatrix4x4>
+#include <QVector3D>
+
+namespace Qt3D {
+
+class CameraPrivate
+{
+public:
+ CameraPrivate( Camera *qq )
+ : q_ptr( qq )
+ , m_position( 0.0f, 0.0f, 1.0f )
+ , m_upVector( 0.0f, 1.0f, 0.0f )
+ , m_viewCenter( 0.0f, 0.0f, 0.0f )
+ , m_cameraToCenter( 0.0f, 0.0f, -1.0f )
+ , m_projectionType( Camera::OrthogonalProjection )
+ , m_nearPlane( 0.1f )
+ , m_farPlane( 1024.0f )
+ , m_fieldOfView( 25.0f )
+ , m_aspectRatio( 1.0f )
+ , m_left( -0.5 )
+ , m_right( 0.5f )
+ , m_bottom( -0.5f )
+ , m_top( 0.5f )
+ , m_viewMatrixDirty( true )
+ , m_viewProjectionMatrixDirty( true )
+ , m_syncNeeded( false )
+ {
+ updateOrthogonalProjection();
+ }
+
+ ~CameraPrivate()
+ {
+ }
+
+ inline void updatePerpectiveProjection()
+ {
+ m_projectionMatrix.setToIdentity();
+ m_projectionMatrix.perspective( m_fieldOfView, m_aspectRatio, m_nearPlane, m_farPlane );
+ m_viewProjectionMatrixDirty = true;
+ m_syncNeeded = true;
+ }
+
+ inline void updateOrthogonalProjection()
+ {
+ m_projectionMatrix.setToIdentity();
+ m_projectionMatrix.ortho( m_left, m_right, m_bottom, m_top, m_nearPlane, m_farPlane );
+ m_viewProjectionMatrixDirty = true;
+ m_syncNeeded = true;
+ }
+
+ Q_DECLARE_PUBLIC( Camera )
+
+ Camera *q_ptr;
+
+ QVector3D m_position;
+ QVector3D m_upVector;
+ QVector3D m_viewCenter;
+
+ QVector3D m_cameraToCenter; // The vector from the camera position to the view center
+
+ Camera::ProjectionType m_projectionType;
+
+ float m_nearPlane;
+ float m_farPlane;
+
+ float m_fieldOfView;
+ float m_aspectRatio;
+
+ float m_left;
+ float m_right;
+ float m_bottom;
+ float m_top;
+
+ mutable QMatrix4x4 m_viewMatrix;
+ mutable QMatrix4x4 m_projectionMatrix;
+ mutable QMatrix4x4 m_viewProjectionMatrix;
+
+ mutable bool m_viewMatrixDirty;
+ mutable bool m_viewProjectionMatrixDirty;
+ mutable bool m_syncNeeded;
+};
+
+}
+
+#endif // CAMERA_P_H
diff --git a/src/render/frontend/cameraselector.cpp b/src/render/frontend/cameraselector.cpp
new file mode 100644
index 000000000..091327646
--- /dev/null
+++ b/src/render/frontend/cameraselector.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "cameraselector.h"
+
+namespace Qt3D {
+
+CameraSelector::CameraSelector(Node *parent)
+ : Qt3D::Component(parent)
+ , m_camera(0)
+{
+}
+
+void CameraSelector::setCamera(Qt3D::Camera *camera)
+{
+ if (m_camera != camera) {
+ m_camera = camera;
+ emit cameraChanged();
+ }
+}
+
+Camera *CameraSelector::camera() const
+{
+ return m_camera;
+}
+
+} // namespace Qt3D
diff --git a/src/render/frontend/cameraselector.h b/src/render/frontend/cameraselector.h
new file mode 100644
index 000000000..9da27405c
--- /dev/null
+++ b/src/render/frontend/cameraselector.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_CAMERASELECTOR_H
+#define QT3D_CAMERASELECTOR_H
+
+#include <qt3dcore_global.h>
+#include <component.h>
+
+namespace Qt3D {
+
+class Camera;
+
+class CameraSelector : public Qt3D::Component
+{
+ Q_OBJECT
+
+ Q_PROPERTY(Qt3D::Camera *camera READ camera WRITE setCamera NOTIFY cameraChanged)
+
+public:
+ explicit CameraSelector(Node *parent = 0);
+
+ void setCamera(Qt3D::Camera *camera);
+ Camera *camera() const;
+
+signals:
+ void cameraChanged();
+
+private:
+ Camera *m_camera;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_CAMERASELECTOR_H
diff --git a/src/render/frontend/effect.cpp b/src/render/frontend/effect.cpp
new file mode 100644
index 000000000..e10932fa4
--- /dev/null
+++ b/src/render/frontend/effect.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "effect.h"
+#include "technique.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+
+Effect::Effect(Node *parent)
+ : Node(parent)
+{
+ qRegisterMetaType<Qt3D::Effect*>();
+ qDebug() << Q_FUNC_INFO;
+}
+
+
+QQmlListProperty<Qt3D::Technique> Effect::techniqueList()
+{
+ return QQmlListProperty<Qt3D::Technique>(this, m_techniques);
+}
+
+void Effect::addTechnique(Technique *t)
+{
+ Q_ASSERT(t);
+ t->setParent(this);
+ m_techniques.append(t);
+ emit techniquesChanged();
+}
+
+QList<Technique *> Effect::techniques() const
+{
+ return m_techniques;
+}
+
+void Effect::clearTechniques()
+{
+ qDeleteAll(m_techniques);
+ m_techniques.clear();
+}
+
+} // of namespace
diff --git a/src/render/frontend/effect.h b/src/render/frontend/effect.h
new file mode 100644
index 000000000..f1caf692e
--- /dev/null
+++ b/src/render/frontend/effect.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef EFFECT_H
+#define EFFECT_H
+
+#include <qt3dcore_global.h>
+#include <node.h>
+
+#include <QQmlListProperty>
+#include <QVector>
+
+namespace Qt3D {
+
+class Technique;
+
+class QT3DCORESHARED_EXPORT Effect : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQmlListProperty<Qt3D::Technique> techniques READ techniqueList NOTIFY techniquesChanged)
+
+public:
+ explicit Effect(Node *parent = 0);
+
+ QQmlListProperty<Qt3D::Technique> techniqueList();
+
+ void addTechnique(Technique *t);
+
+ QList<Technique *> techniques() const;
+
+ void clearTechniques();
+signals:
+ void techniquesChanged();
+
+private:
+ QList<Technique *> m_techniques;
+};
+
+}
+
+Q_DECLARE_METATYPE(Qt3D::Effect*)
+
+#endif // EFFECT_H
diff --git a/src/render/frontend/material.cpp b/src/render/frontend/material.cpp
new file mode 100644
index 000000000..16ba6e8fb
--- /dev/null
+++ b/src/render/frontend/material.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "material.h"
+
+#include <qchangearbiter.h>
+#include <texture.h>
+
+#include <QDebug>
+
+namespace Qt3D {
+
+Material::Material(Node *parent)
+ : Component(parent)
+{
+}
+
+Qt3D::Effect *Material::effect() const
+{
+ return m_effect;
+}
+
+void Material::setEffect(Qt3D::Effect *effect)
+{
+ if (effect == m_effect)
+ return;
+
+ m_effect = effect;
+ emit effectChanged();
+}
+
+void Material::setParameter(QString name, QVariant val)
+{
+ m_parameters[name] = val;
+
+ // schedule update to the backend
+ QScenePropertyChangePtr change(new QScenePropertyChange(MaterialParameter, this));
+ change->m_propertyName = name.toLocal8Bit();
+ change->m_value = val;
+ notifySceneChange(change);
+}
+
+QVariantMap Material::parameterValues() const
+{
+ return m_parameters;
+}
+
+Material::TextureDict Material::textureValues() const
+{
+ return m_textures;
+}
+
+void Material::setTextureParameter(QString name, Texture *tex)
+{
+ m_textures[name] = tex;
+}
+
+void Material::onTagValueChanged()
+{
+ Tag* t = qobject_cast<Tag*>(sender());
+ Q_ASSERT(m_tagList.contains(t));
+
+ QVariant v = t->value();
+ QmlTexture* qmlTex = v.value<QmlTexture*>();
+ if (qmlTex) {
+ qDebug() << "got texture parameter" << t->name();
+ setTextureParameter(t->name(), qmlTex->texture());
+ } else {
+ setParameter(t->name(), t->value());
+ }
+}
+
+QQmlListProperty<Tag> Material::qmlParameters()
+{
+ return QQmlListProperty<Tag>(this, 0,
+ &Material::appendTag,
+ &Material::tagCount,
+ &Material::tagAt,
+ &Material::clearTags );
+}
+
+void Material::appendTag(QQmlListProperty<Tag> *list, Tag *tag)
+{
+ Material *mat = qobject_cast<Material *>(list->object);
+ if (mat) {
+ tag->setParent(mat);
+ connect(tag, SIGNAL(valueChanged()), mat, SLOT(onTagValueChanged()));
+ mat->m_tagList.append(tag);
+ emit mat->parametersChanged();
+ }
+}
+
+Tag *Material::tagAt(QQmlListProperty<Tag> *list, int index)
+{
+ Material *mat = qobject_cast<Material *>(list->object);
+ if (mat)
+ return mat->m_tagList.value(index);
+ return 0;
+}
+
+int Material::tagCount(QQmlListProperty<Tag> *list)
+{
+ Material *mat = qobject_cast<Material *>(list->object);
+ if (mat)
+ return mat->m_tagList.size();
+ return 0;
+}
+
+void Material::clearTags(QQmlListProperty<Tag> *list)
+{
+ Material *mat = qobject_cast<Material *>(list->object);
+ if (mat) {
+ mat->m_parameters.clear();
+ mat->m_tagList.clear();
+ emit mat->parametersChanged();
+ }
+}
+
+} // of namespace
diff --git a/src/render/frontend/material.h b/src/render/frontend/material.h
new file mode 100644
index 000000000..b0dea466a
--- /dev/null
+++ b/src/render/frontend/material.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MATERIAL_H
+#define MATERIAL_H
+
+#include <QVariant>
+
+#include <component.h>
+
+// FIXME - write a custom QML parser and stop mis-using Tag
+#include "tag.h"
+
+#include <qt3dcore_global.h>
+
+namespace Qt3D {
+
+class Effect;
+class Texture;
+
+class QT3DCORESHARED_EXPORT Material : public Component
+{
+ Q_OBJECT
+ Q_PROPERTY(Qt3D::Effect* effect READ effect WRITE setEffect NOTIFY effectChanged)
+ Q_PROPERTY(QQmlListProperty<Qt3D::Tag> parameters READ qmlParameters)
+
+public:
+ explicit Material(Node *parent = 0);
+
+ Qt3D::Effect *effect() const;
+ void setEffect(Qt3D::Effect *effect);
+
+ void setParameter(QString name, QVariant val);
+
+ QVariantMap parameterValues() const;
+
+ typedef QMap<QString, Texture*> TextureDict;
+ TextureDict textureValues() const;
+
+ void setTextureParameter(QString name, Texture* tex);
+
+signals:
+ void effectChanged();
+ void parametersChanged();
+
+private slots:
+ void onTagValueChanged();
+
+private:
+ QQmlListProperty<Tag> qmlParameters();
+
+ // FIXME - remove when we have a custom QML parser
+ static void appendTag(QQmlListProperty<Tag> *list, Tag *bar);
+ static Tag *tagAt(QQmlListProperty<Tag> *list, int index);
+ static int tagCount(QQmlListProperty<Tag> *list);
+ static void clearTags(QQmlListProperty<Tag> *list);
+
+
+ Effect *m_effect;
+ QVariantMap m_parameters;
+
+ // FIXME - remove with tags
+ QList<Tag *> m_tagList;
+
+ TextureDict m_textures;
+};
+
+}
+
+#endif // MATERIAL_H
diff --git a/src/render/frontend/mesh.cpp b/src/render/frontend/mesh.cpp
new file mode 100644
index 000000000..27f8c513b
--- /dev/null
+++ b/src/render/frontend/mesh.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mesh.h"
+
+#include <qchangearbiter.h>
+
+#include <QDebug>
+#include <QFile>
+#include <QFileInfo>
+
+#include <objloader.h>
+
+namespace Qt3D {
+
+Mesh::Mesh(Node *parent)
+ : Component( parent )
+ , m_sourceDirty( false )
+{
+}
+
+Mesh::~Mesh()
+{
+}
+
+void Mesh::setSource( const QString& source )
+{
+ if ( source == m_source )
+ return;
+ m_source = source;
+ m_sourceDirty = true;
+
+ // FIXME - synchronous update
+ update();
+
+ // Let aspects know about the change
+ QScenePropertyChangePtr e(new QScenePropertyChange(Qt3D::MeshChange, this));
+ e->m_propertyName = QByteArrayLiteral("source");
+ e->m_value = m_source;
+ notifySceneChange(e);
+
+ emit sourceChanged();
+}
+
+QString Mesh::source() const
+{
+ return m_source;
+}
+
+MeshDataPtr Mesh::data() const
+{
+ return m_data;
+}
+
+void Mesh::setData(MeshDataPtr d)
+{
+ m_data = d;
+}
+
+void Mesh::update()
+{
+ if (m_sourceDirty) {
+ m_data = MeshDataPtr();
+ m_sourceDirty = false;
+
+ QFileInfo finfo(m_source);
+ if (!finfo.exists()) {
+ qWarning() << Q_FUNC_INFO << "not found:" << m_source;
+ return;
+ }
+
+ QFile f(m_source);
+ f.open(QIODevice::ReadOnly);
+
+ ObjLoader objLoad;
+ objLoad.setLoadTextureCoordinatesEnabled(true);
+
+ if (!objLoad.load(&f)) {
+ qWarning() << Q_FUNC_INFO << "OBJ load failure for:" << m_source;
+ return;
+ }
+
+ qDebug() << "Loaded OBJ ok";
+ setData(objLoad.mesh());
+ setObjectName("OBJ");
+ }
+
+ m_sourceDirty = false;
+}
+
+} // of namespace Qt3D
diff --git a/src/render/frontend/mesh.h b/src/render/frontend/mesh.h
new file mode 100644
index 000000000..766f38042
--- /dev/null
+++ b/src/render/frontend/mesh.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_MESH_H
+#define QT3D_MESH_H
+
+#include <component.h>
+
+#include <meshdata.h>
+
+namespace Qt3D {
+
+/**
+* @brief Simple static mesh
+*
+*/
+class Mesh : public Component
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString source READ source WRITE setSource NOTIFY sourceChanged)
+
+public:
+ Mesh(Node *parent = 0);
+ virtual ~Mesh();
+
+ void setSource(const QString &source);
+ QString source() const;
+
+ MeshDataPtr data() const;
+ void setData(MeshDataPtr d);
+signals:
+ void sourceChanged();
+
+private:
+ Q_INVOKABLE void update();
+
+ MeshDataPtr m_data;
+ QString m_source;
+ bool m_sourceDirty;
+};
+
+}
+
+#endif // of QT3D_MESH_H
diff --git a/src/render/frontend/qitemmodelbuffer.cpp b/src/render/frontend/qitemmodelbuffer.cpp
new file mode 100644
index 000000000..d13e389b4
--- /dev/null
+++ b/src/render/frontend/qitemmodelbuffer.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qitemmodelbuffer.h"
+
+#include <QDebug>
+#include <QColor>
+
+namespace Qt3D {
+
+void variantToBytes(void* dest, const QVariant& v, GLint type)
+{
+ int varType = v.type();
+ switch (type) {
+ case GL_FLOAT: {
+ float f = v.toFloat();
+ memcpy(dest, &f, sizeof(float));
+ return;
+ }
+
+ case GL_INT: {
+ GLint i = v.toInt();
+ memcpy(dest, &i, sizeof(GLint));
+ return;
+ }
+
+ case GL_UNSIGNED_INT: {
+ GLuint i = v.toUInt();
+ memcpy(dest, &i, sizeof(GLuint));
+ return;
+ }
+
+ case GL_FLOAT_VEC3:
+ if (varType == QVariant::Vector3D) {
+ QVector3D v3(v.value<QVector3D>());
+ memcpy(dest, &v3[0], sizeof(float) * 3);
+ return;
+ }
+
+ break;
+
+ case GL_FLOAT_VEC4:
+ if (varType == QVariant::Vector4D) {
+ QVector4D v4(v.value<QVector4D>());
+ memcpy(dest, &v4[0], sizeof(float) * 4);
+ return;
+ }
+
+ if (varType == QVariant::Color) {
+ QColor c = v.value<QColor>();
+ float* fptr = reinterpret_cast<float*>(dest);
+ *fptr++ = c.redF();
+ *fptr++ = c.greenF();
+ *fptr++ = c.blueF();
+ *fptr++ = c.alphaF();
+ return;
+ }
+
+ if (varType == QVariant::Quaternion) {
+ QVector4D qv = v.value<QQuaternion>().toVector4D();
+ memcpy(dest, &qv[0], sizeof(float) * 4);
+ return;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ qWarning() << Q_FUNC_INFO << "failed to convert" << v << "to GL type" <<
+ QString::number(type, 16);
+}
+
+QItemModelBuffer::QItemModelBuffer()
+{
+}
+
+void QItemModelBuffer::setModel(QAbstractItemModel *model)
+{
+ if (model == m_model)
+ return;
+
+ m_model = model;
+ m_buffer.clear();
+
+ connect(m_model, SIGNAL(modelReset()), this, SLOT(onModelReset()));
+ connect(m_model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(onModelDataChanged(QModelIndex,QModelIndex)));
+}
+
+void QItemModelBuffer::setRoot(const QModelIndex &rootIndex)
+{
+ m_rootIndex = rootIndex;
+ m_buffer.clear();
+}
+
+void QItemModelBuffer::mapRoleName(QByteArray roleName, int elementType)
+{
+ mapRoleName(roleName, roleName, elementType);
+}
+
+void QItemModelBuffer::mapRoleName(QByteArray roleName, QString attributeName, int elementType)
+{
+ if (m_model) {
+ if (!m_model->roleNames().values().contains(roleName)) {
+ qWarning() << Q_FUNC_INFO << "unknown role name" << roleName;
+ }
+ }
+
+ m_mappings.append(RoleMapping(roleName, attributeName, elementType));
+ m_buffer.clear();
+}
+
+BufferPtr QItemModelBuffer::buffer()
+{
+ if (!m_buffer) {
+ if (!validateRoles())
+ return m_buffer;
+
+ m_attributes.clear();
+ m_itemStride = 0;
+
+ m_buffer.reset(new Buffer(QOpenGLBuffer::VertexBuffer));
+ // assume model will change
+ m_buffer->setUsage(QOpenGLBuffer::DynamicDraw);
+
+ int rowCount = m_model->rowCount(m_rootIndex);
+ int offset = 0;
+ int mappingCount = m_mappings.count();
+ for (int m=0; m<mappingCount; ++m)
+ m_itemStride += m_mappings.at(m).byteSize;
+
+ for (int m=0; m<mappingCount; ++m) {
+ const RoleMapping mapping(m_mappings.at(m));
+ AttributePtr attr(new Attribute(m_buffer, mapping.type,
+ rowCount,
+ offset, m_itemStride));
+ m_attributes[mapping.attribute] = attr;
+ offset += byteSizeFromType(mapping.type);
+ } // of mappings iteration
+
+ m_buffer->setData(computeBufferData());
+ }
+
+ return m_buffer;
+}
+
+QStringList QItemModelBuffer::attributeNames() const
+{
+ return m_attributes.keys();
+}
+
+AttributePtr QItemModelBuffer::attributeByName(QString nm) const
+{
+ return m_attributes.value(nm);
+}
+
+void QItemModelBuffer::onModelDataChanged(const QModelIndex& topLeft,
+ const QModelIndex& bottomRight)
+{
+ if (!m_buffer)
+ return;
+
+ if (topLeft.parent() != m_rootIndex)
+ return;
+
+ QByteArray newBytes = m_buffer->data();
+ for (int row=topLeft.row(); row<=bottomRight.row(); ++row) {
+ QModelIndex index = topLeft.sibling(row, topLeft.column());
+
+ char* itemPtr = newBytes.data();
+ itemPtr += m_itemStride * row;
+
+ writeDataForIndex(index, m_mappings.count(), itemPtr);
+ } // of rows changed iteration
+
+ m_buffer->setData(newBytes);
+}
+
+void QItemModelBuffer::onModelReset()
+{
+ if (!m_buffer)
+ return;
+
+ QByteArray b = computeBufferData();
+ m_buffer->setData(b);
+}
+
+QByteArray QItemModelBuffer::computeBufferData()
+{
+ int rowCount = m_model->rowCount(m_rootIndex);
+
+ int mappingCount = m_mappings.count();
+ QByteArray newData;
+ newData.resize(m_itemStride * rowCount);
+ char* bufferPtr = newData.data();
+
+ for (int row=0; row<rowCount; ++row) {
+ writeDataForIndex(m_model->index(row, 0, m_rootIndex), mappingCount, bufferPtr);
+ bufferPtr += m_itemStride;
+ } // of rows iteration
+
+ return newData;
+}
+
+void QItemModelBuffer::writeDataForIndex(const QModelIndex& index, int mappingCount, char* bufferPtr)
+{
+ char* fieldPtr = bufferPtr;
+ for (int m=0; m<mappingCount; ++m) {
+ const RoleMapping& mapping(m_mappings.at(m));
+ QVariant v = m_model->data(index, mapping.cachedRole);
+ variantToBytes(fieldPtr, v, mapping.type);
+
+ fieldPtr += mapping.byteSize;
+ } // of mappings iteration
+}
+
+bool QItemModelBuffer::validateRoles()
+{
+ Q_ASSERT(m_model);
+
+ QHash<int, QByteArray> roles(m_model->roleNames());
+ // create a lookup that's the the way round we need
+ QHash<QByteArray, int> inverseRoles;
+ foreach (int r, roles.keys())
+ inverseRoles[roles.value(r)] = r;
+
+ for (int m=0; m<m_mappings.count(); ++m) {
+ QByteArray rnm(m_mappings.at(m).roleName);
+ if (!inverseRoles.contains(rnm)) {
+ qWarning() << "unknown role:" << rnm;
+ return false;
+ }
+
+ m_mappings[m].cachedRole = inverseRoles[rnm];
+ } // of mappings iteration
+
+ return true;
+}
+
+QItemModelBuffer::RoleMapping::RoleMapping(QByteArray rnm, QString nm, int ty) :
+ roleName(rnm),
+ cachedRole(-1),
+ attribute(nm),
+ type(ty)
+{
+ byteSize = byteSizeFromType(ty);
+}
+
+} // namespace Qt3D
diff --git a/src/render/frontend/qitemmodelbuffer.h b/src/render/frontend/qitemmodelbuffer.h
new file mode 100644
index 000000000..c567ab545
--- /dev/null
+++ b/src/render/frontend/qitemmodelbuffer.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_QITEMMODELBUFFER_H
+#define QT3D_QITEMMODELBUFFER_H
+
+#include <QAbstractItemModel>
+#include <QMap>
+#include <QObject>
+
+#include <meshdata.h>
+
+namespace Qt3D {
+
+class QItemModelBuffer : public QObject
+{
+ Q_OBJECT
+public:
+ QItemModelBuffer();
+
+ void setModel(QAbstractItemModel* model);
+ void setRoot(const QModelIndex& rootIndex);
+
+ void mapRoleName(QByteArray roleName, int type);
+ void mapRoleName(QByteArray roleName, QString attributeName, int type);
+
+ BufferPtr buffer();
+
+ QStringList attributeNames() const;
+ AttributePtr attributeByName(QString nm) const;
+
+private slots:
+
+ void onModelReset();
+
+ void onModelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+private:
+ QAbstractItemModel* m_model;
+ QModelIndex m_rootIndex;
+
+ struct RoleMapping {
+ RoleMapping(QByteArray role, QString attr, int ty);
+
+ QByteArray roleName;
+ int cachedRole;
+ QString attribute;
+ int type;
+ int byteSize;
+ };
+
+ QList<RoleMapping> m_mappings;
+
+ BufferPtr m_buffer;
+ QMap<QString, AttributePtr> m_attributes;
+ int m_itemStride;
+
+ QByteArray computeBufferData();
+
+ void writeDataForIndex(const QModelIndex &index, int mappingCount, char *bufferPtr);
+ bool validateRoles();
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_QITEMMODELBUFFER_H
diff --git a/src/render/frontend/render-frontend.pri b/src/render/frontend/render-frontend.pri
new file mode 100644
index 000000000..84930815e
--- /dev/null
+++ b/src/render/frontend/render-frontend.pri
@@ -0,0 +1,37 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/camera.h \
+ $$PWD/camera_p.h \
+ $$PWD/effect.h \
+ $$PWD/material.h \
+ $$PWD/mesh.h \
+ $$PWD/renderpass.h \
+ $$PWD/renderpassfilter.h \
+ $$PWD/shaderprogram.h \
+ $$PWD/technique.h \
+ $$PWD/viewport.h \
+ $$PWD/cameraselector.h \
+ $$PWD/techniquefilter.h \
+ $$PWD/tag.h \
+ $$PWD//shape.h \
+ $$PWD//transform.h \
+ $$PWD//qitemmodelbuffer.h \
+ $$PWD//texture.h
+
+SOURCES += \
+ $$PWD/camera.cpp \
+ $$PWD/effect.cpp \
+ $$PWD/material.cpp \
+ $$PWD/mesh.cpp \
+ $$PWD/renderpass.cpp \
+ $$PWD/renderpassfilter.cpp \
+ $$PWD/shaderprogram.cpp \
+ $$PWD/technique.cpp \
+ $$PWD/viewport.cpp \
+ $$PWD/cameraselector.cpp \
+ $$PWD/techniquefilter.cpp \
+ $$PWD/shape.cpp \
+ $$PWD/transform.cpp \
+ $$PWD/qitemmodelbuffer.cpp \
+ $$PWD/texture.cpp
diff --git a/src/render/frontend/renderpass.cpp b/src/render/frontend/renderpass.cpp
new file mode 100644
index 000000000..59c083fce
--- /dev/null
+++ b/src/render/frontend/renderpass.cpp
@@ -0,0 +1,120 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderpass.h"
+#include "technique.h"
+
+#include <QDebug>
+
+namespace Qt3D {
+
+RenderPass::RenderPass(Node *parent)
+ : Node(parent)
+ , m_name()
+ , m_shaderProgram(0)
+ , m_stateSet(0)
+{
+}
+
+void RenderPass::setName(const QString &name)
+{
+ if (name != m_name) {
+ m_name = name;
+ emit nameChanged();
+ }
+}
+
+QString RenderPass::name() const
+{
+ return m_name;
+}
+
+void RenderPass::setShaderProgram(Qt3D::ShaderProgram *shaderProgram)
+{
+ if (shaderProgram != m_shaderProgram) {
+ m_shaderProgram = shaderProgram;
+ emit shaderProgramChanged();
+ }
+}
+
+Qt3D::ShaderProgram *RenderPass::shaderProgram() const
+{
+ return m_shaderProgram;
+}
+
+void RenderPass::addUniformBinding(Parameter *param, QString glslUniformName)
+{
+ m_uniforms.append(param);
+ m_parameterNameDict[param->name()] = glslUniformName;
+}
+
+void RenderPass::addAttributeBinding(Parameter *param, QString glslAttributeName)
+{
+ m_attributes.append(param);
+ m_parameterNameDict[param->name()] = glslAttributeName;
+}
+
+QString RenderPass::glslNameForParameter(QString paramName) const
+{
+ return m_parameterNameDict.value(paramName);
+}
+
+ParameterList RenderPass::attributes() const
+{
+ return m_attributes;
+}
+
+ParameterList RenderPass::uniforms() const
+{
+ return m_uniforms;
+}
+
+void RenderPass::setStateSet(DrawStateSet *ss)
+{
+ m_stateSet = ss;
+}
+
+DrawStateSet *RenderPass::stateSet() const
+{
+ return m_stateSet;
+}
+
+} // of namespace Qt3D
diff --git a/src/render/frontend/renderpass.h b/src/render/frontend/renderpass.h
new file mode 100644
index 000000000..ad2fb0088
--- /dev/null
+++ b/src/render/frontend/renderpass.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERPASS_H
+#define RENDERPASS_H
+
+#include <node.h>
+#include <qt3dcore_global.h>
+
+#include "shaderprogram.h"
+#include <drawstate.h>
+
+#include <QHash>
+
+namespace Qt3D {
+
+class Parameter;
+typedef QList<Parameter*> ParameterList;
+
+class QT3DCORESHARED_EXPORT RenderPass : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(Qt3D::ShaderProgram * shaderProgram READ shaderProgram WRITE setShaderProgram NOTIFY shaderProgramChanged)
+
+public:
+ explicit RenderPass(Node *parent = 0);
+
+ void setName(const QString &name);
+ QString name() const;
+
+ void setShaderProgram(Qt3D::ShaderProgram* shaderProgram);
+ Qt3D::ShaderProgram* shaderProgram() const;
+
+ void addUniformBinding(Parameter* param, QString glslUniformName);
+
+ void addAttributeBinding(Parameter* param, QString glslAttributeName);
+
+ QString glslNameForParameter(QString paramName) const;
+
+ ParameterList attributes() const;
+ ParameterList uniforms() const;
+
+ void setStateSet(DrawStateSet* ss);
+ DrawStateSet* stateSet() const;
+
+signals:
+ void nameChanged();
+ void shaderProgramChanged();
+
+protected:
+ QString m_name;
+ ShaderProgram* m_shaderProgram;
+ ParameterList m_attributes;
+ ParameterList m_uniforms;
+
+ // map Parameter names to GLSL names
+ QHash<QString, QString> m_parameterNameDict;
+
+ DrawStateSet* m_stateSet;
+};
+
+}
+
+#endif // RENDERPASS_H
diff --git a/src/render/frontend/renderpassfilter.cpp b/src/render/frontend/renderpassfilter.cpp
new file mode 100644
index 000000000..8b25fe239
--- /dev/null
+++ b/src/render/frontend/renderpassfilter.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "renderpassfilter.h"
+
+namespace Qt3D {
+
+RenderPassFilter::RenderPassFilter(Node *parent)
+ : Component(parent)
+{
+}
+
+void RenderPassFilter::setRenderPassNames(const QString &renderpassNames)
+{
+ if (m_renderPassNames != renderpassNames) {
+ m_renderPassNames = renderpassNames;
+ emit renderPassNamesChanged();
+ }
+}
+
+QString RenderPassFilter::renderPassNames() const
+{
+ return m_renderPassNames;
+}
+
+}
diff --git a/src/render/frontend/renderpassfilter.h b/src/render/frontend/renderpassfilter.h
new file mode 100644
index 000000000..cd9f81e88
--- /dev/null
+++ b/src/render/frontend/renderpassfilter.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDERPASSFILTER_H
+#define RENDERPASSFILTER_H
+
+#include <qt3dcore_global.h>
+#include <component.h>
+
+#include <QString>
+
+namespace Qt3D {
+
+class QT3DCORESHARED_EXPORT RenderPassFilter : public Component
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString renderPassNames READ renderPassNames WRITE setRenderPassNames NOTIFY renderPassNamesChanged)
+
+public:
+ explicit RenderPassFilter(Node *parent = 0);
+
+ void setRenderPassNames(const QString &renderpassNames);
+ QString renderPassNames() const;
+
+signals:
+ void renderPassNamesChanged();
+
+private:
+ QString m_renderPassNames;
+};
+
+} // namespace Qt3D
+
+#endif // RENDERPASSFILTER_H
diff --git a/src/render/frontend/shaderprogram.cpp b/src/render/frontend/shaderprogram.cpp
new file mode 100644
index 000000000..e0ef62d2a
--- /dev/null
+++ b/src/render/frontend/shaderprogram.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "shaderprogram.h"
+
+#include <QDebug>
+#include <QFile>
+
+namespace Qt3D {
+
+ShaderProgram::ShaderProgram(Node *parent)
+ : Node(parent)
+ , m_vertexSourceFile()
+ , m_fragmentSourceFile()
+ , m_isLoaded(false)
+{
+}
+
+void ShaderProgram::setVertexSourceFile(const QString& vertexSourceFile)
+{
+ if (vertexSourceFile != m_vertexSourceFile) {
+ m_vertexSourceFile = vertexSourceFile;
+ m_isLoaded = false;
+ emit vertexSourceFileChanged();
+ }
+}
+
+QString ShaderProgram::vertexSourceFile() const
+{
+ return m_vertexSourceFile;
+}
+
+void ShaderProgram::setFragmentSourceFile(const QString& fragmentSourceFile)
+{
+ if (fragmentSourceFile != m_fragmentSourceFile) {
+ m_fragmentSourceFile = fragmentSourceFile;
+ m_isLoaded = false;
+ emit fragmentSourceFileChanged();
+ }
+}
+
+QString ShaderProgram::fragmentSourceFile() const
+{
+ return m_fragmentSourceFile;
+}
+
+QByteArray ShaderProgram::vertexSourceCode() const
+{
+ if (!isLoaded())
+ return QByteArray();
+
+ return m_cachedVertexCode;
+}
+
+QByteArray ShaderProgram::fragmentSourceCode() const
+{
+ if (!isLoaded())
+ return QByteArray();
+
+ return m_cachedFragmentCode;
+}
+
+bool ShaderProgram::isLoaded() const
+{
+ return m_isLoaded;
+}
+
+void ShaderProgram::load()
+{
+ if (m_isLoaded)
+ return;
+
+ m_isLoaded = true;
+
+ QFile f(m_fragmentSourceFile);
+ if (!f.exists()) {
+ qWarning() << "couldn't find shader source file:" << m_fragmentSourceFile;
+ return;
+ } else {
+ f.open(QIODevice::ReadOnly);
+ m_cachedFragmentCode = f.readAll();
+ }
+
+ QFile vs(m_vertexSourceFile);
+ if (!vs.exists()) {
+ qWarning() << "couldn't find shader source file:" << m_vertexSourceFile;
+ return;
+ } else {
+ vs.open(QIODevice::ReadOnly);
+ m_cachedVertexCode = vs.readAll();
+ }
+}
+
+} // of namespace Qt3D
+
diff --git a/src/render/frontend/shaderprogram.h b/src/render/frontend/shaderprogram.h
new file mode 100644
index 000000000..3b49fe651
--- /dev/null
+++ b/src/render/frontend/shaderprogram.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SHADERPROGRAM_H
+#define SHADERPROGRAM_H
+
+#include <node.h>
+
+namespace Qt3D {
+
+class ShaderProgram : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString vertexSourceFile READ vertexSourceFile WRITE setVertexSourceFile NOTIFY vertexSourceFileChanged)
+ Q_PROPERTY(QString fragmentSourceFile READ fragmentSourceFile WRITE setFragmentSourceFile NOTIFY fragmentSourceFileChanged)
+
+public:
+ explicit ShaderProgram(Node *parent = 0);
+
+ void setVertexSourceFile(const QString &vertexSourceFile);
+ QString vertexSourceFile() const;
+
+ void setFragmentSourceFile(const QString &fragmentSource);
+ QString fragmentSourceFile() const;
+
+ QByteArray vertexSourceCode() const;
+ QByteArray fragmentSourceCode() const;
+
+ bool isLoaded() const;
+
+ /**
+ * @brief load - call from main / worker thread to do synchronous
+ * loading of shader source files
+ */
+ void load();
+
+signals:
+ void vertexSourceFileChanged();
+ void fragmentSourceFileChanged();
+
+private:
+ QString m_vertexSourceFile;
+ QString m_fragmentSourceFile;
+
+ bool m_sourcesDirty, m_isLoaded;
+ QByteArray m_cachedVertexCode,
+ m_cachedFragmentCode;
+
+};
+
+}
+
+#endif // SHADERPROGRAM_H
diff --git a/src/render/frontend/shape.cpp b/src/render/frontend/shape.cpp
new file mode 100644
index 000000000..5e9fa3c0f
--- /dev/null
+++ b/src/render/frontend/shape.cpp
@@ -0,0 +1,386 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define _USE_MATH_DEFINES // For MSVC
+#include "shape.h"
+
+#include <cmath>
+
+#include <QDebug>
+
+namespace Qt3D {
+
+namespace {
+
+MeshDataPtr createSphereMesh(double radius, int rings, int slices, bool hasTangents)
+{
+ MeshDataPtr mesh(new MeshData(GL_TRIANGLES));
+
+ int nVerts = ( slices + 1 ) * ( rings + 1 ); // One extra line of latitude
+ QByteArray bufferBytes;
+ // vec3 pos, vec2 texCoord, vec3 normal, vec4 tangent
+ quint32 elementSize = 3 + 2 + 3 + (hasTangents ? 4 : 0);
+ quint32 stride = elementSize * sizeof(float);
+ 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 = cosf( phi );
+ const float sinPhi = sinf( 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 = cosf( theta );
+ const float sinTheta = sinf( 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;
+
+ if (hasTangents) {
+ *fptr++ = sinTheta;
+ *fptr++ = 0.0;
+ *fptr++ = -cosTheta;
+ *fptr++ = 1.0;
+ }
+ }
+ }
+
+ BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer));
+ buf->setUsage(QOpenGLBuffer::StaticDraw);
+ buf->setData(bufferBytes);
+
+ mesh->addAttribute("position", new Attribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride));
+ quint32 offset = sizeof(float) * 3;
+
+ mesh->addAttribute("texcoord", new Attribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride));
+ offset += sizeof(float) * 2;
+
+ mesh->addAttribute("normal", new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride));
+ offset += sizeof(float) * 3;
+
+ if (hasTangents) {
+ mesh->addAttribute("tangent", new Attribute(buf, GL_FLOAT_VEC4, nVerts, offset, stride));
+ offset += sizeof(float) * 4;
+ }
+
+ int faces = (slices * 2) * (rings - 1); // two tris per slice, for all middle rings
+ faces += 2 * slices; // tri per slice for both top and bottom
+
+ QByteArray indexBytes;
+ 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;
+ }
+ }
+
+ BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer));
+ indexBuffer->setUsage(QOpenGLBuffer::StaticDraw);
+ indexBuffer->setData(indexBytes);
+ mesh->setIndexAttr(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)));
+
+ mesh->computeBoundsFromAttribute("position");
+ qDebug() << "computed sphere bounds is:" << mesh->boundingBox();
+
+ return mesh;
+}
+
+
+MeshDataPtr createTorusMesh(double radius, double minorRadius,
+ int rings, int sides)
+{
+ MeshDataPtr mesh(new MeshData(GL_TRIANGLES));
+
+ int nVerts = ( sides + 1 ) * ( rings + 1 );
+ QByteArray bufferBytes;
+ // vec3 pos, vec2 texCoord, vec3 normal
+ quint32 elementSize = 3 + 2 + 3;
+ quint32 stride = elementSize * sizeof(float);
+ bufferBytes.resize(stride * nVerts);
+
+ float* fptr = reinterpret_cast<float*>(bufferBytes.data());
+
+ float ringFactor = (M_PI * 2) / static_cast<float>( rings );
+ float sideFactor = (M_PI * 2) / static_cast<float>( sides );
+
+ for ( int ring = 0; ring <= rings; ring++ )
+ {
+ float u = ring * ringFactor;
+ float cu = cos( u );
+ float su = sin( u );
+
+ for ( int side = 0; side < sides; side++ )
+ {
+ float v = side * sideFactor;
+ float cv = cos( v );
+ float sv = sin( v );
+ 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();
+ }
+ }
+
+ BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer));
+ buf->setUsage(QOpenGLBuffer::StaticDraw);
+ buf->setData(bufferBytes);
+
+ mesh->addAttribute("position", new Attribute(buf, GL_FLOAT_VEC3, nVerts, 0, stride));
+ quint32 offset = sizeof(float) * 3;
+
+ mesh->addAttribute("texcoord", new Attribute(buf, GL_FLOAT_VEC2, nVerts, offset, stride));
+ offset += sizeof(float) * 2;
+
+ mesh->addAttribute("normal", new Attribute(buf, GL_FLOAT_VEC3, nVerts, offset, stride));
+ offset += sizeof(float) * 3;
+
+ 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++ )
+ {
+ int ringStart = ring * sides;
+ int nextRingStart = ( ring + 1 ) * sides;
+ for ( int side = 0; side < sides; side++ )
+ {
+ int nextSide = ( side + 1 ) % sides;
+ *indexPtr++ = ( ringStart + side );
+ *indexPtr++ = ( nextRingStart + side );
+ *indexPtr++ = ( nextRingStart + nextSide );
+ *indexPtr++ = ringStart + side;
+ *indexPtr++ = nextRingStart + nextSide;
+ *indexPtr++ = ( ringStart + nextSide );
+ }
+ }
+
+ BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer));
+ indexBuffer->setUsage(QOpenGLBuffer::StaticDraw);
+ indexBuffer->setData(indexBytes);
+ mesh->setIndexAttr(AttributePtr(new Attribute(indexBuffer, GL_UNSIGNED_SHORT, indices, 0, 0)));
+
+ mesh->computeBoundsFromAttribute("position");
+
+ return mesh;
+}
+
+} // anonymous namespace
+
+Shape::Shape(Node *parent) :
+ Qt3D::Component(parent),
+ m_generateTangents(false),
+ m_type(ShapeSphere),
+ m_rings(16),
+ m_slices(16),
+ m_radius(1.0),
+ m_minorRadius(1.0)
+{
+}
+
+Shape::ShapeType Shape::type() const
+{
+ return m_type;
+}
+
+MeshDataPtr Shape::data() const
+{
+ if (m_type == ShapeTorus)
+ return createTorusMesh(m_radius, m_minorRadius, m_rings, m_slices);
+
+ return createSphereMesh(m_radius, m_rings, m_slices, m_generateTangents);
+}
+
+int Shape::rings() const
+{
+ return m_rings;
+}
+
+int Shape::slices() const
+{
+ return m_slices;
+}
+
+bool Shape::generateTangents() const
+{
+ return m_generateTangents;
+}
+
+double Shape::radius() const
+{
+ return m_radius;
+}
+
+double Shape::minorRadius() const
+{
+ return m_minorRadius;
+}
+
+void Shape::setType(Shape::ShapeType arg)
+{
+ if (m_type != arg) {
+ m_type = arg;
+ m_rebuildMesh = true;
+ emit typeChanged(arg);
+ }
+}
+
+void Shape::setRings(int arg)
+{
+ if (m_rings == arg)
+ return;
+
+ m_rings = arg;
+ m_rebuildMesh = true;
+ emit shapeChanged();
+}
+
+void Shape::setSlices(int arg)
+{
+ if (m_slices == arg)
+ return;
+
+ m_slices = arg;
+ m_rebuildMesh = true;
+ emit shapeChanged();
+}
+
+void Shape::setGenerateTangents(bool gen)
+{
+ if (m_generateTangents == gen)
+ return;
+
+ m_generateTangents = gen;
+ m_rebuildMesh = true;
+ emit shapeChanged();
+}
+
+void Shape::setRadius(double arg)
+{
+ if (m_radius != arg) {
+ m_radius = arg;
+ m_rebuildMesh = true;
+ emit shapeChanged();
+ }
+}
+
+void Shape::setMinorRadius(double arg)
+{
+ if (m_minorRadius != arg) {
+ m_minorRadius = arg;
+ m_rebuildMesh = true;
+ emit shapeChanged();
+ }
+}
+
+} // namespace Qt3D
diff --git a/src/render/frontend/shape.h b/src/render/frontend/shape.h
new file mode 100644
index 000000000..4207720b5
--- /dev/null
+++ b/src/render/frontend/shape.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_SHAPE_H
+#define QT3D_SHAPE_H
+
+#include <component.h>
+
+#include <meshdata.h>
+
+namespace Qt3D {
+
+class Shape : public Qt3D::Component
+{
+ Q_OBJECT
+
+ Q_ENUMS(ShapeType)
+
+ Q_PROPERTY(ShapeType type READ type WRITE setType NOTIFY typeChanged)
+
+ Q_PROPERTY(bool generateTangents READ generateTangents
+ WRITE setGenerateTangents
+ NOTIFY shapeChanged)
+
+ Q_PROPERTY(int rings READ rings WRITE setRings NOTIFY shapeChanged)
+ Q_PROPERTY(int slices READ slices WRITE setSlices NOTIFY shapeChanged)
+
+ Q_PROPERTY(double radius READ radius WRITE setRadius NOTIFY shapeChanged)
+ Q_PROPERTY(double minorRadius READ minorRadius WRITE setMinorRadius NOTIFY shapeChanged)
+
+public:
+ explicit Shape(Node *parent = 0);
+
+ enum ShapeType
+ {
+ ShapeCube,
+ ShapeSphere,
+ ShapeCylinder,
+ ShapeTorus
+ };
+
+ ShapeType type() const;
+
+ MeshDataPtr data() const;
+
+ int rings() const;
+ int slices() const;
+ bool generateTangents() const;
+ double radius() const;
+ double minorRadius() const;
+
+signals:
+
+ void typeChanged(ShapeType arg);
+ void shapeChanged();
+
+public slots:
+
+ void setType(ShapeType arg);
+ void setRings(int arg);
+ void setSlices(int arg);
+
+ void setGenerateTangents(bool gen);
+
+ void setRadius(double arg);
+ void setMinorRadius(double arg);
+
+private:
+ bool m_rebuildMesh,
+ m_generateTangents;
+ ShapeType m_type;
+ int m_rings,
+ m_slices;
+ double m_radius;
+ double m_minorRadius;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_SHAPE_H
diff --git a/src/render/frontend/tag.h b/src/render/frontend/tag.h
new file mode 100644
index 000000000..7dc4b7dc4
--- /dev/null
+++ b/src/render/frontend/tag.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TAG_H
+#define TAG_H
+
+#include <QDebug>
+
+#include <qt3dcore_global.h>
+#include <node.h>
+
+namespace Qt3D {
+
+class QT3DCORESHARED_EXPORT Tag : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+ Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged)
+
+public:
+ Tag(Node *parent = 0)
+ : Node(parent)
+ , m_name()
+ , m_value()
+ {}
+
+ void setName( const QString& name )
+ {
+ if (name != m_name) {
+ m_name = name;
+ emit nameChanged();
+ }
+ }
+
+ QString name() const { return m_name; }
+
+ void setValue( const QVariant& value )
+ {
+ if (value != m_value) {
+ m_value = value;
+ emit valueChanged();
+ }
+ }
+
+ QVariant value() const { return m_value; }
+
+signals:
+ void nameChanged();
+ void valueChanged();
+
+private:
+ QString m_name;
+ QVariant m_value;
+};
+
+} // namespace Qt3D
+
+#endif // TAG_H
diff --git a/src/render/frontend/technique.cpp b/src/render/frontend/technique.cpp
new file mode 100644
index 000000000..5779e8f10
--- /dev/null
+++ b/src/render/frontend/technique.cpp
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "technique.h"
+
+#include <QDebug>
+#include <QOpenGLContext>
+
+namespace Qt3D {
+
+Technique::Technique(Node *parent)
+ : Node(parent)
+{
+}
+
+QQmlListProperty<Qt3D::Tag> Technique::tags()
+{
+ return QQmlListProperty<Qt3D::Tag>(this, 0,
+ &Technique::appendTag,
+ &Technique::tagCount,
+ &Technique::tagAt,
+ &Technique::clearTags );
+}
+
+void Technique::addTag(const QString &name, const QVariant &value)
+{
+ Tag *tag = new Tag(this);
+ tag->setName(name);
+ tag->setValue(value);
+ m_tags.insert(name, tag);
+ m_tagList.append(tag);
+ emit tagsChanged();
+}
+
+void Technique::removeTag(const QString &name)
+{
+ Tag *tag = m_tags.value(name);
+ m_tags.remove(name);
+ m_tagList.removeOne(tag);
+ if (tag) {
+ delete tag;
+ emit tagsChanged();
+ }
+}
+
+void Technique::setTagValue(const QString &name, const QVariant &value)
+{
+ Tag *tag = m_tags.value(name);
+ if (tag)
+ tag->setValue(value);
+}
+
+QVariant Technique::tagValue(const QString &name) const
+{
+ return m_tags.value(name)->value();
+}
+
+bool Technique::containsTag(const QString &name) const
+{
+ return m_tags.contains(name);
+}
+
+void Technique::addPass(RenderPass *pass)
+{
+ Q_ASSERT(pass);
+ pass->setParent(this);
+ m_renderPasses.append(pass);
+ emit renderPassesChanged();
+}
+
+QList<RenderPass *> Technique::renderPasses() const
+{
+ return m_renderPasses;
+}
+
+void Technique::appendTag(QQmlListProperty<Tag> *list, Tag *tag)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique) {
+ tag->setParent(technique);
+ technique->m_tags.insert(tag->name(), tag);
+ technique->m_tagList.append(tag);
+ emit technique->tagsChanged();
+ }
+}
+
+Tag *Technique::tagAt(QQmlListProperty<Tag> *list, int index)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique)
+ return technique->m_tagList.value(index);
+ return 0;
+}
+
+int Technique::tagCount(QQmlListProperty<Tag> *list)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique)
+ return technique->m_tagList.size();
+ return 0;
+}
+
+void Technique::clearTags(QQmlListProperty<Tag> *list)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique) {
+ technique->m_tags.clear();
+ technique->m_tagList.clear();
+ emit technique->tagsChanged();
+ }
+}
+
+QQmlListProperty<Qt3D::RenderPass> Technique::renderPassList()
+{
+ return QQmlListProperty<Qt3D::RenderPass>(this, 0,
+ &Technique::appendRenderPass,
+ &Technique::renderPassCount,
+ &Technique::renderPassAt,
+ &Technique::clearRenderPasses);
+}
+
+void Technique::addParameter(Parameter *p)
+{
+ Q_CHECK_PTR(p);
+ m_parameters.append(p);
+}
+
+Parameter *Technique::parameterByName(QString name) const
+{
+ foreach (Parameter* p, m_parameters) {
+ if (p->name() == name)
+ return p;
+ }
+
+ return NULL;
+}
+
+void Technique::appendRenderPass(QQmlListProperty<RenderPass> *list, RenderPass *renderPass)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique) {
+ technique->addPass(renderPass);
+ }
+}
+
+RenderPass *Technique::renderPassAt(QQmlListProperty<RenderPass> *list, int index)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique)
+ return technique->m_renderPasses.value(index);
+ return 0;
+}
+
+int Technique::renderPassCount(QQmlListProperty<RenderPass> *list)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique)
+ return technique->m_renderPasses.size();
+ return 0;
+}
+
+void Technique::clearRenderPasses(QQmlListProperty<RenderPass> *list)
+{
+ Technique *technique = qobject_cast<Technique *>(list->object);
+ if (technique) {
+ technique->m_renderPasses.clear();
+ emit technique->renderPassesChanged();
+ }
+}
+
+Parameter::Parameter(QObject *parent, QString name, int ty) :
+ QObject(parent),
+ m_name(name),
+ m_type(ty),
+ m_standardUniform(None)
+{
+
+}
+
+void Parameter::setMeshAttributeName(QString name)
+{
+ m_meshName = name;
+}
+
+bool Parameter::isStandardUniform() const
+{
+ return (m_standardUniform != None);
+}
+
+void Parameter::setStandardUniform(Parameter::StandardUniform su)
+{
+ m_standardUniform = su;
+}
+
+Parameter::StandardUniform Parameter::standardUniform() const
+{
+ return m_standardUniform;
+}
+
+bool Parameter::isTextureType() const
+{
+ switch (m_type) {
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ return true;
+ default:
+ return false;
+ }
+}
+
+Render::QUniformValue::Type Parameter::uniformType() const
+{
+ switch (m_type) {
+ case GL_BOOL:
+ case GL_BOOL_VEC2:
+ case GL_BOOL_VEC3:
+ case GL_BOOL_VEC4:
+ return Render::QUniformValue::Bool;
+
+ // integers!
+
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ case GL_FLOAT_MAT4:
+ return Render::QUniformValue::Float;
+
+ case GL_DOUBLE:
+ case GL_DOUBLE_VEC2:
+ case GL_DOUBLE_VEC3:
+ case GL_DOUBLE_VEC4:
+ return Render::QUniformValue::Double;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "couldn't map datatype:" << QString::number(m_type, 16);
+ return Render::QUniformValue::Invalid;
+ }
+}
+
+} // of namespace Qt3D
diff --git a/src/render/frontend/technique.h b/src/render/frontend/technique.h
new file mode 100644
index 000000000..f4050eb3e
--- /dev/null
+++ b/src/render/frontend/technique.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TECHNIQUE_H
+#define TECHNIQUE_H
+
+#include <qt3dcore_global.h>
+#include <node.h>
+
+#include "tag.h"
+#include "renderpass.h"
+
+#include <QList>
+#include <QMap>
+#include <QQmlListProperty>
+#include <QSharedPointer>
+
+// FIXME - move enum somewhere common so don't need to include this here
+#include <quniformvalue.h>
+
+namespace Qt3D {
+
+class QT3DCORESHARED_EXPORT Parameter : public QObject
+{
+ Q_OBJECT
+
+public:
+ // FIXME - sort this by frequency, to minimize the size of the
+ // vector in RenderShader. (We want to use compact storage, but we index
+ // by this enum, and resize to the largest value)
+ enum StandardUniform
+ {
+ None = -1,
+
+ ModelMatrix = 0,
+ ViewMatrix,
+ ProjectionMatrix,
+ ModelView,
+ ModelViewProjection,
+
+ ModelInverse,
+ ViewInverse,
+ ProjectionInverse,
+ ModelViewInverse,
+ ModelViewProjectionInverse,
+
+ ModelNormal,
+ ModelViewNormal
+ };
+
+ Parameter(QObject* parent, QString name, int ty);
+
+ QString name() const
+ { return m_name; }
+
+ // permit one extra level of indrection in mesh naming of
+ // attributes (glTf at least does this)
+ void setMeshAttributeName(QString name);
+ QString meshAttributeName() const
+ { return m_meshName; }
+
+ bool isStandardUniform() const;
+
+ void setStandardUniform(StandardUniform su);
+ StandardUniform standardUniform() const;
+
+ /**
+ * @brief setDefaultValue - for non-texture uniform parameters
+ * @param dv
+ */
+ void setDefaultValue(QVariant dv);
+
+ // setUniformValue();
+
+ QVariant value() const;
+
+ int datatype() const
+ { return m_type; }
+
+ bool isTextureType() const;
+
+ /**
+ * @brief uniformType - map the data type to the primitive uniform type
+ * @return
+ */
+ Render::QUniformValue::Type uniformType() const;
+signals:
+ void valueChanged();
+
+private:
+ QString m_name;
+ int m_type;
+ QVariant m_value;
+ QVariant m_defaultValue;
+ QString m_meshName;
+ StandardUniform m_standardUniform;
+};
+
+class QT3DCORESHARED_EXPORT Technique : public Node
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQmlListProperty<Qt3D::Tag> tags READ tags NOTIFY tagsChanged)
+ Q_PROPERTY(QQmlListProperty<Qt3D::RenderPass> renderPasses READ renderPassList NOTIFY renderPassesChanged)
+
+public:
+ explicit Technique(Node *parent = 0);
+
+ QQmlListProperty<Qt3D::Tag> tags();
+ void addTag( const QString& name, const QVariant& value );
+ void removeTag( const QString& name );
+ void setTagValue( const QString& name, const QVariant& value );
+ QVariant tagValue( const QString& name ) const;
+ bool containsTag( const QString& name ) const;
+
+
+ void addPass(RenderPass* pass);
+ QList<RenderPass *> renderPasses() const;
+
+ QQmlListProperty<Qt3D::RenderPass> renderPassList();
+
+
+
+ // QQmlListProperty<Qt3D::Parameter> parameters();
+
+ void addParameter(Parameter* p);
+ QList<Parameter *> parameters() const
+ { return m_parameters; }
+
+ Parameter* parameterByName(QString name) const;
+signals:
+ void tagsChanged();
+ void renderPassesChanged();
+
+private:
+ static void appendTag(QQmlListProperty<Tag> *list, Tag *bar);
+ static Tag *tagAt(QQmlListProperty<Tag> *list, int index);
+ static int tagCount(QQmlListProperty<Tag> *list);
+ static void clearTags(QQmlListProperty<Tag> *list);
+
+ static void appendRenderPass(QQmlListProperty<RenderPass> *list, RenderPass* renderPass);
+ static RenderPass *renderPassAt(QQmlListProperty<RenderPass> *list, int index);
+ static int renderPassCount(QQmlListProperty<RenderPass> *list);
+ static void clearRenderPasses( QQmlListProperty<RenderPass> *list);
+
+ QList<Tag *> m_tagList;
+ QMap<QString, Tag *> m_tags;
+
+ QList<Parameter *> m_parameters;
+
+ QList<RenderPass *> m_renderPasses;
+};
+
+}
+
+#endif // TECHNIQUE_H
diff --git a/src/render/frontend/techniquefilter.cpp b/src/render/frontend/techniquefilter.cpp
new file mode 100644
index 000000000..038fa51f1
--- /dev/null
+++ b/src/render/frontend/techniquefilter.cpp
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "techniquefilter.h"
+
+namespace Qt3D {
+
+TechniqueFilter::TechniqueFilter(Node *parent)
+ : Qt3D::Component(parent)
+{
+}
+
+QQmlListProperty<Qt3D::Tag> TechniqueFilter::tags()
+{
+ return QQmlListProperty<Qt3D::Tag>(this, 0,
+ &TechniqueFilter::appendTag,
+ &TechniqueFilter::tagCount,
+ &TechniqueFilter::tagAt,
+ &TechniqueFilter::clearTags);
+}
+
+void TechniqueFilter::appendTag(QQmlListProperty<Tag> *list, Tag *tag)
+{
+ TechniqueFilter *filter = qobject_cast<TechniqueFilter *>(list->object);
+ if (filter) {
+ tag->setParent(filter);
+ filter->m_tagList.append(tag);
+ emit filter->tagsChanged();
+ }
+}
+
+Tag *TechniqueFilter::tagAt(QQmlListProperty<Tag> *list, int index)
+{
+ TechniqueFilter *filter = qobject_cast<TechniqueFilter *>(list->object);
+ if (filter)
+ return filter->m_tagList.value(index);
+ return 0;
+}
+
+int TechniqueFilter::tagCount(QQmlListProperty<Tag> *list)
+{
+ TechniqueFilter *filter = qobject_cast<TechniqueFilter *>(list->object);
+ if (filter)
+ return filter->m_tagList.size();
+ return 0;
+}
+
+void TechniqueFilter::clearTags(QQmlListProperty<Tag> *list)
+{
+ TechniqueFilter *filter = qobject_cast<TechniqueFilter *>(list->object);
+ if (filter) {
+ filter->m_tagList.clear();
+ emit filter->tagsChanged();
+ }
+}
+
+} // namespace Qt3D
diff --git a/src/render/frontend/techniquefilter.h b/src/render/frontend/techniquefilter.h
new file mode 100644
index 000000000..102f68a1d
--- /dev/null
+++ b/src/render/frontend/techniquefilter.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_TECHNIQUEFILTER_H
+#define QT3D_TECHNIQUEFILTER_H
+
+#include <qt3dcore_global.h>
+#include <component.h>
+
+#include "tag.h"
+
+#include <QQmlListProperty>
+
+namespace Qt3D {
+
+class TechniqueFilter : public Qt3D::Component
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQmlListProperty<Qt3D::Tag> tags READ tags NOTIFY tagsChanged)
+ Q_CLASSINFO("DefaultProperty", "tags")
+
+public:
+ explicit TechniqueFilter(Node *parent = 0);
+
+ QQmlListProperty<Qt3D::Tag> tags();
+
+signals:
+ void tagsChanged();
+
+private:
+ static void appendTag(QQmlListProperty<Tag> *list, Tag *bar);
+ static Tag *tagAt(QQmlListProperty<Tag> *list, int index);
+ static int tagCount(QQmlListProperty<Tag> *list);
+ static void clearTags(QQmlListProperty<Tag> *list);
+
+ QList<Tag *> m_tagList;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_TECHNIQUEFILTER_H
diff --git a/src/render/frontend/texture.cpp b/src/render/frontend/texture.cpp
new file mode 100644
index 000000000..81c1be5f9
--- /dev/null
+++ b/src/render/frontend/texture.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "texture.h"
+
+#include <texturedata.h>
+
+#include <QImage>
+#include <QDebug>
+
+namespace Qt3D {
+
+QmlTexture::QmlTexture(Node *parent) :
+ Node(parent),
+ m_texture(new Texture)
+{
+ m_texture->setTarget(QOpenGLTexture::Target2D);
+ m_texture->setInternalFormat(QOpenGLTexture::RGBA8_UNorm);
+}
+
+QUrl QmlTexture::source() const
+{
+ return m_source;
+}
+
+bool QmlTexture::isRectangle() const
+{
+ return (m_texture->target() == QOpenGLTexture::TargetRectangle);
+}
+
+Texture *QmlTexture::texture() const
+{
+ return m_texture;
+}
+
+void QmlTexture::setSource(QUrl arg)
+{
+ if (m_source != arg) {
+ m_source = arg;
+
+ if (m_source.isLocalFile()) {
+ QImage img(m_source.toLocalFile());
+ m_texture->setInternalFormat(img.hasAlphaChannel() ?
+ QOpenGLTexture::RGBA8_UNorm :
+ QOpenGLTexture::RGB8_UNorm);
+
+ m_texture->setFromQImage(img);
+ } else {
+ qWarning() << "implement loading from remote URLs";
+ }
+
+ emit sourceChanged();
+ }
+}
+
+void QmlTexture::setRectangle(bool r)
+{
+ m_texture->setTarget(r ? QOpenGLTexture::TargetRectangle :
+ QOpenGLTexture::Target2D);
+}
+
+
+} // namespace Qt3D
diff --git a/src/render/frontend/texture.h b/src/render/frontend/texture.h
new file mode 100644
index 000000000..910f66aca
--- /dev/null
+++ b/src/render/frontend/texture.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_TEXTURE_H
+#define QT3D_TEXTURE_H
+
+#include "node.h"
+
+#include <QUrl>
+
+namespace Qt3D {
+
+class Texture;
+
+class QmlTexture : public Node
+{
+ Q_OBJECT
+public:
+ explicit QmlTexture(Node *parent = 0);
+
+ Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged)
+ Q_PROPERTY(bool rectangle READ isRectangle WRITE setRectangle NOTIFY formatChanged)
+
+ QUrl source() const;
+
+ bool isRectangle() const;
+
+ Texture* texture() const;
+signals:
+ void sourceChanged();
+ void formatChanged();
+
+public slots:
+
+
+ void setSource(QUrl arg);
+
+ void setRectangle(bool r);
+
+private:
+ Texture* m_texture;
+
+ QUrl m_source;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_TEXTURE_H
diff --git a/src/render/frontend/transform.cpp b/src/render/frontend/transform.cpp
new file mode 100644
index 000000000..5ac195dc3
--- /dev/null
+++ b/src/render/frontend/transform.cpp
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "transform.h"
+
+#include <matrixtransform.h>
+
+namespace Qt3D {
+
+Transform::Transform(Node *parent)
+ : Qt3D::Component(parent)
+{
+}
+
+QQmlListProperty<AbstractTransform> Transform::transformList()
+{
+ return QQmlListProperty<AbstractTransform>(this, 0,
+ Transform::qmlAppendTransform,
+ Transform::transformCount,
+ Transform::transformAt,
+ Transform::qmlClearTransforms);
+}
+
+QMatrix4x4 Transform::matrix() const
+{
+ if (m_transformsDirty) {
+ m_matrix = applyTransforms();
+ m_transformsDirty = false;
+ }
+ return m_matrix;
+}
+
+void Transform::setMatrix(const QMatrix4x4 &m)
+{
+ qDeleteAll(m_transforms);
+ m_transforms.clear();
+ appendTransfrom(new MatrixTransform(m));
+}
+
+/*!
+ The center of rotation for the entity. Defaults to the local origin.
+*/
+QVector3D Transform::rotationCenter() const
+{
+ return QVector3D();
+}
+
+QList<AbstractTransform *> Transform::transforms() const
+{
+ return m_transforms;
+}
+
+void Transform::setRotationCenter(const QVector3D &rc)
+{
+ Q_UNUSED(rc);
+}
+
+void Transform::appendTransfrom(AbstractTransform *xform)
+{
+ m_transformsDirty = true;
+ m_transforms.append( xform );
+}
+
+void Transform::removeTransform(AbstractTransform *xform)
+{
+ m_transformsDirty = true;
+ m_transforms.removeOne( xform );
+}
+
+QMatrix4x4 Transform::applyTransforms() const
+{
+ QMatrix4x4 m;
+ m.setToIdentity();
+ Q_FOREACH (AbstractTransform *t, m_transforms)
+ m = t->matrix() * m;
+ return m;
+}
+
+
+void Transform::qmlAppendTransform(QQmlListProperty<AbstractTransform> *list, AbstractTransform *obj )
+{
+ if ( !obj )
+ return;
+
+ Transform *self = static_cast<Transform *>(list->object);
+ self->appendTransfrom(obj);
+}
+
+AbstractTransform* Transform::transformAt(QQmlListProperty<AbstractTransform> *list, int index)
+{
+ Transform *self = static_cast<Transform *>(list->object);
+ return self->transforms().at(index);
+}
+
+int Transform::transformCount(QQmlListProperty<AbstractTransform> *list)
+{
+ Transform *self = static_cast<Transform *>(list->object);
+ return self->transforms().count();
+}
+
+void Transform::qmlClearTransforms(QQmlListProperty<AbstractTransform> *list)
+{
+ Transform *self = static_cast<Transform *>(list->object);
+ qDeleteAll(self->m_transforms);
+ self->m_transforms.clear();
+ self->m_transformsDirty = true;
+}
+
+} // namespace Qt3D
diff --git a/src/render/frontend/transform.h b/src/render/frontend/transform.h
new file mode 100644
index 000000000..65cbadb35
--- /dev/null
+++ b/src/render/frontend/transform.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_TRANSFORM_H
+#define QT3D_TRANSFORM_H
+
+#include <component.h>
+
+#include <QMatrix4x4>
+
+namespace Qt3D {
+
+class AbstractTransform;
+
+class Transform : public Qt3D::Component
+{
+ Q_OBJECT
+ Q_PROPERTY(QQmlListProperty<Qt3D::AbstractTransform> transforms READ transformList)
+ Q_CLASSINFO("DefaultProperty", "transforms")
+
+public:
+ explicit Transform(Node *parent = 0);
+
+ QMatrix4x4 matrix() const;
+ void setMatrix(const QMatrix4x4 &m);
+
+ QVector3D rotationCenter() const;
+ void setRotationCenter(const QVector3D &rc);
+
+ QList<AbstractTransform*> transforms() const;
+
+ // void insertTransformAt(...)
+ Q_INVOKABLE void appendTransfrom(AbstractTransform *xform);
+ Q_INVOKABLE void removeTransform(AbstractTransform *xform);
+
+ QQmlListProperty<Qt3D::AbstractTransform> transformList();
+
+private:
+ QMatrix4x4 applyTransforms() const;
+
+ static void qmlAppendTransform(QQmlListProperty<Qt3D::AbstractTransform> *list, Qt3D::AbstractTransform *bar);
+ static AbstractTransform* transformAt(QQmlListProperty<Qt3D::AbstractTransform> *list, int index);
+ static int transformCount(QQmlListProperty<Qt3D::AbstractTransform> *list);
+ static void qmlClearTransforms(QQmlListProperty<Qt3D::AbstractTransform> *list);
+
+ mutable bool m_transformsDirty;
+ bool m_visible;
+ QList<AbstractTransform*> m_transforms;
+
+ mutable QMatrix4x4 m_matrix;
+ QMatrix4x4 m_sceneMatrix;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_TRANSFORM_H
diff --git a/src/render/frontend/viewport.cpp b/src/render/frontend/viewport.cpp
new file mode 100644
index 000000000..8c13190a1
--- /dev/null
+++ b/src/render/frontend/viewport.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "viewport.h"
+
+namespace Qt3D {
+
+Viewport::Viewport(Node *parent)
+ : Component(parent)
+{
+}
+
+QRectF Viewport::rect() const
+{
+ return m_rect;
+}
+
+void Viewport::setRect(const QRectF &rect)
+{
+ if (m_rect != rect) {
+ m_rect = rect;
+ emit rectChanged( rect );
+ }
+}
+
+}
diff --git a/src/render/frontend/viewport.h b/src/render/frontend/viewport.h
new file mode 100644
index 000000000..7a420d108
--- /dev/null
+++ b/src/render/frontend/viewport.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef VIEWPORT_H
+#define VIEWPORT_H
+
+#include <qt3dcore_global.h>
+
+#include <component.h>
+
+#include <QRectF>
+
+namespace Qt3D {
+
+class Viewport : public Component
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QRectF rect READ rect WRITE setRect NOTIFY rectChanged)
+
+public:
+ explicit Viewport(Node *parent = 0);
+
+ QRectF rect() const;
+
+public slots:
+ void setRect( const QRectF& rect );
+
+signals:
+ void rectChanged( const QRectF& arg );
+
+private:
+ QRectF m_rect;
+};
+
+}
+
+#endif // VIEWPORT_H
diff --git a/src/render/io/gltfparser.cpp b/src/render/io/gltfparser.cpp
new file mode 100644
index 000000000..67bd83960
--- /dev/null
+++ b/src/render/io/gltfparser.cpp
@@ -0,0 +1,842 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "gltfparser.h"
+
+#include "texturedata.h"
+
+#include <entity.h>
+#include <mesh.h>
+#include <material.h>
+#include <technique.h>
+#include <shaderprogram.h>
+#include <effect.h>
+#include <camera.h>
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QFile>
+#include <QDir>
+#include <QFileInfo>
+#include <QQuaternion>
+#include <QMatrix4x4>
+#include <QColor>
+#include <QVector2D>
+#include <QVector3D>
+
+// need to move these to somewhere common?
+#include <drawstate.h>
+#include <states/blendstate.h>
+
+namespace Qt3D {
+
+namespace
+{
+
+Parameter::StandardUniform parseSemanticName(QString s)
+{
+ if (s == "MODEL") return Parameter::ModelMatrix;
+ if (s == "VIEW") return Parameter::ViewMatrix;
+ if (s == "PROJECTION") return Parameter::ProjectionMatrix;
+ if (s == "MODELVIEW") return Parameter::ModelView;
+ if (s == "MODELVIEWPROJECTION")
+ return Parameter::ModelViewProjection;
+
+ if (s == "MODELINVERSE") return Parameter::ModelInverse;
+ if (s == "VIEWINVERSE") return Parameter::ViewInverse;
+ if (s == "PROJECTIONINVERSE")
+ return Parameter::ProjectionInverse;
+ if (s == "MODELVIEWINVERSE")
+ return Parameter::ModelViewInverse;
+ if (s == "MODELVIEWPROJECTIONINVERSE")
+ return Parameter::ModelViewProjectionInverse;
+
+ if (s == "MODELINVERSETRANSPOSE")
+ return Parameter::ModelNormal;
+ if (s == "MODELVIEWINVERSETRANSPOSE")
+ return Parameter::ModelViewNormal;
+
+ return Parameter::None;
+}
+
+} // of anonymous namespace
+
+GLTFParser::GLTFParser() :
+ m_parseDone(false)
+{
+}
+
+bool GLTFParser::isGLTFPath(QString path)
+{
+ QFileInfo finfo(path);
+ if (!finfo.exists())
+ return false;
+
+ // might need to detect other things in the future, but would
+ // prefer to avoid doing a full parse.
+ return (finfo.suffix().toLower() == "json");
+}
+
+void GLTFParser::setFilePath(QString path)
+{
+ QFileInfo finfo(path);
+ if (!finfo.exists()) {
+ qWarning() << "missing file:" << path;
+ return;
+ }
+
+ QFile f(path);
+ f.open(QIODevice::ReadOnly);
+
+ if (!setJSON(QJsonDocument::fromJson(f.readAll()))) {
+ qWarning() << "not a JSON document";
+ return;
+ }
+
+ setBasePath(finfo.dir().absolutePath());
+}
+
+void GLTFParser::setBasePath(QString path)
+{
+ m_basePath = path;
+}
+
+bool GLTFParser::setJSON( QJsonDocument json )
+{
+ if ( !json.isObject() ) {
+ return false;
+ }
+
+ m_json = json;
+ m_parseDone = false;
+
+ m_meshDict.clear();
+ m_attributeDict.clear();
+ m_defaultScene.clear();
+
+ return true;
+}
+
+MeshDataPtr GLTFParser::mesh(QString id)
+{
+ parse();
+ if (m_meshDict.contains(id))
+ return m_meshDict.value(id);
+
+ qWarning() << "Unknown mesh" << id << "in GLTF file" << m_basePath;
+ return MeshDataPtr();
+}
+
+Entity* GLTFParser::defaultScene()
+{
+ parse();
+ if (m_defaultScene.isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "no default scene";
+ return NULL;
+ }
+
+ return scene(m_defaultScene);
+}
+
+Entity* GLTFParser::scene(QString id)
+{
+ parse();
+
+ QJsonObject scenes = m_json.object().value("scenes").toObject();
+ if (!scenes.contains(id)) {
+ qWarning() << "GLTF: no such scene" << id << "in file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject sceneObj = scenes.value(id).toObject();
+ Entity* sceneEntity = new Entity;
+ foreach (QJsonValue nnv, sceneObj.value("nodes").toArray()) {
+ QString nodeName = nnv.toString();
+ Entity* child = node(nodeName);
+ if (!child)
+ continue;
+
+ sceneEntity->addChild(child);
+ }
+
+ return sceneEntity;
+}
+
+Entity* GLTFParser::node(QString id)
+{
+ QJsonObject nodes = m_json.object().value("nodes").toObject();
+ if (!nodes.contains(id)) {
+ qWarning() << "unknown node" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = nodes.value(id).toObject();
+ Entity* result( new Entity );
+ parse();
+
+ if ( jsonObj.contains( "children" ) )
+ {
+ foreach (QJsonValue c, jsonObj.value( "children" ).toArray()) {
+ Entity* child = node(c.toString());
+ if (!child)
+ continue;
+ result->addChild(child);
+ }
+ }
+
+ if ( jsonObj.contains( "meshes") )
+ {
+ typedef QList<Mesh*> MeshList;
+ QMap<QString, MeshList> materialDict;
+
+ foreach (QJsonValue m, jsonObj.value( "meshes" ).toArray())
+ {
+ if (!m_meshDict.contains(m.toString())) {
+ qWarning() << "node" << id << "references unknown mesh" << m.toString();
+ continue;
+ }
+
+ foreach (MeshDataPtr md, m_meshDict.values(m.toString())) {
+ QString matId = m_meshMaterialDict[md.data()];
+ Mesh* meshComp = new Mesh;
+ meshComp->setData(md);
+ materialDict[matId].append(meshComp);
+ }
+ }
+
+ if (materialDict.size() == 1) {
+ // common case
+ result->addComponent(material(materialDict.firstKey()));
+ foreach (Mesh* m, materialDict.first())
+ result->addComponent(m);
+ } else {
+ // need to make a child entity per material
+ foreach (QString matId, materialDict.keys()) {
+ Entity* subEntity(new Entity);
+ result->addChild(subEntity);
+
+ subEntity->addComponent(material(matId));
+ foreach (Mesh* m, materialDict.value(matId))
+ subEntity->addComponent(m);
+ } // of distinct material iteration
+ } // of multiple materials case
+ }
+
+ processName(jsonObj, result);
+
+ if ( jsonObj.contains( "matrix") )
+ {
+ QMatrix4x4 m;
+ QJsonArray matrixValues = jsonObj.value( "matrix" ).toArray();
+
+ for (int i=0; i<16; ++i) {
+ double v = matrixValues.at( i ).toDouble();
+ m(i % 4, i >> 2) = v;
+ }
+
+ result->setMatrix( m );
+ }
+
+ if ( jsonObj.contains( "camera") )
+ {
+ Camera* cam = camera( jsonObj.value("camera").toString() );
+ if (!cam) {
+ qWarning() << "failed to build camera:" << jsonObj.value("camera")
+ << "on node" << id;
+ } else {
+ result->addComponent(cam);
+ }
+ } // of have camera attribute
+
+ return result;
+}
+
+// Get rid of miniwindef.h clobbering legal variable names
+#if defined(near)
+#undef near
+#endif
+
+#if defined(far)
+#undef far
+#endif
+
+Camera* GLTFParser::camera(QString id)
+{
+ parse();
+ QJsonObject cams = m_json.object().value("cameras").toObject();
+ if (!cams.contains(id)) {
+ qWarning() << "unknown camera" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = cams.value(id).toObject();
+ QString camTy = jsonObj.value("type").toString();
+
+ if (camTy == "perspective") {
+ if (!jsonObj.contains("perspective")) {
+ qWarning() << "camera:" << id << "missing 'perspective' object";
+ return NULL;
+ }
+
+ QJsonObject pObj = jsonObj.value("perspective").toObject();
+ double yfov = pObj.value("yfov").toDouble();
+ double near = pObj.value("znear").toDouble();
+ double far = pObj.value("zfar").toDouble();
+
+ Camera* result = new Camera;
+ result->setPerspectiveProjection(yfov, 1.0, near, far);
+ return result;
+ } else if (camTy == "orthographic") {
+ qWarning() << Q_FUNC_INFO << "implement me";
+
+ return NULL;
+ } else {
+ qWarning() << "camera:" << id << "has unsupported type:" << camTy;
+ return NULL;
+ }
+}
+
+Material* GLTFParser::material(QString id)
+{
+ parse();
+
+ if (m_materialCache.contains(id))
+ return m_materialCache.value(id);
+
+ QJsonObject mats = m_json.object().value("materials").toObject();
+ if (!mats.contains(id)) {
+ qWarning() << "unknown material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ QJsonObject jsonObj = mats.value(id).toObject();
+
+ QJsonObject tech = jsonObj.value("instanceTechnique").toObject();
+ QString tname = tech.value("technique").toString();
+ if (!m_techniques.contains(tname)) {
+ qWarning() << "unknown technique" << tname <<
+ "for material" << id << "in GLTF file" << m_basePath;
+ return NULL;
+ }
+
+ Technique *technique = m_techniques.value(tname);
+ if (!m_effectProxies.contains(tname)) {
+ Effect* eff = new Effect;
+ eff->setObjectName(tname);
+ eff->addTechnique(technique);
+ m_effectProxies[tname] = eff;
+ }
+
+ Material* mat = new Material;
+ mat->setEffect(m_effectProxies[tname]);
+
+ processName(jsonObj, mat);
+
+ QJsonObject values = tech.value("values").toObject();
+ foreach (QString vName, values.keys()) {
+ Parameter* param = technique->parameterByName(vName);
+ if (!param) {
+ qWarning() << "unknown parameter:" << vName << "in technique" << tname
+ << "processing material" << id;
+ continue;
+ }
+
+ if (param->isTextureType()) {
+ QString textureId = values.value(vName).toString();
+ if (!m_textures.contains(textureId)) {
+ qWarning() << "unknown texture" << textureId << "for parameter" << vName
+ << "of material" << id;
+ } else {
+ mat->setTextureParameter(vName, m_textures.value(textureId));
+ }
+ } else {
+ QVariant var = parameterValueFromJSON(param, values.value(vName));
+ mat->setParameter(vName, var);
+ }
+ } // of material technique-instance values iteration
+
+ m_materialCache[id] = mat;
+ return mat;
+}
+
+void GLTFParser::parse()
+{
+ if (m_parseDone)
+ return;
+
+ QJsonObject buffers = m_json.object().value("buffers").toObject();
+ foreach (QString nm, buffers.keys()) {
+ processJSONBuffer( nm, buffers.value(nm).toObject() );
+ }
+
+ QJsonObject views = m_json.object().value("bufferViews").toObject();
+ foreach (QString nm, views.keys()) {
+ processJSONBufferView( nm, views.value(nm).toObject() );
+ }
+
+ QJsonObject shaders = m_json.object().value("shaders").toObject();
+ foreach (QString nm, shaders.keys()) {
+ processJSONShader( nm, shaders.value(nm).toObject() );
+ }
+
+ QJsonObject programs = m_json.object().value("programs").toObject();
+ foreach (QString nm, programs.keys()) {
+ processJSONProgram( nm, programs.value(nm).toObject() );
+ }
+
+ QJsonObject techniques = m_json.object().value("techniques").toObject();
+ foreach (QString nm, techniques.keys()) {
+ processJSONTechnique( nm, techniques.value(nm).toObject() );
+ }
+
+ QJsonObject attrs = m_json.object().value("accessors").toObject();
+ foreach (QString nm, attrs.keys()) {
+ processJSONAccessor( nm, attrs.value(nm).toObject() );
+ }
+
+ QJsonObject meshes = m_json.object().value("meshes").toObject();
+ foreach (QString nm, meshes.keys()) {
+ processJSONMesh( nm, meshes.value(nm).toObject() );
+ }
+
+ QJsonObject images = m_json.object().value("images").toObject();
+ foreach (QString nm, images.keys()) {
+ processJSONImage( nm, images.value(nm).toObject() );
+ }
+
+ QJsonObject textures = m_json.object().value("textures").toObject();
+ foreach (QString nm, textures.keys()) {
+ processJSONTexture(nm, textures.value(nm).toObject() );
+ }
+
+ m_defaultScene = m_json.object().value("scene").toString();
+ m_parseDone = true;
+}
+
+void GLTFParser::processJSONBuffer( QString id, const QJsonObject& json )
+{
+ // simply cache buffers for lookup by buffer-views
+ m_bufferDatas[id] = BufferData(json);
+}
+
+void GLTFParser::processJSONBufferView( QString id, const QJsonObject& json )
+{
+ QString bufName = json.value("buffer").toString();
+ if (!m_bufferDatas.contains(bufName)) {
+ qWarning() << "unknown buffer:" << bufName << "processing view:" << id;
+ return;
+ }
+
+ int target = json.value("target").toInt();
+ QOpenGLBuffer::Type ty(QOpenGLBuffer::VertexBuffer);
+
+ switch (target) {
+ case GL_ARRAY_BUFFER: ty = QOpenGLBuffer::VertexBuffer; break;
+ case GL_ELEMENT_ARRAY_BUFFER: ty = QOpenGLBuffer::IndexBuffer; break;
+ default:
+ qWarning() << Q_FUNC_INFO << "buffer" << id << "unsupported target:" << target;
+ return;
+ }
+
+ quint64 offset = 0;
+ if (json.contains("byteOffset")) {
+ offset = json.value("byteOffset").toInt();
+ qDebug() << "bv:" << id << "has offset:" << offset;
+ }
+
+ quint64 len = json.value("byteLength").toInt();
+ QFile* f = resolveLocalData(m_bufferDatas[bufName].path);
+ if (!f->seek(offset)) {
+ qWarning() << "failed to seek to offset in file for bufferView:" << id << offset;
+ }
+
+ QByteArray bytes = f->read(len);
+ if (bytes.count() != (int) len) {
+ qWarning() << "failed to read sufficient bytes from:" << m_bufferDatas[bufName].path
+ << "for view" << id;
+ }
+ delete f;
+
+ BufferPtr b(new Buffer(ty));
+ b->setData(bytes);
+ m_buffers[id] = b;
+}
+
+void GLTFParser::processJSONAccessor( QString id, const QJsonObject& json )
+{
+ QString bvName = json.value("bufferView").toString();
+ if (!m_buffers.contains(bvName)) {
+ qWarning() << "unknown buffer-view:" << bvName << "processing accessor:" << id;
+ return;
+ }
+
+ BufferPtr buf = m_buffers.value(bvName);
+ int offset = 0, stride = 0;
+ int type = json.value("type").toInt();
+ int count = json.value("count").toInt();
+
+ if ( json.contains("byteOffset"))
+ offset = json.value("byteOffset").toInt();
+ if ( json.contains("byteStride"))
+ stride = json.value("byteStride").toInt();
+
+ AttributePtr attr( new Attribute( buf, type, count, offset, stride ) );
+ m_attributeDict[id] = attr;
+}
+
+void GLTFParser::processJSONMesh( QString id, QJsonObject jsonObj )
+{
+ QJsonArray primsArray = jsonObj.value( "primitives").toArray();
+ Q_FOREACH (QJsonValue primVal, primsArray) {
+ QJsonObject primObj = primVal.toObject();
+ int type = primObj.value( "primitive").toInt();
+ QString material = primObj.value( "material").toString();
+
+ if ( material.isEmpty()) {
+ qWarning() << "malformed primitive on " << id << ", missing material value"
+ << material;
+ continue;
+ }
+
+ MeshDataPtr md( new MeshData( type ) );
+ m_meshMaterialDict[md.data()] = material;
+
+ QJsonObject attrs = primObj.value("attributes").toObject();
+ Q_FOREACH (QString attrName, attrs.keys()) {
+ QString k = attrs.value(attrName).toString();
+ if (!m_attributeDict.contains(k)) {
+ qWarning() << "unknown attribute accessor:" << k << "on mesh" << id;
+ continue;
+ }
+
+ md->addAttribute(attrName, m_attributeDict[k]);
+
+ // qDebug() << "DUMP of:" << attrName;
+ // m_attributeDict[k]->dump(20);
+ }
+
+ if ( primObj.contains( "indices" )) {
+ QString k = primObj.value("indices").toString();
+ if (!m_attributeDict.contains(k)) {
+ qWarning() << "unknown index accessor:" << k << "on mesh" << id;
+ } else {
+ md->setIndexAttr(m_attributeDict[k]);
+ // m_attributeDict[k]->dump(100);
+ }
+ } // of has indices
+
+ m_meshDict.insert( id, md );
+ } // of primitives iteration
+}
+
+void GLTFParser::processName(const QJsonObject &json, QObject *ins)
+{
+ if ( json.contains( "name" ) )
+ {
+ ins->setObjectName( json.value("name").toString() );
+ }
+}
+
+void GLTFParser::processJSONProgram( QString id, QJsonObject jsonObj)
+{
+ ShaderProgram* prog = new ShaderProgram;
+ prog->setObjectName(id);
+
+ QString fragName = jsonObj.value("fragmentShader").toString(),
+ vertName = jsonObj.value("vertexShader").toString();
+ if (!m_shaderPaths.contains(fragName) || !m_shaderPaths.contains(vertName)) {
+ qWarning() << Q_FUNC_INFO << "program:" << id << "missing shader:" <<
+ fragName << vertName;
+ return;
+ }
+
+ prog->setFragmentSourceFile(m_shaderPaths[fragName]);
+ prog->setVertexSourceFile(m_shaderPaths[vertName]);
+ m_programs[id] = prog;
+}
+
+void GLTFParser::processJSONShader( QString id, QJsonObject jsonObj)
+{
+ // shaders are trivial for the moment, defer the real work
+ // to the program section
+ QString path = jsonObj.value("path").toString();
+
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qWarning() << "can't find shader" << id << "from path" << path;
+ return;
+ }
+
+ m_shaderPaths[id] = info.absoluteFilePath();
+}
+
+void GLTFParser::processJSONImage( QString id, QJsonObject jsonObj)
+{
+ QString path = jsonObj.value("path").toString();
+ QFileInfo info(m_basePath, path);
+ if (!info.exists()) {
+ qWarning() << "can't find image" << id << "from path" << path;
+ return;
+ }
+
+ QImage img(info.absoluteFilePath());
+ if (img.isNull()) {
+ qWarning() << "failed to load image:" << info.absoluteFilePath();
+ return;
+ }
+
+ m_images[id] = img;
+}
+
+void GLTFParser::processJSONTexture( QString id, QJsonObject jsonObj)
+{
+ Texture* tex = new Texture();
+
+ int target = jsonObj.value("target").toInt();
+ int pixelFormat = jsonObj.value("format").toInt();
+ int internalFormat = jsonObj.value("internalFormat").toInt();
+
+ tex->setTarget(static_cast<QOpenGLTexture::Target>(target));
+ tex->setInternalFormat(QOpenGLTexture::RGBA8_UNorm /* static_cast<QOpenGLTexture::TextureFormat>(internalFormat)*/);
+
+ QString samplerId = jsonObj.value("sampler").toString();
+ QString source = jsonObj.value("source").toString();
+ if (!m_images.contains(source)) {
+ qWarning() << "texture" << id << "references missing image" << source;
+ return;
+ }
+
+ tex->setFromQImage(m_images[source]);
+
+ QJsonObject samplersDict(m_json.object().value("samplers").toObject());
+ if (!samplersDict.contains(samplerId)) {
+ qWarning() << "texture" << id << "references unknown sampler" << samplerId;
+ return;
+ }
+
+ QJsonObject sampler = samplersDict.value(samplerId).toObject();
+
+ tex->setWrapMode(static_cast<QOpenGLTexture::WrapMode>(sampler.value("wrapS").toInt()));
+ // tex->setWrapMode(sampler.value("wrapT").toInt());
+
+ tex->setMinificationFilter(static_cast<QOpenGLTexture::Filter>(sampler.value("minFilter").toInt()));
+ tex->setMagnificationFilter(static_cast<QOpenGLTexture::Filter>(sampler.value("magFilter").toInt()));
+
+ m_textures[id] = tex;
+}
+
+void GLTFParser::processJSONTechnique( QString id, QJsonObject jsonObj )
+{
+ Technique *t = new Technique;
+ t->setObjectName(id);
+
+ QHash<QString, Parameter*> paramDict;
+ QJsonObject params = jsonObj.value( "parameters").toObject();
+ Q_FOREACH (QString pname, params.keys()) {
+ QJsonObject po = params.value(pname).toObject();
+
+ int dataType = po.value("type").toInt();
+ QString semantic = po.value("semantic").toString();
+
+ Parameter* p = new Parameter(t, pname, dataType);
+ Parameter::StandardUniform su = parseSemanticName(semantic);
+ if (su != Parameter::None) {
+ p->setStandardUniform(su);
+ } else {
+ // should really verify it's an attribute parameter?
+ // but what would be the way to do that?
+ // check the accessor dict?
+ p->setMeshAttributeName(semantic);
+ }
+
+ t->addParameter(p);
+
+ paramDict[pname] = p;
+ } // of parameters iteration
+
+ QJsonObject passes = jsonObj.value("passes").toObject();
+ Q_FOREACH (QString pname, passes.keys()) {
+ QJsonObject po = passes.value(pname).toObject();
+ QJsonObject ip = po.value("instanceProgram").toObject();
+
+ QString programName = ip.value("program").toString();
+ if (!m_programs.contains(programName)) {
+ qWarning() << Q_FUNC_INFO << "technique" << id << "pass" << pname
+ << ": missing program" << programName;
+ continue;
+ }
+
+ RenderPass* pass = new RenderPass;
+ pass->setShaderProgram(m_programs[programName]);
+
+ QJsonObject attrs = ip.value("attributes").toObject();
+ Q_FOREACH ( QString attrName, attrs.keys() ) {
+ QString pname = attrs.value(attrName).toString();
+ pass->addAttributeBinding(paramDict[pname], attrName);
+ } // of program-instance attributes
+
+
+ QJsonObject uniforms = ip.value("uniforms").toObject();
+ Q_FOREACH (QString uniformName, uniforms.keys()) {
+ QString pname = uniforms.value(uniformName).toString();
+ pass->addUniformBinding(paramDict[pname], uniformName);
+ } // of program-instance attributes
+
+ QJsonObject states = po.value("states").toObject();
+ DrawStateSet* ss = new DrawStateSet;
+
+ Q_FOREACH (QString stateName, states.keys()) {
+ DrawState* s= buildState(stateName, states.value(stateName));
+ if (!s)
+ continue;
+
+ ss->addState(s);
+ } // of program-instance attributes
+
+ pass->setStateSet(ss);
+ t->addPass(pass);
+ } // of passes iteration
+
+ m_techniques[id] = t;
+}
+
+DrawState* GLTFParser::buildState(QString nm, QJsonValue v)
+{
+ if (nm == "blendEnable") {
+ return NULL; // will see a blendEquation spec too
+ }
+
+ if (nm == "blendFunc") {
+ QJsonObject obj = v.toObject();
+ GLenum srcF = static_cast<GLenum>(obj.value("sfactor").toInt());
+ GLenum dstF = static_cast<GLenum>(obj.value("dfactor").toInt());
+ return BlendState::getOrCreate(srcF, dstF);
+ }
+
+ if (nm == "blendEquation") {
+ return BlendEquation::getOrCreate(static_cast<GLenum>(v.toInt()));
+ }
+
+ if (nm == "cullFaceEnable" && v.toInt()) {
+ return CullFace::getOrCreate(GL_BACK);
+ }
+
+ if (nm == "depthTestEnable" && v.toInt()) {
+ return DepthTest::getOrCreate(GL_LESS);
+ }
+
+ if (nm == "depthMask") {
+ return DepthMask::getOrCreate(v.toInt() ? GL_TRUE : GL_FALSE);
+ }
+
+ qWarning() << Q_FUNC_INFO << "unsupported gltf state:" << nm;
+ return NULL;
+}
+
+QFile *GLTFParser::resolveLocalData(QString path)
+{
+ QDir d(m_basePath);
+ Q_ASSERT(d.exists());
+
+ QString absPath = d.absoluteFilePath(path);
+ QFile* f = new QFile(absPath);
+ f->open(QIODevice::ReadOnly);
+ return f;
+}
+
+GLTFParser::BufferData::BufferData() :
+ length(0)
+{
+}
+
+GLTFParser::BufferData::BufferData(QJsonObject json)
+{
+ path = json.value("path").toString();
+ length = json.value("length").toInt();
+ // url
+}
+
+QVariant GLTFParser::parameterValueFromJSON(Parameter* p, QJsonValue val)
+{
+ switch (p->datatype()) {
+ case GL_BOOL:
+ return val.toBool();
+
+ case GL_FLOAT:
+ return val.toDouble();
+
+ case GL_FLOAT_VEC2: {
+ QJsonArray a = val.toArray();
+ return QVector2D(a[0].toDouble(), a[1].toDouble());
+ }
+
+ case GL_FLOAT_VEC3: {
+ QJsonArray a = val.toArray();
+ return QVector3D(a[0].toDouble(), a[1].toDouble(), a[3].toDouble());
+ }
+
+ case GL_FLOAT_VEC4: {
+ QJsonArray a = val.toArray();
+ return QVector4D(a[0].toDouble(),
+ a[1].toDouble(),
+ a[2].toDouble(),
+ a[3].toDouble());
+ }
+
+ case GL_FLOAT_MAT4: {
+ QJsonArray a = val.toArray();
+
+ QMatrix4x4 m;
+ for (int i=0; i<16; ++i) {
+ m(i % 4, i / 4) = a[i].toDouble();
+ }
+ return m;
+ }
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unhandled type:" << QString::number(p->datatype(), 16);
+ }
+
+ return QVariant();
+}
+
+} // of namespace Qt3D
diff --git a/src/render/io/gltfparser.h b/src/render/io/gltfparser.h
new file mode 100644
index 000000000..76f8662f5
--- /dev/null
+++ b/src/render/io/gltfparser.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLTFPARSER_H
+#define GLTFPARSER_H
+
+#include "meshdata.h"
+
+#include <entity.h>
+#include <technique.h>
+
+#include <QJsonDocument>
+#include <QMultiHash>
+#include <QImage>
+
+class QFile;
+
+namespace Qt3D {
+
+class Material;
+class ShaderProgram;
+class Effect;
+class Camera;
+class Texture;
+
+class GLTFParser
+{
+public:
+ GLTFParser();
+
+ static bool isGLTFPath(QString path);
+
+ void setFilePath(QString path);
+
+ void setBasePath( QString path );
+
+ bool setJSON( QJsonDocument json );
+
+ /**
+ * @brief instantiate Create Nodes based on glTf JSON document
+ * @return A new scene-graph fragment based on the provided glTf
+ */
+ Entity *node(QString id);
+ Entity *defaultScene();
+ MeshDataPtr mesh(QString id);
+ Entity *scene(QString id);
+ Material *material(QString id);
+ Camera *camera(QString id);
+
+private:
+ void parse();
+
+ void processJSONMesh( QString id, QJsonObject jsonObj );
+ void processJSONAccessor(QString id, const QJsonObject &json);
+ void processJSONBuffer(QString id, const QJsonObject &json);
+ void processJSONBufferView(QString id, const QJsonObject &json);
+
+ void processName( const QJsonObject& json, QObject* ins );
+
+ QJsonDocument m_json;
+ QString m_basePath;
+ bool m_parseDone;
+ QString m_defaultScene;
+
+ // multi-hash because our MeshData corresponds to a single primitive
+ // in glTf.
+ QMultiHash<QString, MeshDataPtr> m_meshDict;
+
+ // GLTF assigns materials at the mesh level, but we do them as siblings,
+ // so record the association here for when we instantiate meshes
+ QMap<MeshData*, QString> m_meshMaterialDict;
+
+ QMap<QString, AttributePtr> m_attributeDict;
+
+ class BufferData
+ {
+ public:
+ BufferData();
+
+ BufferData(QJsonObject json);
+
+ quint64 length;
+ QString path;
+ // type if ever useful
+ };
+
+ QMap<QString, Material*> m_materialCache;
+
+ QMap<QString, BufferData> m_bufferDatas;
+ QMap<QString, BufferPtr> m_buffers;
+
+ QMap<QString, QString> m_shaderPaths;
+ QMap<QString, ShaderProgram*> m_programs;
+
+ QMap<QString, Technique *> m_techniques;
+ // glTF doesn't deal in effects, but we need a trivial one to wrap
+ // up our techniques
+ QMap<QString, Effect*> m_effectProxies;
+
+ QMap<QString, Texture*> m_textures;
+ QMap<QString, QImage> m_images;
+
+ QFile* resolveLocalData(QString path);
+
+ void processJSONShader(QString id, QJsonObject jsonObj);
+ void processJSONProgram(QString id, QJsonObject jsonObj);
+ void processJSONTechnique(QString id, QJsonObject jsonObj);
+
+ void processJSONImage(QString id, QJsonObject jsonObj);
+ void processJSONTexture(QString id, QJsonObject jsonObj);
+
+ QVariant parameterValueFromJSON(Parameter *p, QJsonValue val);
+
+ DrawState *buildState(QString nm, QJsonValue obj);
+};
+
+}
+
+#endif // GLTFPARSER_H
diff --git a/src/render/io/meshdata.cpp b/src/render/io/meshdata.cpp
new file mode 100644
index 000000000..7c68adb6b
--- /dev/null
+++ b/src/render/io/meshdata.cpp
@@ -0,0 +1,422 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "meshdata.h"
+
+#include <QSet>
+#include <QDebug>
+#include <QOpenGLVertexArrayObject>
+
+namespace Qt3D
+{
+
+GLint elementType(GLint type)
+{
+ switch (type) {
+ case GL_FLOAT:
+ case GL_FLOAT_VEC2:
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ return GL_FLOAT;
+
+ case GL_DOUBLE:
+ case GL_DOUBLE_VEC2:
+ case GL_DOUBLE_VEC3:
+ case GL_DOUBLE_VEC4:
+ return GL_DOUBLE;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16);
+ }
+
+ return GL_INVALID_VALUE;
+}
+
+GLint tupleSizeFromType(GLint type)
+{
+ switch (type) {
+ case GL_FLOAT:
+ case GL_DOUBLE:
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_INT:
+ break; // fall through
+
+ case GL_FLOAT_VEC2:
+ case GL_DOUBLE_VEC2: return 2;
+
+ case GL_FLOAT_VEC3:
+ case GL_DOUBLE_VEC3: return 3;
+
+ case GL_FLOAT_VEC4:
+ case GL_DOUBLE_VEC4: return 4;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16);
+ }
+
+ return 1;
+}
+
+GLuint byteSizeFromType(GLint type)
+{
+ switch (type) {
+ case GL_FLOAT: return sizeof(float);
+ case GL_DOUBLE: return sizeof(double);
+ case GL_UNSIGNED_BYTE: return sizeof(unsigned char);
+ case GL_UNSIGNED_INT: return sizeof(GLuint);
+
+ case GL_FLOAT_VEC2: return sizeof(float) * 2;
+ case GL_DOUBLE_VEC2: return sizeof(double) * 2;
+
+ case GL_FLOAT_VEC3: return sizeof(float) * 3;
+ case GL_DOUBLE_VEC3: return sizeof(double) * 3;
+
+ case GL_FLOAT_VEC4: return sizeof(float) * 4;
+ case GL_DOUBLE_VEC4: return sizeof(double) * 4;
+
+ default:
+ qWarning() << Q_FUNC_INFO << "unsupported:" << QString::number(type, 16);
+ }
+
+ return 0;
+}
+
+MeshData::MeshData()
+ : m_primitiveType(0)
+{
+}
+
+MeshData::MeshData(int primitiveType) :
+ m_primitiveType(primitiveType)
+{
+ Q_ASSERT((m_primitiveType == GL_TRIANGLES) ||
+ (m_primitiveType == GL_LINES) ||
+ (m_primitiveType == GL_POINTS));
+}
+
+void MeshData::addAttribute(QString name, AttributePtr attr)
+{
+ Q_ASSERT(!m_attributes.contains(name));
+ m_attributes[name] = attr;
+}
+
+void MeshData::addAttribute(QString name, Attribute *attr)
+{
+ Q_ASSERT(!m_attributes.contains(name));
+ m_attributes[name] = AttributePtr(attr);
+}
+
+void MeshData::setIndexAttr(AttributePtr indexAttr)
+{
+ m_indexAttr = indexAttr;
+}
+
+void MeshData::setIndexData(BufferPtr buf, int type, int count, int offset)
+{
+ m_indexAttr = AttributePtr(new Attribute(buf, type, count, offset));
+}
+
+GLint MeshData::primitiveType() const
+{
+ return m_primitiveType;
+}
+
+GLsizei MeshData::primitiveCount() const
+{
+ if (m_indexAttr) {
+ return m_indexAttr->count();
+ } else {
+ // assume all attribute arrays have the same size
+ // will break with instanced drawing, but probably per-instance
+ // arrays aren't coming from this code-path.
+ // Maybe.
+ return m_attributes.first()->count();
+ }
+}
+
+QStringList MeshData::attributeNames() const
+{
+ return m_attributes.keys();
+}
+
+AttributePtr MeshData::attributeByName(QString nm) const
+{
+ return m_attributes.value(nm);
+}
+
+AttributePtr MeshData::indexAttr() const
+{
+ return m_indexAttr;
+}
+
+QList<BufferPtr> MeshData::buffers() const
+{
+ QSet<BufferPtr> r;
+ if (m_indexAttr)
+ r.insert(m_indexAttr->buffer());
+
+ foreach (AttributePtr v, m_attributes.values())
+ r.insert(v->buffer());
+
+ return r.toList();
+}
+
+void MeshData::setBoundingBox(const AxisAlignedBoundingBox &bbox)
+{
+ m_box = bbox;
+}
+
+void MeshData::computeBoundsFromAttribute(QString name)
+{
+ AttributePtr attr = attributeByName(name);
+ if (!attr) {
+ qWarning() << Q_FUNC_INFO << "unknoen attribute:" << name;
+ return;
+ }
+
+ m_box.clear();
+ m_box.update(attr->asVector3D());
+}
+
+Attribute::Attribute(BufferPtr buf, int type, int count, int offset, int stride) :
+ m_buffer(buf),
+ m_type(type),
+ m_count(count),
+ m_stride(stride),
+ m_offset(offset),
+ m_divisor(0)
+{
+
+}
+
+void Attribute::setDivisor(unsigned int divisor)
+{
+ m_divisor = divisor;
+}
+
+BufferPtr Attribute::buffer() const
+{
+ return m_buffer;
+}
+
+QVector<QVector3D> Attribute::asVector3D() const
+{
+ const char* rawBuffer = m_buffer->data().constData();
+ rawBuffer += m_offset;
+ const float* fptr;
+ int stride;
+
+ switch (type()) {
+ case GL_FLOAT_VEC2:
+ stride = sizeof(float) * 2; break;
+
+ case GL_FLOAT_VEC3:
+ stride = sizeof(float) * 3; break;
+
+ case GL_FLOAT_VEC4:
+ stride = sizeof(float) * 4; break;
+
+ default:
+ qDebug() << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector3D";
+ return QVector<QVector3D>();
+ }
+
+ if (m_stride != 0)
+ stride = m_stride;
+ QVector<QVector3D> result;
+ result.resize(m_count);
+
+ for (int c=0; c<m_count; ++c) {
+ QVector3D v;
+ fptr = reinterpret_cast<const float*>(rawBuffer);
+
+ switch (type()) {
+ case GL_FLOAT_VEC2:
+ v.setX(fptr[0]);
+ v.setY(fptr[1]);
+ v.setZ(0.0f);
+ break;
+
+ case GL_FLOAT_VEC3:
+ case GL_FLOAT_VEC4:
+ v.setX(fptr[0]);
+ v.setY(fptr[1]);
+ v.setZ(fptr[2]);
+ break;
+
+ default:
+ break; // should never happen, we check types above
+ }
+
+ result[c] = v;
+ rawBuffer += stride;
+ }
+
+ return result;
+}
+
+QVector<QVector2D> Attribute::asVector2D() const
+{
+ char* rawBuffer = m_buffer->data().data();
+ rawBuffer += m_offset;
+ float* fptr;
+ int stride;
+
+ switch (type()) {
+ case GL_FLOAT_VEC2:
+ stride = sizeof(float) * 2; break;
+
+ case GL_FLOAT_VEC3:
+ stride = sizeof(float) * 3; break;
+
+ case GL_FLOAT_VEC4:
+ stride = sizeof(float) * 4; break;
+
+ default:
+ qDebug() << Q_FUNC_INFO << "can't convert" << QString::number(type(), 16) << "to QVector2D";
+ return QVector<QVector2D>();
+ }
+
+ if (m_stride != 0)
+ stride = m_stride;
+
+ QVector<QVector2D> result;
+ result.resize(m_count);
+
+ for (int c=0; c<m_count; ++c) {
+ QVector2D v;
+ fptr = reinterpret_cast<float*>(rawBuffer);
+ v.setX(fptr[0]);
+ v.setY(fptr[1]);
+ result[c] = v;
+ rawBuffer += stride;
+ }
+
+ return result;
+}
+
+void Attribute::dump(int count)
+{
+ char* rawBuffer = m_buffer->data().data();
+ rawBuffer += m_offset;
+
+ float* fptr;
+ quint16* usptr;
+
+ int stride = m_stride;
+
+ for (int c=0; c<count; ++c) {
+ switch (type()) {
+ case GL_UNSIGNED_SHORT:
+ if (!stride) stride = sizeof(quint16);
+ usptr = reinterpret_cast<quint16*>(rawBuffer);
+ qDebug() << c << ":u16:" << usptr[0];
+ break;
+
+ case GL_FLOAT_VEC2:
+ if (!stride) stride = sizeof(float) * 2;
+ fptr = reinterpret_cast<float*>(rawBuffer);
+ qDebug() << c << ":vec2:"<< fptr[0] << fptr[0];
+ break;
+
+ case GL_FLOAT_VEC3:
+ if (!stride) stride = sizeof(float) * 3;
+ fptr = reinterpret_cast<float*>(rawBuffer);
+ qDebug() << c << ":vec3:" << fptr[0] << fptr[0] << fptr[2];
+ break;
+
+ default: qDebug() << Q_FUNC_INFO << "unspported type:" << QString::number(type(), 16);
+ }
+
+
+ }
+}
+
+Buffer::Buffer(QOpenGLBuffer::Type ty) :
+ m_type(ty),
+ m_usage(QOpenGLBuffer::StaticDraw)
+{
+}
+
+void Buffer::setUsage(QOpenGLBuffer::UsagePattern usage)
+{
+ m_usage = usage;
+}
+
+void Buffer::setData(QByteArray bytes)
+{
+ m_clientSideBytes = bytes;
+ // mark as dirty for dynamic / stream data
+ // if static, check this is the first and only set.
+}
+
+QByteArray Buffer::data() const
+{
+ return m_clientSideBytes;
+}
+
+QOpenGLBuffer Buffer::createGL() const
+{
+ QOpenGLBuffer b(m_type);
+ b.setUsagePattern(m_usage);
+ if (!b.create())
+ qWarning() << Q_FUNC_INFO << "buffer creation failed";
+
+ if (!b.bind())
+ qWarning() << Q_FUNC_INFO << "buffer binding failed";
+
+ b.allocate(m_clientSideBytes.count());
+ b.release();
+ return b;
+}
+
+void Buffer::upload(QOpenGLBuffer b)
+{
+ if (!b.bind())
+ qWarning() << Q_FUNC_INFO << "buffer bind failed";
+ b.allocate(NULL, m_clientSideBytes.count()); // orphan the buffer
+ b.allocate(m_clientSideBytes.data(),
+ m_clientSideBytes.count());
+ b.release();
+ qDebug() << "uploaded buffer size=" << m_clientSideBytes.count();
+}
+
+} // of namespace
diff --git a/src/render/io/meshdata.h b/src/render/io/meshdata.h
new file mode 100644
index 000000000..92a9330bb
--- /dev/null
+++ b/src/render/io/meshdata.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MESHDATA_H
+#define MESHDATA_H
+
+#include <QSharedPointer>
+#include <QList>
+#include <QMap>
+#include <QOpenGLBuffer>
+#include <QVector2D>
+
+#include <axisalignedboundingbox.h>
+
+
+namespace Qt3D
+{
+
+GLint elementType(GLint type);
+GLint tupleSizeFromType(GLint type);
+GLuint byteSizeFromType(GLint type);
+
+class Buffer
+{
+public:
+ Buffer(QOpenGLBuffer::Type ty);
+
+ void setUsage(QOpenGLBuffer::UsagePattern usage);
+
+ void setData(QByteArray bytes);
+ QByteArray data() const;
+
+ QOpenGLBuffer::Type type() const
+ { return m_type; }
+
+ void bind();
+
+ QOpenGLBuffer createGL() const;
+ void upload(QOpenGLBuffer b);
+
+ // make a QObject and signal when contents change?
+ // GraphicsContext could listen, orphan the QOpenGLBuffer and hence
+ // reupload next time it's need
+private:
+ const QOpenGLBuffer::Type m_type;
+ QOpenGLBuffer::UsagePattern m_usage;
+ QByteArray m_clientSideBytes;
+};
+
+typedef QSharedPointer<Buffer> BufferPtr;
+
+class Attribute
+{
+public:
+ Attribute(BufferPtr buf, int type, int count, int offset=0, int stride = 0);
+
+ void setDivisor(unsigned int divisor);
+
+ unsigned int divisor() const
+ { return m_divisor; }
+
+ BufferPtr buffer() const;
+
+ int type() const
+ { return m_type; }
+
+ unsigned int count() const
+ { return m_count; }
+
+ unsigned int byteStride() const
+ { return m_stride; }
+
+ unsigned int byteOffset() const
+ { return m_offset; }
+
+ QVector<QVector3D> asVector3D() const;
+ QVector<QVector2D> asVector2D() const;
+
+ void dump(int count);
+private:
+ BufferPtr m_buffer;
+ int m_type, m_count;
+ unsigned int m_stride, m_offset; // both in bytes
+ // AxisAlignedBoundBox m_range;
+ unsigned int m_divisor;
+};
+
+typedef QSharedPointer<Attribute> AttributePtr;
+
+/**
+ * @brief The MeshData class is shared by all instances of a RenderMesh,
+ * and holds the actual client (CPU)-side buffers representing mesh attributes
+ * and indices.
+ */
+class MeshData
+{
+public:
+ MeshData();
+ explicit MeshData(int primitiveType);
+
+ void addAttribute(QString name, AttributePtr attr);
+
+ // permit inline 'new' call, will take ownership
+ void addAttribute(QString name, Attribute* attr);
+
+ void setIndexAttr(AttributePtr indexAttr);
+ void setIndexData(BufferPtr buf, int type, int count, int offset = 0);
+
+ GLint primitiveType() const;
+ GLsizei primitiveCount() const;
+
+ QStringList attributeNames() const;
+
+ AttributePtr attributeByName(QString nm) const;
+
+ AttributePtr indexAttr() const;
+
+ QString materialName() const;
+
+ QList<BufferPtr> buffers() const;
+
+ // specify the bounding box explicitly
+ void setBoundingBox(const AxisAlignedBoundingBox& bbox);
+
+ void computeBoundsFromAttribute(QString name);
+
+ AxisAlignedBoundingBox boundingBox() const
+ { return m_box; }
+private:
+ QMap<QString, AttributePtr> m_attributes;
+ QString m_materialName;
+
+ int m_primitiveType;
+ AttributePtr m_indexAttr;
+
+ AxisAlignedBoundingBox m_box;
+};
+
+typedef QSharedPointer<MeshData> MeshDataPtr;
+
+}
+
+#endif // MESHDATA_H
diff --git a/src/render/io/objloader.cpp b/src/render/io/objloader.cpp
new file mode 100644
index 000000000..a01aa5e2e
--- /dev/null
+++ b/src/render/io/objloader.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "objloader.h"
+
+#include "mesh.h"
+#include "axisalignedboundingbox.h"
+
+#include <QDebug>
+#include <QFile>
+#include <QOpenGLBuffer>
+#include <QOpenGLShaderProgram>
+#include <QTextStream>
+#include <QVector>
+
+namespace Qt3D {
+
+inline uint qHash(const Qt3D::FaceIndices &faceIndices)
+{
+ return faceIndices.positionIndex
+ + 10 * faceIndices.texCoordIndex
+ + 100 * faceIndices.normalIndex;
+}
+
+ObjLoader::ObjLoader()
+ : m_loadTextureCoords( true ),
+ m_generateTangents( true ),
+ m_centerMesh( false )
+{
+}
+
+bool ObjLoader::load( const QString& fileName )
+{
+ QFile file( fileName );
+ if ( !file.open( ::QIODevice::ReadOnly | ::QIODevice::Text ) )
+ {
+ qDebug() << "Could not open file" << fileName << "for reading";
+ return false;
+ }
+
+ return load( &file );
+}
+
+static void addFaceVertex(const FaceIndices &faceIndices,
+ QVector<FaceIndices> &faceIndexVector,
+ QHash<FaceIndices, unsigned int> &faceIndexMap)
+{
+ if (faceIndices.positionIndex != std::numeric_limits<unsigned int>::max()) {
+ faceIndexVector.append(faceIndices);
+ if (!faceIndexMap.contains(faceIndices))
+ faceIndexMap.insert(faceIndices, faceIndexMap.size());
+ } else {
+ qWarning( "Missing position index" );
+ }
+}
+
+bool ObjLoader::load(::QIODevice *ioDev)
+{
+ Q_CHECK_PTR(ioDev);
+ if (!ioDev->isOpen()) {
+ qWarning() << "iodevice" << ioDev << "not open for reading";
+ return false;
+ }
+
+ int faceCount = 0;
+
+ // Parse faces taking into account each vertex in a face can index different indices
+ // for the positions, normals and texture coords;
+ // Generate unique vertices (in OpenGL parlance) and output to m_points, m_texCoords,
+ // m_normals and calculate mapping from faces to unique indices
+ QVector<QVector3D> positions;
+ QVector<QVector3D> normals;
+ QVector<QVector2D> texCoords;
+ QHash<FaceIndices, unsigned int> faceIndexMap;
+ QVector<FaceIndices> faceIndexVector;
+
+ QTextStream stream(ioDev);
+ while (!stream.atEnd()) {
+ QString line = stream.readLine();
+ line = line.simplified();
+
+ if (line.length() > 0 && line.at(0) != QChar::fromLatin1('#')) {
+ QTextStream lineStream(&line, QIODevice::ReadOnly);
+ QString token;
+ lineStream >> token;
+
+ if (token == QStringLiteral("v")) {
+ float x, y, z;
+ lineStream >> x >> y >> z;
+ positions.append(QVector3D( x, y, z ));
+ } else if (token == QStringLiteral("vt") && m_loadTextureCoords) {
+ // Process texture coordinate
+ float s,t;
+ lineStream >> s >> t;
+ texCoords.append(QVector2D(s, t));
+ } else if (token == QStringLiteral("vn")) {
+ float x, y, z;
+ lineStream >> x >> y >> z;
+ normals.append(QVector3D( x, y, z ));
+ } else if (token == QStringLiteral("f")) {
+ // Process face
+ ++faceCount;
+ QVector<FaceIndices> face;
+ int faceVertices = 0;
+ while (!lineStream.atEnd()) {
+ QString faceString;
+ lineStream >> faceString;
+
+ FaceIndices faceIndices;
+ QStringList indices = faceString.split(QChar::fromLatin1('/'));
+ switch (indices.size()) {
+ case 3:
+ faceIndices.normalIndex = indices.at(2).toInt() - 1; // fall through
+ case 2:
+ faceIndices.texCoordIndex = indices.at(1).toInt() - 1; // fall through
+ case 1:
+ faceIndices.positionIndex = indices.at(0).toInt() - 1;
+ break;
+ default:
+ qWarning() << "Unsupported number of indices in face element";
+ }
+
+ face.append(faceIndices);
+ ++faceVertices;
+ }
+
+ // If number of edges in face is greater than 3,
+ // decompose into triangles as a triangle fan.
+ FaceIndices v0 = face[0];
+ FaceIndices v1 = face[1];
+ FaceIndices v2 = face[2];
+
+ // First face
+ addFaceVertex(v0, faceIndexVector, faceIndexMap);
+ addFaceVertex(v1, faceIndexVector, faceIndexMap);
+ addFaceVertex(v2, faceIndexVector, faceIndexMap);
+
+ for ( int i = 3; i < face.size(); ++i ) {
+ v1 = v2;
+ v2 = face[i];
+ addFaceVertex(v0, faceIndexVector, faceIndexMap);
+ addFaceVertex(v1, faceIndexVector, faceIndexMap);
+ addFaceVertex(v2, faceIndexVector, faceIndexMap);
+ }
+ } // end of face
+ } // end of input line
+ } // while (!stream.atEnd())
+
+ updateIndices(positions, normals, texCoords, faceIndexMap, faceIndexVector);
+
+ if (m_normals.isEmpty())
+ generateAveragedNormals(m_points, m_normals, m_indices);
+
+ if (m_generateTangents && !m_texCoords.isEmpty())
+ generateTangents(m_points, m_normals, m_indices, m_texCoords, m_tangents);
+
+ if (m_centerMesh)
+ center(m_points);
+
+//#if 0
+ qDebug() << "Loaded mesh:";
+ qDebug() << " " << m_points.size() << "points";
+ qDebug() << " " << faceCount << "faces";
+ qDebug() << " " << m_indices.size() / 3 << "triangles.";
+ qDebug() << " " << m_normals.size() << "normals";
+ qDebug() << " " << m_tangents.size() << "tangents ";
+ qDebug() << " " << m_texCoords.size() << "texture coordinates.";
+//#endif
+
+ return true;
+}
+
+MeshDataPtr ObjLoader::mesh() const
+{
+ MeshDataPtr mesh(new MeshData(GL_TRIANGLES));
+
+ QByteArray bufferBytes;
+ const int count = m_points.size();
+ quint32 elementSize = 3 + (hasTextureCoordinates() ? 2 : 0)
+ + (hasNormals() ? 3 : 0)
+ + (hasTangents() ? 4 : 0);
+ quint32 stride = elementSize * sizeof(float);
+ bufferBytes.resize(stride * count);
+ float* fptr = reinterpret_cast<float*>(bufferBytes.data());
+
+ for (int index = 0; index < count; ++index) {
+ *fptr++ = m_points.at(index).x();
+ *fptr++ = m_points.at(index).y();
+ *fptr++ = m_points.at(index).z();
+
+ if (hasTextureCoordinates()) {
+ *fptr++ = m_texCoords.at(index).x();
+ *fptr++ = m_texCoords.at(index).y();
+ }
+
+ if (hasNormals()) {
+ *fptr++ = m_normals.at(index).x();
+ *fptr++ = m_normals.at(index).y();
+ *fptr++ = m_normals.at(index).z();
+ }
+
+ if (hasTangents()) {
+ *fptr++ = m_tangents.at(index).x();
+ *fptr++ = m_tangents.at(index).y();
+ *fptr++ = m_tangents.at(index).z();
+ *fptr++ = m_tangents.at(index).w();
+ }
+ } // of buffer filling loop
+
+ BufferPtr buf(new Buffer(QOpenGLBuffer::VertexBuffer));
+ buf->setUsage(QOpenGLBuffer::StaticDraw);
+ buf->setData(bufferBytes);
+
+
+ mesh->addAttribute("position", new Attribute(buf, GL_FLOAT_VEC3, count, 0, stride));
+ quint32 offset = sizeof(float) * 3;
+
+ if (hasTextureCoordinates()) {
+ mesh->addAttribute("texcoord", new Attribute(buf, GL_FLOAT_VEC2, count, offset, stride));
+ offset += sizeof(float) * 2;
+ }
+
+ if (hasNormals()) {
+ mesh->addAttribute("normal", new Attribute(buf, GL_FLOAT_VEC3, count, offset, stride));
+ offset += sizeof(float) * 3;
+ }
+
+ if (hasTangents()) {
+ mesh->addAttribute("tangent", new Attribute(buf, GL_FLOAT_VEC4, count, offset, stride));
+ offset += sizeof(float) * 4;
+ }
+
+ QByteArray indexBytes;
+ GLuint ty;
+ if (m_indices.size() < 65536) {
+ // we can use USHORT
+ ty = GL_UNSIGNED_SHORT;
+ indexBytes.resize(m_indices.size() * sizeof(quint16));
+ quint16* usptr = reinterpret_cast<quint16*>(indexBytes.data());
+ for (int i=0; i<m_indices.size(); ++i)
+ *usptr++ = static_cast<quint16>(m_indices.at(i));
+ } else {
+ // use UINT - no conversion needed, but let's ensure int is 32-bit!
+ ty = GL_UNSIGNED_INT;
+ Q_ASSERT(sizeof(int) == sizeof(quint32));
+ indexBytes.resize(m_indices.size() * sizeof(quint32));
+ memcpy(indexBytes.data(), reinterpret_cast<const char*>(m_indices.data()), indexBytes.size());
+ }
+
+ BufferPtr indexBuffer(new Buffer(QOpenGLBuffer::IndexBuffer));
+ indexBuffer->setUsage(QOpenGLBuffer::StaticDraw);
+ indexBuffer->setData(indexBytes);
+ mesh->setIndexAttr(AttributePtr(new Attribute(indexBuffer, ty, m_indices.size(), 0, 0)));
+
+ mesh->computeBoundsFromAttribute("position");
+ qDebug() << "computed bounds is:" << mesh->boundingBox();
+
+ return mesh;
+}
+
+void ObjLoader::updateIndices(const QVector<QVector3D> &positions,
+ const QVector<QVector3D> &normals,
+ const QVector<QVector2D> &texCoords,
+ const QHash<FaceIndices, unsigned int> &faceIndexMap,
+ const QVector<FaceIndices> &faceIndexVector)
+{
+ // Iterate over the faceIndexMap and pull out pos, texCoord and normal data
+ // thereby generating unique vertices of data (by OpenGL definition)
+ const int vertexCount = faceIndexMap.size();
+ const bool hasTexCoords = !texCoords.isEmpty();
+ const bool hasNormals = !normals.isEmpty();
+
+ m_points.resize(vertexCount);
+ m_texCoords.clear();
+ if (hasTexCoords)
+ m_texCoords.resize(vertexCount);
+ m_normals.clear();
+ if (hasNormals)
+ m_normals.resize(vertexCount);
+
+ foreach (const FaceIndices &faceIndices, faceIndexMap.keys()) {
+ const int i = faceIndexMap.value(faceIndices);
+
+ m_points[i] = positions[faceIndices.positionIndex];
+ if (hasTexCoords)
+ m_texCoords[i] = texCoords[faceIndices.texCoordIndex];
+ if (hasNormals)
+ m_normals[i] = normals[faceIndices.normalIndex];
+ }
+
+ // Now iterate over the face indices and lookup the unique vertex index
+ const int indexCount = faceIndexVector.size();
+ m_indices.clear();
+ m_indices.reserve(indexCount);
+ foreach (const FaceIndices &faceIndices, faceIndexVector) {
+ const unsigned int i = faceIndexMap.value(faceIndices);
+ m_indices.append(i);
+ }
+}
+
+void ObjLoader::generateAveragedNormals( const QVector<QVector3D>& points,
+ QVector<QVector3D>& normals,
+ const QVector<unsigned int>& faces ) const
+{
+ for ( int i = 0; i < points.size(); ++i )
+ normals.append( QVector3D() );
+
+ for ( int i = 0; i < faces.size(); i += 3 )
+ {
+ const QVector3D& p1 = points[ faces[i] ];
+ const QVector3D& p2 = points[ faces[i+1] ];
+ const QVector3D& p3 = points[ faces[i+2] ];
+
+ QVector3D a = p2 - p1;
+ QVector3D b = p3 - p1;
+ QVector3D n = QVector3D::crossProduct( a, b ).normalized();
+
+ normals[ faces[i] ] += n;
+ normals[ faces[i+1] ] += n;
+ normals[ faces[i+2] ] += n;
+ }
+
+ for ( int i = 0; i < normals.size(); ++i )
+ normals[i].normalize();
+}
+
+void ObjLoader::generateTangents( const QVector<QVector3D>& points,
+ const QVector<QVector3D>& normals,
+ const QVector<unsigned int>& faces,
+ const QVector<QVector2D>& texCoords,
+ QVector<QVector4D>& tangents ) const
+{
+ tangents.clear();
+ QVector<QVector3D> tan1Accum;
+ QVector<QVector3D> tan2Accum;
+
+ for ( int i = 0; i < points.size(); i++ )
+ {
+ tan1Accum.append( QVector3D() );
+ tan2Accum.append( QVector3D() );
+ tangents.append( QVector4D() );
+ }
+
+ // Compute the tangent vector
+ for ( int i = 0; i < faces.size(); i += 3 )
+ {
+ const QVector3D& p1 = points[ faces[i] ];
+ const QVector3D& p2 = points[ faces[i+1] ];
+ const QVector3D& p3 = points[ faces[i+2] ];
+
+ const QVector2D& tc1 = texCoords[ faces[i] ];
+ const QVector2D& tc2 = texCoords[ faces[i+1] ];
+ const QVector2D& tc3 = texCoords[ faces[i+2] ];
+
+ QVector3D q1 = p2 - p1;
+ QVector3D q2 = p3 - p1;
+ float s1 = tc2.x() - tc1.x(), s2 = tc3.x() - tc1.x();
+ float t1 = tc2.y() - tc1.y(), t2 = tc3.y() - tc1.y();
+ float r = 1.0f / ( s1 * t2 - s2 * t1 );
+ QVector3D tan1( ( t2 * q1.x() - t1 * q2.x() ) * r,
+ ( t2 * q1.y() - t1 * q2.y() ) * r,
+ ( t2 * q1.z() - t1 * q2.z() ) * r );
+ QVector3D tan2( ( s1 * q2.x() - s2 * q1.x() ) * r,
+ ( s1 * q2.y() - s2 * q1.y() ) * r,
+ ( s1 * q2.z() - s2 * q1.z() ) * r );
+ tan1Accum[ faces[i] ] += tan1;
+ tan1Accum[ faces[i+1] ] += tan1;
+ tan1Accum[ faces[i+2] ] += tan1;
+ tan2Accum[ faces[i] ] += tan2;
+ tan2Accum[ faces[i+1] ] += tan2;
+ tan2Accum[ faces[i+2] ] += tan2;
+ }
+
+ for ( int i = 0; i < points.size(); ++i )
+ {
+ const QVector3D& n = normals[i];
+ QVector3D& t1 = tan1Accum[i];
+ QVector3D& t2 = tan2Accum[i];
+
+ // Gram-Schmidt orthogonalize
+ tangents[i] = QVector4D( QVector3D( t1 - QVector3D::dotProduct( n, t1 ) * n ).normalized(), 0.0f );
+
+ // Store handedness in w
+ tangents[i].setW( ( QVector3D::dotProduct( QVector3D::crossProduct( n, t1 ), t2 ) < 0.0f ) ? -1.0f : 1.0f );
+ }
+}
+
+void ObjLoader::center( QVector<QVector3D>& points )
+{
+ if ( points.isEmpty() )
+ return;
+
+ AxisAlignedBoundingBox bb(points);
+ QVector3D center = bb.center();
+
+ // Translate center of the AABB to the origin
+ for ( int i = 0; i < points.size(); ++i )
+ {
+ QVector3D& point = points[i];
+ point = point - center;
+ }
+}
+
+}
diff --git a/src/render/io/objloader.h b/src/render/io/objloader.h
new file mode 100644
index 000000000..6c7ae93c0
--- /dev/null
+++ b/src/render/io/objloader.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OBJLOADER_H
+#define OBJLOADER_H
+
+#include "meshdata.h"
+
+#include <QVector>
+#include <QVector2D>
+#include <QVector3D>
+#include <QVector4D>
+
+#include <limits>
+
+class QString;
+class QIODevice;
+
+namespace Qt3D {
+
+struct FaceIndices
+{
+ FaceIndices()
+ : positionIndex(std::numeric_limits<unsigned int>::max())
+ , texCoordIndex(std::numeric_limits<unsigned int>::max())
+ , normalIndex(std::numeric_limits<unsigned int>::max())
+ {}
+
+ FaceIndices(unsigned int posIndex, unsigned int tcIndex, unsigned int nIndex)
+ : positionIndex(posIndex)
+ , texCoordIndex(tcIndex)
+ , normalIndex(nIndex)
+ {}
+
+ bool operator == (const FaceIndices &other) const
+ {
+ return positionIndex == other.positionIndex &&
+ texCoordIndex == other.texCoordIndex &&
+ normalIndex == other.normalIndex;
+ }
+
+ unsigned int positionIndex;
+ unsigned int texCoordIndex;
+ unsigned int normalIndex;
+};
+
+class ObjLoader
+{
+public:
+ ObjLoader();
+
+ void setLoadTextureCoordinatesEnabled( bool b ) { m_loadTextureCoords = b; }
+ bool isLoadTextureCoordinatesEnabled() const { return m_loadTextureCoords; }
+
+ void setTangentGenerationEnabled( bool b ) { m_generateTangents = b; }
+ bool isTangentGenerationEnabled() const { return m_generateTangents; }
+
+ void setMeshCenteringEnabled( bool b ) { m_centerMesh = b; }
+ bool isMeshCenteringEnabled() const { return m_centerMesh; }
+
+ bool hasNormals() const { return !m_normals.isEmpty(); }
+ bool hasTextureCoordinates() const { return !m_texCoords.isEmpty(); }
+ bool hasTangents() const { return !m_tangents.isEmpty(); }
+
+ bool load( const QString& fileName );
+ bool load( ::QIODevice* ioDev );
+
+ QVector<QVector3D> vertices() const { return m_points; }
+ QVector<QVector3D> normals() const { return m_normals; }
+ QVector<QVector2D> textureCoordinates() const { return m_texCoords; }
+ QVector<QVector4D> tangents() const { return m_tangents; }
+ QVector<unsigned int> indices() const { return m_indices; }
+
+ MeshDataPtr mesh() const;
+
+private:
+ void updateIndices(const QVector<QVector3D> &positions,
+ const QVector<QVector3D> &normals,
+ const QVector<QVector2D> &texCoords,
+ const QHash<FaceIndices, unsigned int> &faceIndexMap,
+ const QVector<FaceIndices> &faceIndexVector);
+ void generateAveragedNormals( const QVector<QVector3D>& points,
+ QVector<QVector3D>& normals,
+ const QVector<unsigned int>& faces ) const;
+ void generateTangents( const QVector<QVector3D>& points,
+ const QVector<QVector3D>& normals,
+ const QVector<unsigned int>& faces,
+ const QVector<QVector2D>& texCoords,
+ QVector<QVector4D>& tangents ) const;
+ void center( QVector<QVector3D>& points );
+
+ bool m_loadTextureCoords;
+ bool m_generateTangents;
+ bool m_centerMesh;
+
+ QVector<QVector3D> m_points;
+ QVector<QVector3D> m_normals;
+ QVector<QVector2D> m_texCoords;
+ QVector<QVector4D> m_tangents;
+ QVector<unsigned int> m_indices;
+};
+
+}
+
+#endif // OBJLOADER_H
diff --git a/src/render/io/render-io.pri b/src/render/io/render-io.pri
new file mode 100644
index 000000000..18e19540f
--- /dev/null
+++ b/src/render/io/render-io.pri
@@ -0,0 +1,13 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/meshdata.h \
+ $$PWD/gltfparser.h \
+ $$PWD/objloader.h \
+ $$PWD/texturedata.h
+
+SOURCES += \
+ $$PWD/meshdata.cpp \
+ $$PWD/gltfparser.cpp \
+ $$PWD/objloader.cpp \
+ $$PWD/texturedata.cpp
diff --git a/src/render/io/texturedata.cpp b/src/render/io/texturedata.cpp
new file mode 100644
index 000000000..3a1b8aa8f
--- /dev/null
+++ b/src/render/io/texturedata.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "texturedata.h"
+
+#include <QDebug>
+#include <QOpenGLTexture>
+
+namespace Qt3D {
+
+Texture::Texture() :
+ m_target(QOpenGLTexture::Target2D),
+ m_width(1),
+ m_height(1),
+ m_depth(1),
+ m_autoMipMap(false)
+{
+}
+
+void Texture::setTarget(QOpenGLTexture::Target target)
+{
+ m_target = target;
+}
+
+void Texture::setSize(int w, int h, int d)
+{
+ m_width = w;
+ m_height = h;
+ m_depth = d;
+}
+
+int Texture::width() const
+{
+ return m_width;
+}
+
+int Texture::height() const
+{
+ return m_height;
+}
+
+int Texture::depth() const
+{
+ return m_depth;
+}
+
+void Texture::setInternalFormat(QOpenGLTexture::TextureFormat format)
+{
+ m_format = format;
+}
+
+bool Texture::setFromQImage(QImage img, int layer)
+{
+ setSize(img.width(), img.height());
+
+ if ((m_target != QOpenGLTexture::Target2D) &&
+ (m_target != QOpenGLTexture::Target2DArray) &&
+ (m_target == QOpenGLTexture::TargetRectangle))
+ {
+ qWarning() << Q_FUNC_INFO << "invalid texture target";
+ return false;
+ }
+
+ TexImageDataPtr dataPtr(new TexImageData(0, layer));
+ dataPtr->setImage(img);
+ addImageData(dataPtr);
+
+ return true;
+}
+
+void Texture::addImageData(TexImageDataPtr imgData)
+{
+ m_data.append(imgData);
+}
+
+QList<TexImageDataPtr> Texture::imageData() const
+{
+ return m_data;
+}
+
+void Texture::setGenerateMipMaps(bool gen)
+{
+ m_autoMipMap = gen;
+}
+
+void Texture::setMinificationFilter(QOpenGLTexture::Filter f)
+{
+ m_minFilter = f;
+}
+
+void Texture::setMagnificationFilter(QOpenGLTexture::Filter f)
+{
+ m_magFilter = f;
+}
+
+void Texture::setWrapMode(QOpenGLTexture::WrapMode wrapMode)
+{
+ m_wrapMode = wrapMode;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+TexImageData::TexImageData(int level, int layer) :
+ m_layer(layer),
+ m_mipMapLevel(level),
+ m_cubeFace(QOpenGLTexture::CubeMapPositiveX),
+ m_isCompressed(false)
+{
+
+}
+
+void TexImageData::setImage(QImage image)
+{
+ QImage glImage = image.convertToFormat(QImage::Format_RGBA8888);
+// setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.bits(), &uploadOptions);
+
+ QByteArray imageBytes((const char*) glImage.constBits(), glImage.byteCount());
+ setData(imageBytes, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
+}
+
+void TexImageData::setData(QByteArray data, QOpenGLTexture::PixelFormat fmt, QOpenGLTexture::PixelType ptype)
+{
+ m_isCompressed = false;
+ m_data = data;
+ m_pixelFormat = fmt;
+ m_pixelType = ptype;
+}
+
+} // namespace Qt3D
diff --git a/src/render/io/texturedata.h b/src/render/io/texturedata.h
new file mode 100644
index 000000000..6ce214c26
--- /dev/null
+++ b/src/render/io/texturedata.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QT3D_TEXTUREDATA_H
+#define QT3D_TEXTUREDATA_H
+
+#include <QOpenGLTexture>
+#include <QImage>
+#include <QSharedPointer>
+
+namespace Qt3D {
+
+class TexImageData
+{
+public:
+ TexImageData(int level, int layer);
+
+ QOpenGLTexture::CubeMapFace cubeFace() const
+ { return m_cubeFace; }
+
+ void setCubeFace(QOpenGLTexture::CubeMapFace face);
+
+ int layer() const
+ { return m_layer; }
+
+ int mipMapLevel() const
+ { return m_mipMapLevel; }
+
+ bool isCompressed() const
+ { return m_isCompressed; }
+
+ void setImage(QImage);
+
+ void setData(QByteArray data,
+ QOpenGLTexture::PixelFormat fmt,
+ QOpenGLTexture::PixelType ptype);
+ void setCompressedData(QByteArray data, QOpenGLTexture::PixelFormat fmt);
+
+ QByteArray data() const
+ { return m_data; }
+
+ QOpenGLTexture::PixelFormat pixelFormat() const
+ { return m_pixelFormat; }
+
+ QOpenGLTexture::PixelType pixelType() const
+ { return m_pixelType; }
+
+private:
+ int m_layer, m_mipMapLevel;
+ QOpenGLTexture::CubeMapFace m_cubeFace;
+ QOpenGLTexture::PixelFormat m_pixelFormat;
+ QOpenGLTexture::PixelType m_pixelType;
+
+ bool m_isCompressed;
+ QByteArray m_data;
+};
+
+typedef QSharedPointer<TexImageData> TexImageDataPtr;
+
+class Texture
+{
+public:
+ Texture();
+
+ void setTarget(QOpenGLTexture::Target target);
+
+ void setInternalFormat(QOpenGLTexture::TextureFormat format);
+
+ QOpenGLTexture::TextureFormat format() const
+ { return m_format; }
+
+ QOpenGLTexture::Target target() const
+ { return m_target; }
+
+ /**
+ * @brief setFromQImage - set size and image data based upon a QImage
+ * Can optionally generate mip-map levels automatically too. Target
+ * must be Texture2D, Texture2DArray or TextureRectangle.
+ * @param img - valid QImage. If Texture2D is set, should be power-of-2
+ * dimensions.
+ */
+ bool setFromQImage(QImage img, int layer = 0);
+
+ void addImageData(TexImageDataPtr imgData);
+ QList<TexImageDataPtr> imageData() const;
+
+ void setGenerateMipMaps(bool gen);
+ bool generateMipMaps() const
+ { return m_autoMipMap; }
+
+// sampler data - in the future proxy to a Sampler helper
+ void setMinificationFilter(QOpenGLTexture::Filter f);
+ void setMagnificationFilter(QOpenGLTexture::Filter f);
+
+ QOpenGLTexture::Filter minificationFilter() const
+ { return m_minFilter; }
+
+ QOpenGLTexture::Filter magnificationFilter() const
+ { return m_magFilter; }
+
+ void setWrapMode(QOpenGLTexture::WrapMode wrapMode);
+ QOpenGLTexture::WrapMode wrapMode() const
+ { return m_wrapMode; }
+
+ void setSize(int width, int height=1, int depth=1);
+
+ int width() const;
+ int height() const;
+ int depth() const;
+
+private:
+ QOpenGLTexture::Target m_target;
+ QOpenGLTexture::TextureFormat m_format;
+ int m_width, m_height, m_depth;
+ bool m_autoMipMap;
+
+ QList<TexImageDataPtr> m_data;
+
+ QOpenGLTexture::Filter m_minFilter, m_magFilter;
+ // FIXME, store per direction
+ QOpenGLTexture::WrapMode m_wrapMode;
+};
+
+} // namespace Qt3D
+
+#endif // QT3D_TEXTUREDATA_H
diff --git a/src/render/render.pri b/src/render/render.pri
new file mode 100644
index 000000000..ea2b93bea
--- /dev/null
+++ b/src/render/render.pri
@@ -0,0 +1,3 @@
+include(backend/render-backend.pri)
+include(frontend/render-frontend.pri)
+include(io/render-io.pri)
diff --git a/src/src.pro b/src/src.pro
index ae6a3ae90..f8b0ef3bc 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,4 +1,6 @@
TEMPLATE = subdirs
CONFIG += ordered
-SUBDIRS = threed
-qtHaveModule(qml): SUBDIRS += quick3d imports
+SUBDIRS += core
+
+#SUBDIRS += thred
+#qtHaveModule(qml): SUBDIRS += quick3d imports
diff --git a/sync.profile b/sync.profile
index 4cc2ddca0..aec8fc637 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,4 +1,5 @@
%modules = ( # path to module name map
+ "Qt3DCore" => "$basedir/src/threed",
"Qt3D" => "$basedir/src/threed",
"Qt3DQuick" => "$basedir/src/quick3d",
);