summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-10-06 11:49:09 +0000
committerOswald Buddenhagen <oswald.buddenhagen@qt.io>2017-10-06 16:58:43 +0200
commit07840524085bd1785b8f9142b03d942f678c5c51 (patch)
tree499c1674fdd1b3e0c07688d8e4e56748dfea2ca3 /examples
Initial import
Diffstat (limited to 'examples')
-rw-r--r--examples/examples.pro4
-rw-r--r--examples/studio3d/qmlbehaviors/qmlbehaviors.uia16
-rw-r--r--examples/studio3d/qmlbehaviors/qmlbehaviors.uip93
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/Billboard.qml182
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/CatchEvents.qml66
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/DateTime.qml60
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/Keyboard.qml199
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/SineWave.qml124
-rw-r--r--examples/studio3d/qmlbehaviors/scripts/Toggle.qml117
-rw-r--r--examples/studio3d/qmldynamickeyframes/main.cpp91
-rw-r--r--examples/studio3d/qmldynamickeyframes/presentation/dyn_key.uip95
-rw-r--r--examples/studio3d/qmldynamickeyframes/qml/qmldynamickeyframes/main.qml217
-rw-r--r--examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.pro19
-rw-r--r--examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.qrc6
-rw-r--r--examples/studio3d/qmlstreamer/main.cpp89
-rw-r--r--examples/studio3d/qmlstreamer/presentation/images/dummy.pngbin0 -> 1858 bytes
-rw-r--r--examples/studio3d/qmlstreamer/presentation/rotating_cube.uia7
-rw-r--r--examples/studio3d/qmlstreamer/presentation/rotating_cube.uip41
-rw-r--r--examples/studio3d/qmlstreamer/presentation/scripts/RedFill.qml80
-rw-r--r--examples/studio3d/qmlstreamer/qml/qmlstreamer/main.qml84
-rw-r--r--examples/studio3d/qmlstreamer/qmlstreamer.pro19
-rw-r--r--examples/studio3d/qmlstreamer/qmlstreamer.qrc9
-rw-r--r--examples/studio3d/studio3d.pro10
-rw-r--r--examples/studio3d/surfaceviewer/main.cpp101
-rw-r--r--examples/studio3d/surfaceviewer/presentation/circling_cube.uip72
-rw-r--r--examples/studio3d/surfaceviewer/presentation/fonts/TitilliumWeb-Regular.ttfbin0 -> 63752 bytes
-rw-r--r--examples/studio3d/surfaceviewer/surfaceviewer.pro13
-rw-r--r--examples/studio3d/surfaceviewer/surfaceviewer.qrc5
-rw-r--r--examples/studio3d/surfaceviewer_offscreen/main.cpp127
-rw-r--r--examples/studio3d/surfaceviewer_offscreen/presentation/circling_cube.uip70
-rw-r--r--examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.pro13
-rw-r--r--examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.qrc5
-rw-r--r--examples/studio3d/widgetviewer/main.cpp81
-rw-r--r--examples/studio3d/widgetviewer/mainwindow.cpp338
-rw-r--r--examples/studio3d/widgetviewer/mainwindow.h106
-rw-r--r--examples/studio3d/widgetviewer/mainwindow.ui201
-rw-r--r--examples/studio3d/widgetviewer/resources/style/checkbox.pngbin0 -> 343 bytes
-rw-r--r--examples/studio3d/widgetviewer/resources/style/dark.qss450
-rw-r--r--examples/studio3d/widgetviewer/resources/style/down_arrow.pngbin0 -> 1008 bytes
-rw-r--r--examples/studio3d/widgetviewer/resources/style/handle.pngbin0 -> 2837 bytes
-rw-r--r--examples/studio3d/widgetviewer/widgetviewer.pro14
-rw-r--r--examples/studio3d/widgetviewer/widgetviewer.qrc8
42 files changed, 3232 insertions, 0 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
new file mode 100644
index 00000000..21a33d48
--- /dev/null
+++ b/examples/examples.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+
+SUBDIRS += \
+ studio3d
diff --git a/examples/studio3d/qmlbehaviors/qmlbehaviors.uia b/examples/studio3d/qmlbehaviors/qmlbehaviors.uia
new file mode 100644
index 00000000..1f0bb850
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/qmlbehaviors.uia
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<application xmlns="http://qt.io/qt3dstudio/uia">
+ <assets initial="qmlbehaviors">
+ <presentation id="qmlbehaviors" src="qmlbehaviors.uip"/>
+ </assets>
+
+ <statemachine ref="#logic">
+ <visual-states>
+ <state ref="Initial">
+ <enter>
+ <goto-slide element="main:Scene" rel="next"/>
+ </enter>
+ </state>
+ </visual-states>
+ </statemachine>
+</application>
diff --git a/examples/studio3d/qmlbehaviors/qmlbehaviors.uip b/examples/studio3d/qmlbehaviors/qmlbehaviors.uip
new file mode 100644
index 00000000..2653fc03
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/qmlbehaviors.uip
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="3" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" />
+ <Classes >
+ <Behavior id="Billboard" name="Billboard" sourcepath="scripts\Billboard.qml" />
+ <Behavior id="CatchEvents" name="CatchEvents" sourcepath="scripts\CatchEvents.qml" />
+ <Behavior id="Keyboard" name="Keyboard" sourcepath="scripts\Keyboard.qml" />
+ <Behavior id="SineWave" name="SineWave" sourcepath="scripts\SineWave.qml" />
+ <Behavior id="Toggle" name="Toggle" sourcepath="scripts\Toggle.qml" />
+ </Classes>
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" >
+ <Behavior id="Billboard_002" class="#Billboard" />
+ </Camera>
+ <Light id="Light" />
+ <Model id="Cube2" >
+ <Material id="Material_001" />
+ <Behavior id="SineWave_001" class="#SineWave" />
+ <Model id="Cube" >
+ <Material id="Material" />
+ <Behavior id="Billboard_001" class="#Billboard" />
+ </Model>
+ </Model>
+ <Model id="Sphere" >
+ <Material id="Material_002" />
+ </Model>
+ <Model id="Rectangle" >
+ <Material id="Material_003" />
+ <Behavior id="Toggle_001" class="#Toggle" />
+ </Model>
+ </Layer>
+ <Behavior id="CatchEvents_001" class="#CatchEvents" />
+ <Behavior id="Keyboard_001" class="#Keyboard" />
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" />
+ <Add ref="#Camera" />
+ <Add ref="#Light" lightambient="0.333333 0 0" lighttype="Directional" rotation="29 36 0" />
+ <State id="Scene-Slide1" name="Slide1" playmode="PingPong" >
+ <Add ref="#Billboard_002" name="Billboard" renderCamera="#Cube2" />
+ <Add ref="#Cube2" name="Cube2" position="-410.66 -269.615 131.722" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -410.66 100 100 3.706 514.024 100 100 6.958 -17.5718 100 100 10 -531.565 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 -246.021 100 100 3.706 -141.615 100 100 6.958 394.782 100 100 10 -154.656 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 131.722 100 100 3.706 131.722 100 100 6.958 131.722 100 100 10 131.722 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.x" type="EaseInOut" />
+ <AnimationTrack property="rotation.y" type="EaseInOut" />
+ <AnimationTrack property="rotation.z" type="EaseInOut" />
+ <Action id="Cube2-Action" eyeball="True" triggerObject="#Cube2" event="onPressureDown" targetObject="#SineWave_001" handler="toggle" />
+ </Add>
+ <Add ref="#Material_001" />
+ <Add ref="#SineWave_001" name="SineWave" ampOffset="0" amplitude="45" />
+ <Add ref="#Cube" name="Cube" position="-531.565 -276.656 131.722" scale="1 1 1" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 113.361 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 100 100</AnimationTrack>
+ </Add>
+ <Add ref="#Material" name="Material" />
+ <Add ref="#Billboard_001" name="Billboard" billboardType="Face Camera" renderCamera="#Camera" startImmediately="True" yOnly="False" />
+ <Add ref="#Sphere" name="Sphere" position="191.969 4.33009 0" sourcepath="#Sphere" />
+ <Add ref="#Material_002" />
+ <Add ref="#Rectangle" name="Rectangle" position="56.2916 1.44336 0" sourcepath="#Rectangle" />
+ <Add ref="#Material_003" />
+ <Add ref="#Toggle_001" name="Toggle" >
+ <Action id="Toggle-Action" eyeball="True" triggerObject="#Toggle_001" event="onToggle" targetObject="#Material_002" handler="Set Property" >
+ <HandlerArgument name="Property Name" type="String" argtype="Property" value="diffuse" />
+ <HandlerArgument name="Property Value" type="Float3" argtype="Dependent" value="0 0 1" />
+ </Action>
+ <Action id="Toggle-Action_001" eyeball="True" triggerObject="#Toggle_001" event="onUntoggle" targetObject="#Material_002" handler="Set Property" >
+ <HandlerArgument name="Property Name" type="String" argtype="Property" value="diffuse" />
+ <HandlerArgument name="Property Value" type="Float3" argtype="Dependent" value="1 1 1" />
+ </Action>
+ </Add>
+ <Add ref="#CatchEvents_001" name="CatchEvents" />
+ <Add ref="#Keyboard_001" name="Keyboard" >
+ <Action id="Keyboard-Action" eyeball="True" triggerObject="#Keyboard_001" event="onLEFTDown" targetObject="#Sphere" handler="Set Property" >
+ <HandlerArgument name="Property Name" type="String" argtype="Property" value="scale" />
+ <HandlerArgument name="Property Value" type="Float3" argtype="Dependent" value="2 2 2" />
+ </Action>
+ <Action id="Keyboard-Action_001" eyeball="True" triggerObject="#Keyboard_001" event="onLEFTUp" targetObject="#Sphere" handler="Set Property" >
+ <HandlerArgument name="Property Name" type="String" argtype="Property" value="scale" />
+ <HandlerArgument name="Property Value" type="Float3" argtype="Dependent" value="1 1 1" />
+ </Action>
+ </Add>
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/studio3d/qmlbehaviors/scripts/Billboard.qml b/examples/studio3d/qmlbehaviors/scripts/Billboard.qml
new file mode 100644
index 00000000..de4ae3f5
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/Billboard.qml
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*[[
+ <Property name="renderCamera" formalName="Render Camera" type="ObjectRef" default="Scene.Layer.Camera" description="The camera which will be rendering the scene." />
+ <Property name="billboardType" formalName="Billboard Type" type="StringList" default="Face Camera" list="Face Camera,Match Camera Rotation" description="Always face the camera, or only match its rotation." />
+ <Property name="yOnly" formalName="Y-Axis Only?" type="Boolean" default="False" description="Only rotate the object about the global y-axis?" />
+ <Property name="startImmediately" formalName="Start Immediately?" type="Boolean" default="True" publishLevel="Advanced" description="Start immediately, or wait for the Enable action to be called?" />
+
+ <Handler name="start" formalName="Start" category="Billboard" description="Begin keeping the parent object billboarded." />
+ <Handler name="stop" formalName="Stop" category="Billboard" description="Stop rotating the parent object." />
+]]*/
+
+import QtQml 2.2
+
+QtObject {
+ //External:
+ property string renderCamera
+ property string billboardType
+ property bool yOnly
+ property bool startImmediately
+ //Internal:
+ property bool running: false
+ property var updateFunction
+
+ function start() {
+ running = true;
+ }
+
+ function stop() {
+ running = false;
+ }
+
+ function onInitialize() {
+ if (billboardType === "Face Camera") {
+ if (!yOnly)
+ updateFunction = faceCamera;
+ else
+ updateFunction = faceCameraGlobalY;
+ }
+ else {
+ if (!yOnly)
+ updateFunction = matchRotation;
+ else
+ updateFunction = matchRotationGlobalY;
+ }
+
+ if (startImmediately)
+ start();
+ }
+
+ function onUpdate() {
+ if (!running)
+ return;
+
+ updateFunction();
+ }
+
+ function faceCamera() {
+ var cameraTransform = Qt3ds.calculateGlobalTransform(renderCamera);
+ var cameraSpot = cameraTransform.row(3).toVector3d();
+ var myTransform = Qt3ds.calculateGlobalTransform();
+ var mySpot = myTransform.row(3).toVector3d();
+
+ var matrix = Qt3ds.calculateGlobalTransform(Qt3ds.getParent()).inverted();
+ matrix.m41 = 0;
+ matrix.m42 = 0;
+ matrix.m43 = 0;
+
+ var rotateRay = cameraSpot
+ .minus(mySpot)
+ .times(matrix);
+
+ var rotation = Qt3ds.lookAt(rotateRay);
+ setAttributeVector("rotation", rotation);
+ }
+
+ function faceCameraGlobalY() {
+ var cameraTransform = Qt3ds.calculateGlobalTransform(renderCamera);
+ var cameraSpot = cameraTransform.row(3).toVector3d();
+ var myTransform = Qt3ds.calculateGlobalTransform();
+ var mySpot = myTransform.row(3).toVector3d();
+
+ var rotateRay = cameraSpot.minus(mySpot);
+
+ var rotation = getAttributeVector("rotation");
+ rotation.y = Math.atan2(rotateRay.x, rotateRay.z);
+ setAttributeVector("rotation", rotation);
+ }
+
+ function matchRotation() {
+ var cameraTransform = Qt3ds.calculateGlobalTransform(renderCamera);
+ var cameraSpot = cameraTransform.row(3).toVector3d();
+
+ var matrix = Qt3ds.calculateGlobalTransform(Qt3ds.getParent()).inverted();
+ matrix.m41 = 0;
+ matrix.m42 = 0;
+ matrix.m43 = 0;
+
+ var rotateRay = Qt.vector3d(0, 0, 1)
+ .times(cameraTransform)
+ .minus(cameraSpot)
+ .times(matrix);
+
+ var rotation = Qt3ds.lookAt(rotateRay);
+ setAttributeVector("rotation", rotation);
+ }
+
+ function matchRotationGlobalY() {
+ var cameraTransform = Qt3ds.calculateGlobalTransform(renderCamera);
+ var cameraSpot = cameraTransform.row(3).toVector3d();
+
+ var rotateRay = Qt.vector3d(0, 0, 1)
+ .times(cameraTransform)
+ .minus(cameraSpot)
+
+ var rotation = getAttributeVector("rotation");
+ rotation.y = Qt3ds.lookAt(rotateRay).y;
+ setAttributeVector("rotation", rotation);
+ }
+
+ function getAttributeVector(name) {
+ var vec = Qt.vector3d(0, 0, 0);
+ Qt3ds.getAttribute(name + ".x", vec.x);
+ Qt3ds.getAttribute(name + ".y", vec.y);
+ Qt3ds.getAttribute(name + ".z", vec.z);
+ return vec;
+ }
+
+ function setAttributeVector(name, vec) {
+ Qt3ds.setAttribute(name + ".x", vec.x);
+ Qt3ds.setAttribute(name + ".y", vec.y);
+ Qt3ds.setAttribute(name + ".z", vec.z);
+ }
+}
diff --git a/examples/studio3d/qmlbehaviors/scripts/CatchEvents.qml b/examples/studio3d/qmlbehaviors/scripts/CatchEvents.qml
new file mode 100644
index 00000000..f5b14a80
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/CatchEvents.qml
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.2
+
+QtObject {
+ function onInitialize() {
+ Qt3ds.registerForEvent("onPressureDown", onMouseDown);
+ Qt3ds.registerForEvent("onPressureUp", onMouseUp);
+ }
+
+ function onMouseDown() {
+ console.log("Mouse down!");
+ }
+
+ function onMouseUp() {
+ console.log("Mouse up!");
+ }
+}
diff --git a/examples/studio3d/qmlbehaviors/scripts/DateTime.qml b/examples/studio3d/qmlbehaviors/scripts/DateTime.qml
new file mode 100644
index 00000000..79773dc5
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/DateTime.qml
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQml 2.2
+
+QtObject {
+ function onUpdate() {
+ var date = new Date();
+ var timeString = date.getDate() + "/" + (date.getMonth()+1) + "/" + date.getFullYear()
+ + " " + date.getHours() + ":" + date.getMinutes() + "." + date.getSeconds();
+ Qt3ds.setAttribute("textstring", timeString);
+ }
+}
diff --git a/examples/studio3d/qmlbehaviors/scripts/Keyboard.qml b/examples/studio3d/qmlbehaviors/scripts/Keyboard.qml
new file mode 100644
index 00000000..9a1d86f1
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/Keyboard.qml
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*[[
+<Event name="onLEFTDown" category="Navigation" />
+<Event name="onLEFTUp" category="Navigation" />
+<Event name="onRIGHTDown" category="Navigation" />
+<Event name="onRIGHTUp" category="Navigation" />
+<Event name="onUPDown" category="Navigation" />
+<Event name="onUPUp" category="Navigation" />
+<Event name="onDOWNDown" category="Navigation" />
+<Event name="onDOWNUp" category="Navigation" />
+]]*/
+
+import QtQml 2.2
+
+QtObject {
+ property var keyNames: ["NOKEY",
+ "ESCAPE",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "0",
+ "SUBTRACT",
+ "EQUALS",
+ "BACK",
+ "TAB",
+ "Q",
+ "W",
+ "E",
+ "R",
+ "T",
+ "Y",
+ "U",
+ "I",
+ "O",
+ "P",
+ "LBRACKET",
+ "RBRACKET",
+ "RETURN",
+ "LCONTROL",
+ "A",
+ "S",
+ "D",
+ "F",
+ "G",
+ "H",
+ "J",
+ "K",
+ "L",
+ "SEMICOLON",
+ "APOSTROPHE",
+ "GRAVE",
+ "LSHIFT",
+ "BACKSLASH",
+ "Z",
+ "X",
+ "C",
+ "V",
+ "B",
+ "N",
+ "M",
+ "COMMA",
+ "PERIOD",
+ "SLASH",
+ "RSHIFT",
+ "MULTIPLY",
+ "LALT",
+ "SPACE",
+ "CAPITAL",
+ "F1",
+ "F2", // 60
+ "F3",
+ "F4",
+ "F5",
+ "F6",
+ "F7",
+ "F8",
+ "F9",
+ "F10",
+ "NUMLOCK",
+ "SCROLL", // 70
+ "NUMPAD7",
+ "NUMPAD8",
+ "NUMPAD9",
+ "NUMPADSUBTRACT",
+ "NUMPAD4",
+ "NUMPAD5",
+ "NUMPAD6",
+ "NUMPADADD",
+ "NUMPAD1",
+ "NUMPAD2", // 80
+ "NUMPAD3",
+ "NUMPAD0",
+ "NUMPADDECIMAL",
+ "NOOP",
+ "ZENKAKUHANKAKU",
+ "102ND",
+ "F11",
+ "F12",
+ "F13",
+ "F14", // 90
+ "HIRAGANA",
+ "HENKAN",
+ "KATAKANAHIRAGANA",
+ "MUHENKAN",
+ "KPJPCOMMA",
+ "NUMPADENTER",
+ "RCONTROL",
+ "NUMPADDIVIDE",
+ "PRINTSCREEN",
+ "RALT", // 100
+ "LINEFEED",
+ "HOME",
+ "UP",
+ "PGUP",
+ "LEFT",
+ "RIGHT",
+ "END",
+ "DOWN",
+ "PGDN",
+ "INSERT", // 110
+ "DELETE",
+ "MACRO",
+ "MUTE",
+ "VOLUMEDOWN",
+ "VOLUMEUP",
+ "POWER",
+ "KPEQUAL",
+ "KPPLUSMINUS",
+ "PAUSE",
+ "SCALE"]
+
+ function onInitialize() {
+ Qt3ds.registerForEvent("onKeyDown", onKeyDown);
+ Qt3ds.registerForEvent("onKeyUp", onKeyUp);
+ }
+
+ function onKeyDown(keyCode) {
+ Qt3ds.fireEvent("on" + keyNames[keyCode] + "Down");
+ }
+
+ function onKeyUp(keyCode) {
+ Qt3ds.fireEvent("on" + keyNames[keyCode] + "Up");
+ }
+}
diff --git a/examples/studio3d/qmlbehaviors/scripts/SineWave.qml b/examples/studio3d/qmlbehaviors/scripts/SineWave.qml
new file mode 100644
index 00000000..4aa9daf7
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/SineWave.qml
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*[[
+ <Property name="attribute" formalName="Attribute Name" description="Attribute on the parent element to change." animatable="False" type="String" default="rotation.x" />
+ <Property name="ampOffset" formalName="Center Value" description="Value to center around." animatable="False" type="Float" default="0" />
+ <Property name="amplitude" formalName="Amplitude" description="Maximum value added to/subtracted from the center." animatable="True" type="Float" default="50" />
+ <Property name="period" formalName="Period" description="Number of seconds to complete one full cycle." animatable="False" type="Float" default="5" />
+ <Property name="timeOffset" formalName="Start Time Offset" description="Start the sine wave at a different point." animatable="False" type="Float" default="0" />
+ <Property name="startImmediately" formalName="Start Immediately?" description="Start immediately or wait for the Start action to be called?" animatable="False" type="Boolean" default="True" />
+
+ <Handler name="start" formalName="Start" description="Start the Sine Wave control of the property." />
+ <Handler name="stop" formalName="Stop" description="Stop the Sine Wave control of the property." />
+ <Handler name="toggle" formalName="Toggle" description="If the behavior is running, stop it; otherwise, start it." />
+
+ <Event name="onStarted" description="Fires when the Sine Wave is started." />
+ <Event name="onStopped" description="Fires when the Sine Wave is stopped." />
+]]*/
+
+import QtQml 2.2
+
+QtObject {
+ //External:
+ property string attribute
+ property real ampOffset
+ property real amplitude
+ property real period
+ property real timeOffset
+ property bool startImmediately
+ //Internal:
+ property bool running: false
+ property bool inDegrees: false
+ property real elapsedTime: 0
+
+ function start() {
+ if (!running) {
+ running = true;
+ Qt3ds.fireEvent("onStarted");
+ }
+ }
+
+ function stop() {
+ if (running) {
+ running = false;
+ Qt3ds.fireEvent("onStopped");
+ }
+ }
+
+ function toggle() {
+ if (running)
+ stop();
+ else
+ start();
+ }
+
+ function onInitialize() {
+ if (attribute.indexOf("rotation") != -1)
+ inDegrees = true;
+
+ if (startImmediately)
+ start();
+ }
+
+ function onUpdate() {
+ if (!running)
+ return;
+
+ if (inDegrees) {
+ ampOffset *= (Math.PI / 180);
+ amplitude *= (Math.PI / 180);
+ }
+
+ elapsedTime += Qt3ds.getDeltaTime();
+ var value = ampOffset + amplitude * Math.cos(elapsedTime * Math.PI * 2 / period);
+ Qt3ds.setAttribute(attribute, value);
+ }
+}
diff --git a/examples/studio3d/qmlbehaviors/scripts/Toggle.qml b/examples/studio3d/qmlbehaviors/scripts/Toggle.qml
new file mode 100644
index 00000000..aa71f264
--- /dev/null
+++ b/examples/studio3d/qmlbehaviors/scripts/Toggle.qml
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*[[
+ <Property name="attribute" formalName="Attribute Name" description="Attribute on the parent element to change." animatable="False" type="String" default="rotation.x" />
+ <Property name="firstValue" formalName="First Value" description="Value when not toggled." animatable="False" type="Float" default="0" />
+ <Property name="secondValue" formalName="Second Value" description="Value when toggled." animatable="False" type="Float" default="1" />
+ <Property name="timerInterval" formalName="Timer Interval" description="Interval for the toggles." animatable="False" type="Float" default="500" />
+ <Property name="startImmediately" formalName="Start Immediately?" description="Start immediately or wait for the Start action to be called?" animatable="False" type="Boolean" default="True" />
+
+ <Handler name="start" formalName="Start" description="Start the toggling." />
+ <Handler name="stop" formalName="Stop" description="Stop the toggling." />
+
+ <Event name="onToggle" description="Fires when toggled." />
+ <Event name="onUntoggle" description="Fires when untoggled." />
+]]*/
+
+import QtQml 2.2
+
+QtObject {
+ //External:
+ property string attribute
+ property real firstValue
+ property real secondValue
+ property real timerInterval
+ property bool startImmediately
+ //Internal:
+ property int index: 0
+ property bool running: false
+ property real timer: 0
+
+ function start() {
+ running = true;
+ Qt3ds.setAttribute(attribute, firstValue);
+ }
+
+ function stop() {
+ running = false;
+ }
+
+ function toggle() {
+ if (index == 0) {
+ Qt3ds.setAttribute(attribute, secondValue);
+ Qt3ds.fireEvent("onToggle");
+ } else if (index == 1) {
+ Qt3ds.setAttribute(attribute, firstValue);
+ Qt3ds.fireEvent("onUntoggle");
+ }
+ index++;
+ if (index > 1)
+ index = 0;
+ }
+
+ function onInitialize() {
+ if (startImmediately)
+ start();
+ }
+
+ function onUpdate() {
+ if (!running)
+ return;
+
+ timer += Qt3ds.getDeltaTime();
+ var interval = timerInterval / 1000;
+ while (timer >= interval) {
+ timer -= interval;
+ toggle();
+ }
+ }
+}
diff --git a/examples/studio3d/qmldynamickeyframes/main.cpp b/examples/studio3d/qmldynamickeyframes/main.cpp
new file mode 100644
index 00000000..adddbdce
--- /dev/null
+++ b/examples/studio3d/qmldynamickeyframes/main.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtCore/QDir>
+#include <QtQuick/QQuickView>
+#include <QtQml/QQmlEngine>
+#include <QtCore/QLoggingCategory>
+
+#ifdef USE_EMBEDDED_FONTS
+#include <QtGui/QFontDatabase>
+#include <QtCore/QDebug>
+#endif
+
+int main(int argc, char *argv[])
+{
+#ifdef USE_EMBEDDED_FONTS
+ qputenv("QT_QPA_FONTDIR",".");
+#endif
+
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+#ifdef USE_EMBEDDED_FONTS
+ int fontId = QFontDatabase::addApplicationFont(":/res/Font/TitilliumWeb-Regular.ttf");
+ QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(fontId);
+ if (!loadedFontFamilies.empty()) {
+ QString fontName = loadedFontFamilies.at(0);
+ QGuiApplication::setFont(QFont(fontName));
+ } else {
+ qWarning("Error: failed to load font");
+ }
+#endif
+
+ QQuickView viewer;
+
+ viewer.setSource(QUrl("qrc:/main.qml"));
+
+ viewer.setTitle(QStringLiteral("Qt 3D Studio Dynamic Keyframes Example"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/studio3d/qmldynamickeyframes/presentation/dyn_key.uip b/examples/studio3d/qmldynamickeyframes/presentation/dyn_key.uip
new file mode 100644
index 00000000..30696019
--- /dev/null
+++ b/examples/studio3d/qmldynamickeyframes/presentation/dyn_key.uip
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="3" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" />
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" />
+ <Light id="Light" />
+ <Model id="Sphere" >
+ <Material id="Material" />
+ </Model>
+ <Model id="Rectangle" >
+ <Material id="Material_001" />
+ </Model>
+ <Model id="Rectangle2" >
+ <Material id="Material_002" />
+ </Model>
+ <Model id="Rectangle3" >
+ <Material id="Material_003" />
+ </Model>
+ <Model id="Rectangle4" >
+ <Material id="Material_004" />
+ </Model>
+ <Model id="Rectangle5" >
+ <Material id="Material_005" />
+ </Model>
+ <Model id="Rectangle6" >
+ <Material id="Material_006" />
+ </Model>
+ </Layer>
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" endtime="2000" />
+ <Add ref="#Camera" endtime="2000" />
+ <Add ref="#Light" endtime="2000" />
+ <Add ref="#Sphere" name="Sphere" endtime="2000" position="-300 0 0" scale="1 1 1" sourcepath="#Sphere" />
+ <Add ref="#Material" />
+ <State id="Scene-Ball_PingPong" name="Ball_PingPong" playmode="PingPong" >
+ <Set ref="#Layer" endtime="2000" />
+ <Set ref="#Camera" endtime="2000" />
+ <Set ref="#Light" endtime="2000" />
+ <Set ref="#Sphere" endtime="2000" position="-282 0 0" scale="1 1 1" >
+ <AnimationTrack property="position.x" type="EaseInOut" dynamic="True" >0 -300 100 100 2 300 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" dynamic="True" >0 0 100 100 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" dynamic="True" >0 0 100 100 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="scale.x" type="EaseInOut" dynamic="True" >0 1 100 100 2 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.y" type="EaseInOut" dynamic="True" >0 1.001 100 100 2 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.z" type="EaseInOut" dynamic="True" >0 1 100 100 2 1 100 100</AnimationTrack>
+ </Set>
+ <Add ref="#Rectangle" name="Rectangle" endtime="2000" position="-550 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_001" />
+ </State>
+ <State id="Scene-Ball_ToCenter+Scale" name="Ball_ToCenter+Scale" playmode="PingPong" playthroughto="Previous" >
+ <Set ref="#Layer" endtime="2000" />
+ <Set ref="#Camera" endtime="2000" />
+ <Set ref="#Light" endtime="2000" />
+ <Set ref="#Sphere" endtime="2000" position="-300 0 0" scale="1 1 1" >
+ <AnimationTrack property="position.x" type="EaseInOut" dynamic="True" >0 -300 0 0 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" dynamic="True" >0 0 0 0 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" dynamic="True" >0 0 0 0 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="scale.x" type="EaseInOut" dynamic="True" >0 1 0 0 2 3 100 100</AnimationTrack>
+ <AnimationTrack property="scale.y" type="EaseInOut" dynamic="True" >0 1 0 0 2 3 100 100</AnimationTrack>
+ <AnimationTrack property="scale.z" type="EaseInOut" dynamic="True" >0 1 0 0 2 3 100 100</AnimationTrack>
+ </Set>
+ <Add ref="#Rectangle2" name="Rectangle2" endtime="2000" position="-550 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_002" />
+ <Add ref="#Rectangle3" name="Rectangle3" endtime="2000" position="-530 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_003" />
+ </State>
+ <State id="Scene-Ball_ToStart+Scale" name="Ball_ToStart+Scale" playmode="PingPong" playthroughto="#Scene-Ball_PingPong" >
+ <Set ref="#Layer" endtime="2000" />
+ <Set ref="#Camera" endtime="2000" />
+ <Set ref="#Light" endtime="2000" />
+ <Set ref="#Sphere" endtime="2000" position="-300 0 0" scale="1 1 1" >
+ <AnimationTrack property="position.x" type="EaseInOut" dynamic="True" >0 363.953 100 100 2 -300 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" dynamic="True" >0 0 100 100 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" dynamic="True" >0 0 100 100 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="scale.x" type="EaseInOut" dynamic="True" >0 1 100 100 2 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.y" type="EaseInOut" dynamic="True" >0 1.1 100 100 2 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.z" type="EaseInOut" dynamic="True" >0 1 100 100 2 1 100 100</AnimationTrack>
+ </Set>
+ <Add ref="#Rectangle4" name="Rectangle4" endtime="2000" position="-550 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_004" />
+ <Add ref="#Rectangle5" name="Rectangle5" endtime="2000" position="-530 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_005" />
+ <Add ref="#Rectangle6" name="Rectangle6" endtime="2000" position="-510 -320.429 0" scale="0.1 0.1 0.1" sourcepath="#Rectangle" />
+ <Add ref="#Material_006" />
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/studio3d/qmldynamickeyframes/qml/qmldynamickeyframes/main.qml b/examples/studio3d/qmldynamickeyframes/qml/qmldynamickeyframes/main.qml
new file mode 100644
index 00000000..002d0d84
--- /dev/null
+++ b/examples/studio3d/qmldynamickeyframes/qml/qmldynamickeyframes/main.qml
@@ -0,0 +1,217 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtStudio3D 1.0
+
+Item {
+ id: mainview
+ width: 1280
+ height: 768
+ visible: true
+
+ // Qt 3D Studio element
+ //
+ // The presentation displayed in this example consists of three simple slides with ping-pong
+ // animations:
+ //
+ // Slide 1: Move ball to the right side of the screen
+ // Slide 2: Move ball to center of the screen and scale it up
+ // Slide 3: Move ball back to the initial position on the left side of the screen
+ //
+ // Because the animations in the presentation are defined dynamic, the current position
+ // and scale of the ball are used as the initial keyframes for animations whenever
+ // a slide is changed.
+ Studio3D {
+ id: studio3D
+ anchors.fill: parent
+
+ // ViewerSettings item is used to specify presentation independent viewer settings.
+ ViewerSettings {
+ scaleMode: ViewerSettings.ScaleModeFill
+ showRenderStats: false
+ }
+
+ // Presentation item is used to control the presentation.
+ Presentation {
+ source: "qrc:/presentation/dyn_key.uip"
+
+ // SceneElement item is used to listen for slide changes of a scene in the presentation.
+ // You can also change the slides via its properties.
+ SceneElement {
+ id: scene
+ elementPath: "Scene"
+ onCurrentSlideIndexChanged: {
+ console.log("Current slide : " + currentSlideIndex + " ("
+ + currentSlideName + ")");
+ }
+ onPreviousSlideIndexChanged: {
+ console.log("Previous slide: " + previousSlideIndex + " ("
+ + previousSlideName + ")");
+ }
+ }
+
+ // Element item is used to change element attributes
+ Element {
+ id: materialElement
+ elementPath: "Scene.Layer.Sphere.Material"
+ }
+
+ property int desiredSlideIndex: 1
+ property int colorIndex: 0
+ property var colorArray: [
+ [1.0, 1.0, 1.0],
+ [1.0, 0.0, 0.0],
+ [0.0, 1.0, 0.0],
+ [0.0, 0.0, 1.0],
+ [0.0, 1.0, 1.0],
+ [1.0, 0.0, 1.0],
+ [1.0, 1.0, 0.0]
+ ]
+
+ function nextSlide() {
+ // Separate desiredSlideIndex variable is used to keep track of the desired slide,
+ // because SceneElement's currentSlideIndex property works asynchronously.
+ // This way the button click always changes the slide even if you click
+ // it twice during the same frame.
+ desiredSlideIndex = desiredSlideIndex != 3 ? desiredSlideIndex + 1 : 1;
+ scene.currentSlideIndex = desiredSlideIndex
+ slideButtonText.text = "Change Slide (" + desiredSlideIndex + ")"
+ }
+
+ function resetTime() {
+ scene.goToTime(0);
+ }
+
+ function changeColor() {
+ colorIndex = colorIndex >= colorArray.length - 1 ? colorIndex = 0 : colorIndex + 1;
+ materialElement.setAttribute("diffuse.r", colorArray[colorIndex][0]);
+ materialElement.setAttribute("diffuse.g", colorArray[colorIndex][1]);
+ materialElement.setAttribute("diffuse.b", colorArray[colorIndex][2]);
+ changeColorButton.color = Qt.rgba(colorArray[colorIndex][0],
+ colorArray[colorIndex][1],
+ colorArray[colorIndex][2], 1.0);
+ }
+ }
+ onRunningChanged: console.log("Presentation running")
+ }
+
+ // Some buttons to control the scene
+ Rectangle {
+ id: slideButton
+ anchors.left: parent.left
+ anchors.top: parent.top
+ width: 200
+ height: 50
+ border.color: "red"
+ border.width: 3
+ color: "white"
+ Text {
+ id: slideButtonText
+ anchors.fill: parent
+ text: "Change Slide (1)"
+ font.pointSize: 16
+ verticalAlignment: Qt.AlignVCenter
+ horizontalAlignment: Qt.AlignHCenter
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ studio3D.presentation.nextSlide();
+ }
+ }
+ }
+ Rectangle {
+ id: resetTimeButton
+ anchors.left: parent.left
+ anchors.top: slideButton.bottom
+ width: 200
+ height: 50
+ border.color: "red"
+ border.width: 3
+ color: "white"
+ Text {
+ anchors.fill: parent
+ text: "Reset Time"
+ font.pointSize: 16
+ verticalAlignment: Qt.AlignVCenter
+ horizontalAlignment: Qt.AlignHCenter
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ studio3D.presentation.resetTime();
+ }
+ }
+ }
+ Rectangle {
+ id: changeColorButton
+ anchors.left: parent.left
+ anchors.top: resetTimeButton.bottom
+ width: 200
+ height: 50
+ border.color: "red"
+ border.width: 3
+ color: "white"
+ Text {
+ anchors.fill: parent
+ text: "Change Color"
+ font.pointSize: 16
+ verticalAlignment: Qt.AlignVCenter
+ horizontalAlignment: Qt.AlignHCenter
+ }
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ studio3D.presentation.changeColor();
+ }
+ }
+ }
+}
diff --git a/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.pro b/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.pro
new file mode 100644
index 00000000..c1345ecc
--- /dev/null
+++ b/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+
+QT += qml quick
+
+integrity: DEFINES += USE_EMBEDDED_FONTS
+
+target.path = $$[QT_INSTALL_EXAMPLES]/studio3d/$$TARGET
+INSTALLS += target
+
+SOURCES += main.cpp
+
+RESOURCES += qmldynamickeyframes.qrc
+
+OTHER_FILES += qml/qmldynamickeyframes/* \
+ doc/src/* \
+ doc/images/*
+
+# Icon in case example is included in installer
+exists(example.ico): RC_ICONS = example.ico
diff --git a/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.qrc b/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.qrc
new file mode 100644
index 00000000..d53280d2
--- /dev/null
+++ b/examples/studio3d/qmldynamickeyframes/qmldynamickeyframes.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="main.qml">qml/qmldynamickeyframes/main.qml</file>
+ <file>presentation/dyn_key.uip</file>
+ </qresource>
+</RCC>
diff --git a/examples/studio3d/qmlstreamer/main.cpp b/examples/studio3d/qmlstreamer/main.cpp
new file mode 100644
index 00000000..82b640a8
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/main.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtQuick/QQuickView>
+#include <QtQml/QQmlEngine>
+
+#ifdef USE_EMBEDDED_FONTS
+#include <QtGui/QFontDatabase>
+#include <QtCore/QDebug>
+#endif
+
+int main(int argc, char *argv[])
+{
+#ifdef USE_EMBEDDED_FONTS
+ qputenv("QT_QPA_FONTDIR",".");
+#endif
+
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+#ifdef USE_EMBEDDED_FONTS
+ int fontId = QFontDatabase::addApplicationFont(":/res/Font/TitilliumWeb-Regular.ttf");
+ QStringList loadedFontFamilies = QFontDatabase::applicationFontFamilies(fontId);
+ if (!loadedFontFamilies.empty()) {
+ QString fontName = loadedFontFamilies.at(0);
+ QGuiApplication::setFont(QFont(fontName));
+ } else {
+ qWarning("Error: failed to load font");
+ }
+#endif
+
+ QQuickView viewer;
+
+ viewer.setSource(QUrl("qrc:/main.qml"));
+
+ viewer.setTitle(QStringLiteral("Qt 3D Studio QmlStreamer Example"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/studio3d/qmlstreamer/presentation/images/dummy.png b/examples/studio3d/qmlstreamer/presentation/images/dummy.png
new file mode 100644
index 00000000..6e401328
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/presentation/images/dummy.png
Binary files differ
diff --git a/examples/studio3d/qmlstreamer/presentation/rotating_cube.uia b/examples/studio3d/qmlstreamer/presentation/rotating_cube.uia
new file mode 100644
index 00000000..6006dcb6
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/presentation/rotating_cube.uia
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<application xmlns="http://qt.io/qt3dstudio/uia">
+ <assets initial="rotating_cube">
+ <presentation id="rotating_cube" src="rotating_cube.uip"/>
+ <presentation-qml id="red-fill" args="scripts/RedFill.qml" />
+ </assets>
+</application>
diff --git a/examples/studio3d/qmlstreamer/presentation/rotating_cube.uip b/examples/studio3d/qmlstreamer/presentation/rotating_cube.uip
new file mode 100644
index 00000000..322177af
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/presentation/rotating_cube.uip
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="3" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" />
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" />
+ <Light id="Light" />
+ <Model id="Cube" >
+ <Material id="Material" >
+ <Image id="Material_diffusemap" />
+ </Material>
+ </Model>
+ </Layer>
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" endtime="2000" />
+ <Add ref="#Camera" endtime="2000" />
+ <Add ref="#Light" endtime="2000" />
+ <State id="Scene-Rotating_Cube" name="Rotating_Cube" playmode="PingPong" >
+ <Set ref="#Layer" endtime="2000" />
+ <Set ref="#Camera" endtime="2000" />
+ <Set ref="#Light" endtime="2000" />
+ <Add ref="#Cube" name="Cube" endtime="2000" position="-349.297 168.875 0" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -349.297 100 100 2 334.863 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 168.875 100 100 2 -160.215 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 100 100 2 0 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.x" type="EaseInOut" >0 0 100 100 2 -16.4917 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.y" type="EaseInOut" >0 0 100 100 2 -154.887 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.z" type="EaseInOut" >0 0 100 100 2 270.405 100 100</AnimationTrack>
+ </Add>
+ <Add ref="#Material" diffuse="1 1 1" diffusemap="#Material_diffusemap" />
+ <Add ref="#Material_diffusemap" sourcepath=".\images\dummy.png" subpresentation="red-fill" />
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/studio3d/qmlstreamer/presentation/scripts/RedFill.qml b/examples/studio3d/qmlstreamer/presentation/scripts/RedFill.qml
new file mode 100644
index 00000000..7ee3063f
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/presentation/scripts/RedFill.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+
+Item {
+ width: 1024
+ height: 512
+ Rectangle {
+ id: rectangle
+ x: 0
+ y: 0
+ width: 0
+ height: 512
+ color: "red"
+ }
+ Text {
+ anchors.fill: parent
+ text: "QML"
+ font.pixelSize: 200
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ PropertyAnimation {
+ target: rectangle
+ property: "width"
+ from: 0
+ to: 1024
+ duration: 3000
+ loops: Animation.Infinite
+ running: true
+ }
+}
diff --git a/examples/studio3d/qmlstreamer/qml/qmlstreamer/main.qml b/examples/studio3d/qmlstreamer/qml/qmlstreamer/main.qml
new file mode 100644
index 00000000..6ffe4210
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/qml/qmlstreamer/main.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.7
+import QtStudio3D 1.0
+
+Item {
+ id: mainview
+ width: 1280
+ height: 768
+ visible: true
+
+ // Qt 3D Studio presentation element
+ //
+ // The presentation consists of as simple rotating cube with QML item as texture.
+ Studio3D {
+ id: studio3D
+ anchors.fill: parent
+ ViewerSettings {
+ scaleMode: ViewerSettings.ScaleModeFill
+ }
+ Presentation {
+ source: "qrc:/presentation/rotating_cube.uia"
+ SubPresentationSettings {
+ qmlStreams: [
+ QmlStream {
+ presentationId: "red-fill"
+ RedFill {
+ width: 1024
+ height: 512
+ }
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/examples/studio3d/qmlstreamer/qmlstreamer.pro b/examples/studio3d/qmlstreamer/qmlstreamer.pro
new file mode 100644
index 00000000..48392e17
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/qmlstreamer.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+
+QT += qml quick
+
+integrity: DEFINES += USE_EMBEDDED_FONTS
+
+target.path = $$[QT_INSTALL_EXAMPLES]/studio3d/$$TARGET
+INSTALLS += target
+
+SOURCES += main.cpp
+
+RESOURCES += qmlstreamer.qrc
+
+OTHER_FILES += qml/qmlstreamer/* \
+ doc/src/* \
+ doc/images/*
+
+# Icon in case example is included in installer
+exists(example.ico): RC_ICONS = example.ico
diff --git a/examples/studio3d/qmlstreamer/qmlstreamer.qrc b/examples/studio3d/qmlstreamer/qmlstreamer.qrc
new file mode 100644
index 00000000..94d833ea
--- /dev/null
+++ b/examples/studio3d/qmlstreamer/qmlstreamer.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="main.qml">qml/qmlstreamer/main.qml</file>
+ <file>presentation/rotating_cube.uip</file>
+ <file>presentation/rotating_cube.uia</file>
+ <file>presentation/images/dummy.png</file>
+ <file alias="RedFill.qml">presentation/scripts/RedFill.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/studio3d/studio3d.pro b/examples/studio3d/studio3d.pro
new file mode 100644
index 00000000..434b30aa
--- /dev/null
+++ b/examples/studio3d/studio3d.pro
@@ -0,0 +1,10 @@
+TEMPLATE = subdirs
+
+!package {
+ SUBDIRS += \
+ qmldynamickeyframes \
+ qmlstreamer \
+ widgetviewer \
+ surfaceviewer \
+ surfaceviewer_offscreen
+}
diff --git a/examples/studio3d/surfaceviewer/main.cpp b/examples/studio3d/surfaceviewer/main.cpp
new file mode 100644
index 00000000..12fcdd0b
--- /dev/null
+++ b/examples/studio3d/surfaceviewer/main.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtStudio3D/Q3DSSurfaceViewer>
+#include <QtStudio3D/Q3DSViewerSettings>
+#include <QtStudio3D/Q3DSPresentation>
+#include <QtStudio3D/Q3DSSceneElement>
+#include <QtStudio3D/Q3DSElement>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+#include <QtGui/QOpenGLContext>
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QGuiApplication app(argc, argv);
+
+ QWindow window;
+
+ QSize size(1200, 800);
+ window.resize(size);
+ window.setSurfaceType(QSurface::OpenGLSurface);
+ window.setTitle(QStringLiteral("Qt 3D Studio surface viewer example"));
+ window.create();
+
+ QOpenGLContext context;
+ context.setFormat(window.format());
+ context.create();
+
+ Q3DSSurfaceViewer viewer;
+ viewer.presentation()->setSource(QUrl(QStringLiteral("qrc:/presentation/circling_cube.uip")));
+ viewer.setUpdateInterval(0);
+ viewer.settings()->setScaleMode(Q3DSViewerSettings::ScaleModeFill);
+ viewer.settings()->setShowRenderStats(true);
+
+ Q3DSSceneElement sceneElement(viewer.presentation(), QStringLiteral("Scene"));
+ Q3DSElement counterElement(viewer.presentation(), QStringLiteral("Scene.Layer.Loopcounter"));
+
+ viewer.initialize(&window, &context);
+
+ window.show();
+
+ int n = 0;
+ QString loopCounter = QStringLiteral("Loop %1");
+ QObject::connect(&sceneElement, &Q3DSSceneElement::currentSlideIndexChanged, [&]() {
+ if (sceneElement.currentSlideIndex() == 1)
+ n++;
+ counterElement.setAttribute(QStringLiteral("textstring"), loopCounter.arg(n));
+ });
+
+ return app.exec();
+}
diff --git a/examples/studio3d/surfaceviewer/presentation/circling_cube.uip b/examples/studio3d/surfaceviewer/presentation/circling_cube.uip
new file mode 100644
index 00000000..8f76b0a7
--- /dev/null
+++ b/examples/studio3d/surfaceviewer/presentation/circling_cube.uip
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="3" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" />
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" />
+ <Light id="Light" />
+ <Light id="Light2" />
+ <Model id="Cube" >
+ <Material id="Material" />
+ </Model>
+ <Light id="Light2_001" />
+ <Model id="Cube_001" >
+ <Material id="Material_001" />
+ </Model>
+ <Text id="Loopcounter" />
+ </Layer>
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" />
+ <Add ref="#Camera" />
+ <Add ref="#Light" lighttype="Point" position="500 500 -500" rotation="36.8649 -268.216 350.188" />
+ <Add ref="#Loopcounter" name="Loopcounter" endtime="8000" font="TitilliumWeb-Regular" horzalign="Left" position="-546.345 288.675 0" scale="1 1 1" textstring="Loop: 1" />
+ <State id="Scene-Circling cube" name="Circling cube" playmode="Play Through To..." >
+ <Set ref="#Layer" endtime="4000" />
+ <Set ref="#Camera" endtime="4000" />
+ <Set ref="#Light" endtime="4000" />
+ <Add ref="#Light2" name="Light2" endtime="4000" lighttype="Point" position="-500 -500 -500" rotation="-52.8052 -40.339 113.184" />
+ <Add ref="#Cube" name="Cube" endtime="4000" position="-399.815 10.1036 0" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -400 0 0 0.5 -200 0 0 1 0 0 0 1.5 200 0 0 2 400 0 0 2.509 200 0 0 3 0 0 0 3.502 -200
+ 0 0 4 -400 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 0 0 0 0.5 120 0 0 1 200 0 0 1.5 120 0 0 2 0 0 0 2.509 -120 0 0 3 -200 0 0 3.502 -120
+ 0 0 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 0 0 0.5 0 0 0 1 0 0 0 1.5 0 0 0 2 0 0 0 2.509 0 0 0 3 0 0 0 3.502 0
+ 0 0 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.x" type="EaseInOut" >0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0</AnimationTrack>
+ <AnimationTrack property="rotation.y" type="EaseInOut" >0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0</AnimationTrack>
+ <AnimationTrack property="rotation.z" type="EaseInOut" >0 0 0 0 1 -90 0 0 2 -180 0 0 3 -270 0 0 4 -360 0 0</AnimationTrack>
+ </Add>
+ <Add ref="#Material" diffuse="0.12549 0.301961 0.909804" >
+ <AnimationTrack property="diffuse.x" type="EaseInOut" >0 0.160784 100 100 2 1 100 100 4 0.160784 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.y" type="EaseInOut" >0 0.956863 100 100 2 0 100 100 4 0.956863 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.z" type="EaseInOut" >0 0.0745098 100 100 2 0 100 100 4 0.0745098 100 100</AnimationTrack>
+ </Add>
+ </State>
+ <State id="Scene-Scaling cube" name="Scaling cube" playmode="Play Through To..." playthroughto="Previous" >
+ <Set ref="#Layer" endtime="4000" />
+ <Set ref="#Camera" endtime="4000" />
+ <Set ref="#Light" endtime="4000" />
+ <Add ref="#Light2_001" name="Light2" endtime="4000" lighttype="Point" position="-500 -500 -500" rotation="-52.8052 -40.339 113.184" />
+ <Add ref="#Cube_001" name="Cube" endtime="4000" position="-400 0 0" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -400 100 100 2 -206.589 100 100 4 -400 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 0 100 100 2 0 100 100 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 100 100 2 0 100 100 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="scale.x" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.y" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.z" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ </Add>
+ <Add ref="#Material_001" diffuse="0.12549 0.301961 0.909804" >
+ <AnimationTrack property="diffuse.x" type="EaseInOut" >0 0.160784 100 100 2 1 100 100 4 0.160784 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.y" type="EaseInOut" >0 0.956863 100 100 2 0 100 100 4 0.956863 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.z" type="EaseInOut" >0 0.0745098 100 100 2 0 100 100 4 0.0745098 100 100</AnimationTrack>
+ </Add>
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/studio3d/surfaceviewer/presentation/fonts/TitilliumWeb-Regular.ttf b/examples/studio3d/surfaceviewer/presentation/fonts/TitilliumWeb-Regular.ttf
new file mode 100644
index 00000000..6da82193
--- /dev/null
+++ b/examples/studio3d/surfaceviewer/presentation/fonts/TitilliumWeb-Regular.ttf
Binary files differ
diff --git a/examples/studio3d/surfaceviewer/surfaceviewer.pro b/examples/studio3d/surfaceviewer/surfaceviewer.pro
new file mode 100644
index 00000000..667c6282
--- /dev/null
+++ b/examples/studio3d/surfaceviewer/surfaceviewer.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+QT += studio3d
+
+target.path = $$[QT_INSTALL_EXAMPLES]/studio3d/$$TARGET
+INSTALLS += target
+
+SOURCES += main.cpp
+
+RESOURCES += surfaceviewer.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/studio3d/surfaceviewer/surfaceviewer.qrc b/examples/studio3d/surfaceviewer/surfaceviewer.qrc
new file mode 100644
index 00000000..ed050d32
--- /dev/null
+++ b/examples/studio3d/surfaceviewer/surfaceviewer.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>presentation/circling_cube.uip</file>
+ </qresource>
+</RCC>
diff --git a/examples/studio3d/surfaceviewer_offscreen/main.cpp b/examples/studio3d/surfaceviewer_offscreen/main.cpp
new file mode 100644
index 00000000..eb26803a
--- /dev/null
+++ b/examples/studio3d/surfaceviewer_offscreen/main.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtStudio3D/Q3DSSurfaceViewer>
+#include <QtStudio3D/Q3DSViewerSettings>
+#include <QtStudio3D/Q3DSPresentation>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QOffscreenSurface>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLFramebufferObject>
+#include <QtCore/QUrl>
+#include <QtCore/QDebug>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QSurfaceFormat format;
+ format.setDepthBufferSize(24);
+ format.setStencilBufferSize(8);
+
+ QOpenGLContext context;
+ context.setFormat(format);
+ if (!context.create())
+ qFatal("Failed to create OpenGL context");
+
+ // Must have a "surface". Depending on the platform this may be a small
+ // window, pbuffer surface, or even nothing (in case surfaceless contexts are
+ // supported) under the hood.
+ QOffscreenSurface surface;
+ surface.setFormat(context.format());
+ surface.create();
+
+ if (!context.makeCurrent(&surface))
+ qFatal("makeCurrent failed");
+
+ const QSize size(1280, 800);
+ QOpenGLFramebufferObject fbo(size, QOpenGLFramebufferObject::CombinedDepthStencil);
+
+ Q3DSSurfaceViewer viewer;
+ viewer.presentation()->setSource(QUrl(QStringLiteral("qrc:/presentation/circling_cube.uip")));
+ viewer.settings()->setScaleMode(Q3DSViewerSettings::ScaleModeFill);
+
+ // Will call update() manually when a new frame is wanted.
+ viewer.setUpdateInterval(-1);
+
+ // Automatic sizing must be turned off.
+ viewer.setAutoSize(false);
+
+ // Provide the render target size instead.
+ viewer.setSize(size);
+
+ if (!viewer.initialize(&surface, &context, fbo.handle()))
+ qFatal("Initialization failed");
+
+ // Render a few frames, read them back, and save into png files.
+ qint64 t = 0;
+ for (int frame = 1; frame <= 20; ++frame) {
+ // Advance animations manually. By default animations would advance
+ // based on whatever time the rendering, readback and PNG generation
+ // throttle this thread to. That is not ideal so maintain our own
+ // "global time".
+ viewer.presentation()->setGlobalAnimationTime(t);
+ t += 16; // 60 fps
+
+ // Render the next frame.
+ viewer.update();
+
+ // Write it to a file.
+ const QString fn = QString(QLatin1String("output_%1.png")).arg(frame);
+ fbo.toImage().save(fn);
+
+ qDebug("Rendered and saved frame %d to %s", frame, qPrintable(fn));
+ }
+
+ // Now one could do the following to generate a 60 fps video from these frames:
+ // ffmpeg -r 60 -f image2 -s 1280x800 -i output_%d.png -vcodec libx264 -crf 25 -pix_fmt yuv420p output.mp4
+
+ return 0;
+}
diff --git a/examples/studio3d/surfaceviewer_offscreen/presentation/circling_cube.uip b/examples/studio3d/surfaceviewer_offscreen/presentation/circling_cube.uip
new file mode 100644
index 00000000..3dc6c6c0
--- /dev/null
+++ b/examples/studio3d/surfaceviewer_offscreen/presentation/circling_cube.uip
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<UIP version="3" >
+ <Project >
+ <ProjectSettings author="" company="" presentationWidth="800" presentationHeight="480" maintainAspect="False" />
+ <Graph >
+ <Scene id="Scene" >
+ <Layer id="Layer" >
+ <Camera id="Camera" />
+ <Light id="Light" />
+ <Light id="Light2" />
+ <Model id="Cube" >
+ <Material id="Material" />
+ </Model>
+ <Light id="Light2_001" />
+ <Model id="Cube_001" >
+ <Material id="Material_001" />
+ </Model>
+ </Layer>
+ </Scene>
+ </Graph>
+ <Logic >
+ <State name="Master Slide" component="#Scene" >
+ <Add ref="#Layer" />
+ <Add ref="#Camera" />
+ <Add ref="#Light" lighttype="Point" position="500 500 -500" rotation="36.8649 -268.216 350.188" />
+ <State id="Scene-Circling cube" name="Circling cube" playmode="Play Through To..." >
+ <Set ref="#Layer" endtime="4000" />
+ <Set ref="#Camera" endtime="4000" />
+ <Set ref="#Light" endtime="4000" />
+ <Add ref="#Light2" name="Light2" endtime="4000" lighttype="Point" position="-500 -500 -500" rotation="-52.8052 -40.339 113.184" />
+ <Add ref="#Cube" name="Cube" endtime="4000" position="-399.815 10.1036 0" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -400 0 0 0.5 -200 0 0 1 0 0 0 1.5 200 0 0 2 400 0 0 2.509 200 0 0 3 0 0 0 3.502 -200
+ 0 0 4 -400 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 0 0 0 0.5 120 0 0 1 200 0 0 1.5 120 0 0 2 0 0 0 2.509 -120 0 0 3 -200 0 0 3.502 -120
+ 0 0 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 0 0 0.5 0 0 0 1 0 0 0 1.5 0 0 0 2 0 0 0 2.509 0 0 0 3 0 0 0 3.502 0
+ 0 0 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="rotation.x" type="EaseInOut" >0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0</AnimationTrack>
+ <AnimationTrack property="rotation.y" type="EaseInOut" >0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 0 4 0 0 0</AnimationTrack>
+ <AnimationTrack property="rotation.z" type="EaseInOut" >0 0 0 0 1 -90 0 0 2 -180 0 0 3 -270 0 0 4 -360 0 0</AnimationTrack>
+ </Add>
+ <Add ref="#Material" diffuse="0.12549 0.301961 0.909804" >
+ <AnimationTrack property="diffuse.x" type="EaseInOut" >0 0.160784 100 100 2 1 100 100 4 0.160784 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.y" type="EaseInOut" >0 0.956863 100 100 2 0 100 100 4 0.956863 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.z" type="EaseInOut" >0 0.0745098 100 100 2 0 100 100 4 0.0745098 100 100</AnimationTrack>
+ </Add>
+ </State>
+ <State id="Scene-Scaling cube" name="Scaling cube" playmode="Play Through To..." playthroughto="Previous" >
+ <Set ref="#Layer" endtime="4000" />
+ <Set ref="#Camera" endtime="4000" />
+ <Set ref="#Light" endtime="4000" />
+ <Add ref="#Light2_001" name="Light2" endtime="4000" lighttype="Point" position="-500 -500 -500" rotation="-52.8052 -40.339 113.184" />
+ <Add ref="#Cube_001" name="Cube" endtime="4000" position="-400 0 0" sourcepath="#Cube" >
+ <AnimationTrack property="position.x" type="EaseInOut" >0 -400 100 100 2 -206.589 100 100 4 -400 100 100</AnimationTrack>
+ <AnimationTrack property="position.y" type="EaseInOut" >0 0 100 100 2 0 100 100 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="position.z" type="EaseInOut" >0 0 100 100 2 0 100 100 4 0 100 100</AnimationTrack>
+ <AnimationTrack property="scale.x" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.y" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ <AnimationTrack property="scale.z" type="EaseInOut" >0 1 100 100 2 2 100 100 4 1 100 100</AnimationTrack>
+ </Add>
+ <Add ref="#Material_001" diffuse="0.12549 0.301961 0.909804" >
+ <AnimationTrack property="diffuse.x" type="EaseInOut" >0 0.160784 100 100 2 1 100 100 4 0.160784 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.y" type="EaseInOut" >0 0.956863 100 100 2 0 100 100 4 0.956863 100 100</AnimationTrack>
+ <AnimationTrack property="diffuse.z" type="EaseInOut" >0 0.0745098 100 100 2 0 100 100 4 0.0745098 100 100</AnimationTrack>
+ </Add>
+ </State>
+ </State>
+ </Logic>
+ </Project>
+</UIP>
diff --git a/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.pro b/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.pro
new file mode 100644
index 00000000..6d782f6f
--- /dev/null
+++ b/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.pro
@@ -0,0 +1,13 @@
+TEMPLATE = app
+
+QT += studio3d
+
+target.path = $$[QT_INSTALL_EXAMPLES]/studio3d/$$TARGET
+INSTALLS += target
+
+SOURCES += main.cpp
+
+RESOURCES += surfaceviewer_offscreen.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.qrc b/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.qrc
new file mode 100644
index 00000000..ed050d32
--- /dev/null
+++ b/examples/studio3d/surfaceviewer_offscreen/surfaceviewer_offscreen.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>presentation/circling_cube.uip</file>
+ </qresource>
+</RCC>
diff --git a/examples/studio3d/widgetviewer/main.cpp b/examples/studio3d/widgetviewer/main.cpp
new file mode 100644
index 00000000..dd0b3a57
--- /dev/null
+++ b/examples/studio3d/widgetviewer/main.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtWidgets/QApplication>
+#include <QtCore/QFile>
+
+#include "mainwindow.h"
+
+int main(int argc, char *argv[])
+{
+ // Enable high DPI scaling
+ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+
+ // Setting the application settings before the creation of the main window is important,
+ // as this also initializes the settings.
+ QCoreApplication::setOrganizationName("The Qt Company");
+ QCoreApplication::setOrganizationDomain("qt.io");
+ QCoreApplication::setApplicationName("Qt 3D Studio Viewer Example");
+
+ QApplication a(argc, argv);
+ MainWindow w;
+ w.resize(1280, 720);
+ w.show();
+
+ // Load an application style
+ QFile styleFile(":/resources/style/dark.qss");
+ styleFile.open(QFile::ReadOnly);
+
+ // Apply the loaded stylesheet
+ QString style(styleFile.readAll());
+ a.setStyleSheet(style);
+
+ return a.exec();
+}
diff --git a/examples/studio3d/widgetviewer/mainwindow.cpp b/examples/studio3d/widgetviewer/mainwindow.cpp
new file mode 100644
index 00000000..b57c1ba2
--- /dev/null
+++ b/examples/studio3d/widgetviewer/mainwindow.cpp
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QDebug>
+#include <QtCore/QSettings>
+#include <QtCore/QFileInfo>
+#include <QtCore/QMimeData>
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QMessageBox>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QWindow>
+#include <QtQml/QQmlContext>
+#include <QtQml/QQmlEngine>
+#include <QtStudio3D/Q3DSPresentation>
+#include <QtStudio3D/Q3DSViewerSettings>
+
+#include "mainwindow.h"
+#include "ui_mainwindow.h"
+
+MainWindow::MainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::MainWindow)
+{
+ ui->setupUi(this);
+
+ ui->actionOpen->setShortcut(QKeySequence::Open);
+ QList<QKeySequence> shortcuts;
+ shortcuts.push_back(QKeySequence(QKeySequence::Quit));
+ shortcuts.push_back(QKeySequence("CTRL+Q"));
+ ui->actionQuit->setShortcuts(shortcuts);
+ ui->actionFull_Screen->setShortcut(QKeySequence::FullScreen);
+ ui->actionReload->setShortcut(QKeySequence::Refresh);
+
+ QStringList strArg = QApplication::arguments();
+ if (strArg.size() >= 2) {
+ QFileInfo theFilePath(strArg[1]);
+ if (theFilePath.exists()) {
+ m_openFileDir = theFilePath.path();
+ ui->widget->presentation()->setSource(strArg[1]);
+ QSettings().setValue("PreviousOpenFolder", m_openFileDir);
+ }
+ }
+
+ m_embeddedMode = false;
+ m_startInFullscreen = false;
+ QStringList::const_iterator constIterator;
+ for (constIterator = strArg.constBegin(); constIterator != strArg.constEnd(); ++constIterator) {
+ if (!(*constIterator).compare("-embedded")) {
+ m_embeddedMode = true;
+ } else if (!(*constIterator).compare("-fullscreen")) {
+ // When in fullscreen also enable embedded mode
+ m_embeddedMode = true;
+ m_startInFullscreen = true;
+ }
+ }
+
+ // Hide menu when we are in embedded mode
+ if (m_embeddedMode)
+ ui->menuBar->hide();
+
+ QSettings settings;
+ ui->actionBorder->setChecked(settings.value("ShowMatte", false).toBool());
+ ui->actionFull_Screen->setChecked(settings.value("FullScreen", false).toBool());
+ ui->actionShowOnScreenStats->setChecked(settings.value("ShowOnScreenStats", false).toBool());
+
+ // Set runtime states
+ ui->widget->settings()->setMatteColor(settings.value("ShowMatte", false).toBool()
+ ? QColor(50, 50, 50) : Qt::black);
+ ui->widget->settings()->setShowRenderStats(settings.value("ShowOnScreenStats", false).toBool());
+ if (!m_startInFullscreen)
+ m_startInFullscreen = settings.value("FullScreen", false).toBool();
+
+ addAction(ui->actionFull_Screen);
+ addAction(ui->actionShowOnScreenStats);
+ addAction(ui->actionBorder);
+ addAction(ui->actionShadeMode);
+
+ // Disable hotkeys when we are in embedded mode
+ if (!m_embeddedMode) {
+ addAction(ui->actionReload);
+ addAction(ui->actionQuit);
+ addAction(ui->actionOpen);
+ }
+
+ // Allow drag'n'dropping
+ setAcceptDrops(true);
+
+ ui->widget->setUpdateInterval(0);
+
+ connect(ui->widget, &Q3DSWidget::runningChanged, this, &MainWindow::updateUI);
+}
+
+MainWindow::~MainWindow()
+{
+ QSettings settings;
+ settings.setValue("FullScreen", this->isFullScreen());
+ settings.setValue("ShowMatte", ui->widget->settings()->matteColor() != Qt::black);
+ settings.setValue("ShowOnScreenStats", ui->widget->settings()->isShowRenderStats());
+ // Don't save the window geometry if we are in fullscreen mode.
+ // This is invalid geometry and actually breaks our ability to start on a second monitor
+ if (!this->isFullScreen()) {
+ settings.setValue("WindowGeometry", saveGeometry());
+ settings.setValue("WindowState", saveState());
+ }
+ delete ui;
+}
+
+void MainWindow::toggleFullscreenMode(bool inFullscreen)
+{
+ if (inFullscreen) {
+ showFullScreen();
+ ui->menuBar->hide();
+ } else {
+ showNormal();
+ if (!m_embeddedMode)
+ ui->menuBar->show();
+ }
+ updateScaleUI();
+}
+
+void MainWindow::on_actionFull_Screen_triggered()
+{
+ bool isFullScreen = this->isFullScreen();
+ if (!isFullScreen) {
+ QSettings settings;
+ settings.setValue("WindowGeometry", saveGeometry());
+ settings.setValue("WindowState", saveState());
+ }
+ toggleFullscreenMode(!isFullScreen);
+}
+
+void MainWindow::on_actionBorder_triggered()
+{
+ if (ui->widget->settings()->matteColor() == Qt::black)
+ ui->widget->settings()->setMatteColor(QColor(50, 50, 50));
+ else
+ ui->widget->settings()->setMatteColor(Qt::black);
+}
+
+void MainWindow::on_actionShowOnScreenStats_triggered()
+{
+ bool showStats = !ui->widget->settings()->isShowRenderStats();
+ ui->widget->settings()->setShowRenderStats(showStats);
+}
+
+void MainWindow::on_actionShadeMode_triggered()
+{
+ Q3DSViewerSettings::ShadeMode shadeMode = ui->widget->settings()->shadeMode();
+ if (shadeMode == Q3DSViewerSettings::ShadeModeShaded)
+ ui->widget->settings()->setShadeMode(Q3DSViewerSettings::ShadeModeShadedWireframe);
+ else
+ ui->widget->settings()->setShadeMode(Q3DSViewerSettings::ShadeModeShaded);
+}
+
+void MainWindow::on_actionQuit_triggered()
+{
+ close();
+}
+
+void MainWindow::on_actionOpen_triggered()
+{
+ QSettings settings;
+ if (m_openFileDir.size() == 0)
+ m_openFileDir = settings.value("PreviousOpenFolder", QString("")).toString();
+
+ QString filename = QFileDialog::getOpenFileName(
+ this, tr("Open File or Project"), m_openFileDir,
+ tr("All supported formats (*.uip *.uia *.uiab);;Studio UI Presentation "
+ "(*.uip);;Application file (*.uia);;Binary Application (*.uiab)"),
+ NULL);
+
+ if (filename.size() == 0)
+ return;
+
+ QFileInfo theInfo(filename);
+ m_openFileDir = theInfo.path();
+ settings.setValue("PreviousOpenFolder", m_openFileDir);
+
+ loadFile(filename);
+}
+
+void MainWindow::on_actionReload_triggered()
+{
+ ui->widget->reset();
+ updateScaleUI();
+}
+
+void MainWindow::loadFile(const QString &filename)
+{
+ ui->widget->presentation()->setSource(QUrl::fromLocalFile(filename));
+ ui->widget->initialize();
+ updateScaleUI();
+}
+
+void MainWindow::on_actionCenter_triggered()
+{
+ ui->widget->settings()->setScaleMode(Q3DSViewerSettings::ScaleModeCenter);
+ updateScaleUI();
+}
+
+void MainWindow::on_actionScale_To_Fit_triggered()
+{
+ ui->widget->settings()->setScaleMode(Q3DSViewerSettings::ScaleModeFit);
+ updateScaleUI();
+}
+
+void MainWindow::on_actionScale_To_Fill_triggered()
+{
+ ui->widget->settings()->setScaleMode(Q3DSViewerSettings::ScaleModeFill);
+ updateScaleUI();
+}
+
+QString MainWindow::convertMimeDataToFilename(const QMimeData *mimeData)
+{
+ if (mimeData->hasUrls()) {
+ for (const QUrl &url : mimeData->urls()) {
+ QString str = url.toLocalFile();
+ if (str.isEmpty() == false) {
+ if ((QFileInfo(str).suffix() == "uip") || (QFileInfo(str).suffix() == "uia")
+ || (QFileInfo(str).suffix() == "uiab")) {
+ // Allow uip, uia and uia binary
+ return str;
+ }
+ }
+ }
+ }
+ return QString();
+}
+
+void MainWindow::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (convertMimeDataToFilename(event->mimeData()).isEmpty() == false)
+ event->acceptProposedAction();
+}
+
+void MainWindow::dropEvent(QDropEvent *event)
+{
+ QString fileName = convertMimeDataToFilename(event->mimeData());
+ if (fileName.isEmpty() == false)
+ loadFile(fileName);
+}
+
+void MainWindow::showEvent(QShowEvent *event)
+{
+ QMainWindow::showEvent(event);
+ restoreGeometry(QSettings().value("WindowGeometry").toByteArray());
+ restoreState(QSettings().value("WindowState").toByteArray());
+ if (m_startInFullscreen || this->isFullScreen()) {
+ m_startInFullscreen = false; // only once
+ toggleFullscreenMode(true);
+ }
+ if (ui->widget->isRunning() == false && !ui->widget->presentation()->source().isEmpty()) {
+ if (!ui->widget->initialize()) {
+ QString msg = QStringLiteral("Unable to initialize OpenGL.\nThis may be because your "
+ "graphic device is not sufficient, or simply because your driver is too old.\n"
+ "\nPlease try upgrading your graphics driver and try again.");
+ QMessageBox::critical(NULL, "Fatal Error", msg, QMessageBox::Close);
+ QCoreApplication::exit(1);
+ }
+ }
+}
+
+void MainWindow::updateUI()
+{
+ QString name = ui->widget->presentation()->source().toString();
+ setWindowTitle(tr("%1Qt 3D Studio Viewer example").arg(name.size()
+ ? name.append(" - ") : name));
+ updateScaleUI();
+ QWindow *w = windowHandle();
+ if (w) {
+ if (!QQmlEngine::contextForObject(w)) {
+ QQmlEngine *engine = new QQmlEngine(this);
+ QQmlContext *context = new QQmlContext(engine, this);
+ QQmlEngine::setContextForObject(w, context);
+ }
+ }
+}
+
+void MainWindow::updateScaleUI()
+{
+ ui->actionCenter->setChecked(false);
+ ui->actionScale_To_Fit->setChecked(false);
+ ui->actionScale_To_Fill->setChecked(false);
+ Q3DSViewerSettings::ScaleMode mode = ui->widget->settings()->scaleMode();
+ if (mode == Q3DSViewerSettings::ScaleModeCenter)
+ ui->actionCenter->setChecked(true);
+ else if (mode == Q3DSViewerSettings::ScaleModeFill)
+ ui->actionScale_To_Fill->setChecked(true);
+ else
+ ui->actionScale_To_Fit->setChecked(true);
+}
diff --git a/examples/studio3d/widgetviewer/mainwindow.h b/examples/studio3d/widgetviewer/mainwindow.h
new file mode 100644
index 00000000..271768ec
--- /dev/null
+++ b/examples/studio3d/widgetviewer/mainwindow.h
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtWidgets/QMainWindow>
+#include <QtStudio3D/Q3DSWidget>
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class MainWindow;
+}
+class QMimeData;
+QT_END_NAMESPACE
+
+class MainWindow : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ explicit MainWindow(QWidget *parent = nullptr);
+ ~MainWindow();
+
+ void loadFile(const QString &filename);
+
+protected:
+ // Qt event handling
+ void dragEnterEvent(QDragEnterEvent *event) override;
+ void dropEvent(QDropEvent *event) override;
+ void showEvent(QShowEvent *event) override;
+
+private:
+ Ui::MainWindow *ui;
+
+ void toggleFullscreenMode(bool inFullscreen);
+ QString convertMimeDataToFilename(const QMimeData *mimeData);
+
+private Q_SLOTS:
+ void on_actionFull_Screen_triggered();
+ void on_actionBorder_triggered();
+ void on_actionShowOnScreenStats_triggered();
+ void on_actionShadeMode_triggered();
+ void on_actionQuit_triggered();
+ void on_actionOpen_triggered();
+ void on_actionReload_triggered();
+ void on_actionCenter_triggered();
+ void on_actionScale_To_Fit_triggered();
+ void on_actionScale_To_Fill_triggered();
+ void updateUI();
+ void updateScaleUI();
+
+private:
+ QString m_openFileDir;
+ bool m_embeddedMode; // when true hide menu and disable some hotkeys
+ bool m_startInFullscreen; // this flag will be true when started with -fullscreen flag
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/studio3d/widgetviewer/mainwindow.ui b/examples/studio3d/widgetviewer/mainwindow.ui
new file mode 100644
index 00000000..cea8bf66
--- /dev/null
+++ b/examples/studio3d/widgetviewer/mainwindow.ui
@@ -0,0 +1,201 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MainWindow</class>
+ <widget class="QMainWindow" name="MainWindow">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1042</width>
+ <height>556</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Qt 3D Studio Viewer example</string>
+ </property>
+ <property name="styleSheet">
+ <string notr="true"/>
+ </property>
+ <widget class="QWidget" name="centralWidget">
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="Q3DSWidget" name="widget" native="true"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QMenuBar" name="menuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>1042</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="actionOpen"/>
+ <addaction name="actionReload"/>
+ <addaction name="separator"/>
+ <addaction name="actionQuit"/>
+ </widget>
+ <widget class="QMenu" name="menuView">
+ <property name="title">
+ <string>View</string>
+ </property>
+ <widget class="QMenu" name="menuScale_Mode">
+ <property name="toolTip">
+ <string>Set application scale mode (-scalemode [center,fit,fill] command line parameter)</string>
+ </property>
+ <property name="title">
+ <string>Scale Mode</string>
+ </property>
+ <addaction name="actionCenter"/>
+ <addaction name="actionScale_To_Fit"/>
+ <addaction name="actionScale_To_Fill"/>
+ </widget>
+ <addaction name="actionFull_Screen"/>
+ <addaction name="actionBorder"/>
+ <addaction name="menuScale_Mode"/>
+ <addaction name="actionShadeMode"/>
+ <addaction name="actionShowOnScreenStats"/>
+ </widget>
+ <addaction name="menuFile"/>
+ <addaction name="menuView"/>
+ </widget>
+ <action name="actionQuit">
+ <property name="text">
+ <string>Quit</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ </action>
+ <action name="actionFull_Screen">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Full Screen</string>
+ </property>
+ <property name="shortcut">
+ <string>F11</string>
+ </property>
+ </action>
+ <action name="actionBorder">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Show Matte</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+D</string>
+ </property>
+ </action>
+ <action name="actionShadeMode">
+ <property name="text">
+ <string>Shade Mode</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle between shaded only and wireframe on shaded</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+W</string>
+ </property>
+ </action>
+ <action name="actionShowOnScreenStats">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Show Render Statistics</string>
+ </property>
+ <property name="shortcut">
+ <string>F1</string>
+ </property>
+ </action>
+ <action name="actionOpen">
+ <property name="text">
+ <string>Open...</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ </action>
+ <action name="actionReload">
+ <property name="text">
+ <string>Reload</string>
+ </property>
+ </action>
+ <action name="actionCenter">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Center</string>
+ </property>
+ <property name="toolTip">
+ <string>Center content and use design dimensions</string>
+ </property>
+ </action>
+ <action name="actionScale_To_Fit">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Scale To Fit</string>
+ </property>
+ <property name="toolTip">
+ <string>Fit content to available space but maintain aspect ratio</string>
+ </property>
+ </action>
+ <action name="actionScale_To_Fill">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Scale To Fill</string>
+ </property>
+ <property name="toolTip">
+ <string>Use entire screen space for content, changing aspect ratio as necessary</string>
+ </property>
+ </action>
+ <action name="actionToggle_Scale_Mode">
+ <property name="text">
+ <string>Toggle Scale Mode</string>
+ </property>
+ <property name="toolTip">
+ <string>Toggle between the various scale modes</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+S</string>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <customwidgets>
+ <customwidget>
+ <class>Q3DSWidget</class>
+ <extends>QWidget</extends>
+ <header>q3dswidget.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/examples/studio3d/widgetviewer/resources/style/checkbox.png b/examples/studio3d/widgetviewer/resources/style/checkbox.png
new file mode 100644
index 00000000..b4a9aa3b
--- /dev/null
+++ b/examples/studio3d/widgetviewer/resources/style/checkbox.png
Binary files differ
diff --git a/examples/studio3d/widgetviewer/resources/style/dark.qss b/examples/studio3d/widgetviewer/resources/style/dark.qss
new file mode 100644
index 00000000..0bb5af7f
--- /dev/null
+++ b/examples/studio3d/widgetviewer/resources/style/dark.qss
@@ -0,0 +1,450 @@
+QToolTip
+{
+ border: 1px solid black;
+ background-color: #ffa02f;
+ padding: 1px;
+ border-radius: 3px;
+ opacity: 100;
+}
+
+QWidget
+{
+ color: #b1b1b1;
+ background-color: #323232;
+}
+
+QWidget:item:hover
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #ca0619);
+ color: #000000;
+}
+
+QWidget:item:selected
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+
+QMenuBar::item
+{
+ background: transparent;
+}
+
+QMenuBar::item:selected
+{
+ background: transparent;
+ border: 1px solid #ffaa00;
+}
+
+QMenuBar::item:pressed
+{
+ background: #444;
+ border: 1px solid #000;
+ background-color: QLinearGradient(
+ x1:0, y1:0,
+ x2:0, y2:1,
+ stop:1 #212121,
+ stop:0.4 #343434/*,
+ stop:0.2 #343434,
+ stop:0.1 #ffaa00*/
+ );
+ margin-bottom:-1px;
+ padding-bottom:1px;
+}
+
+QMenu
+{
+ border: 1px solid #000;
+}
+
+QMenu::item
+{
+ padding: 4px 20px 4px 20px;
+}
+
+QMenu::item:selected
+{
+ color: #000000;
+}
+
+QWidget:disabled
+{
+ color: #404040;
+ background-color: #323232;
+}
+
+QAbstractItemView
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4d4d4d, stop: 0.1 #646464, stop: 1 #5d5d5d);
+}
+
+QLineEdit
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #4d4d4d, stop: 0 #646464, stop: 1 #5d5d5d);
+ padding: 1px;
+ border-style: solid;
+ border: 1px solid #1e1e1e;
+ border-radius: 5;
+}
+
+QPushButton
+{
+ color: #b1b1b1;
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
+ border-width: 1px;
+ border-color: #1e1e1e;
+ border-style: solid;
+ border-radius: 6;
+ padding: 3px;
+ font-size: 12px;
+ padding-left: 5px;
+ padding-right: 5px;
+}
+
+QPushButton:pressed
+{
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
+}
+
+QComboBox
+{
+ selection-background-color: #ffaa00;
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #565656, stop: 0.1 #525252, stop: 0.5 #4e4e4e, stop: 0.9 #4a4a4a, stop: 1 #464646);
+ border-style: solid;
+ border: 1px solid #1e1e1e;
+ border-radius: 5;
+}
+
+QComboBox:hover,QPushButton:hover
+{
+ border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+
+
+QComboBox:on
+{
+ padding-top: 3px;
+ padding-left: 4px;
+ background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #2d2d2d, stop: 0.1 #2b2b2b, stop: 0.5 #292929, stop: 0.9 #282828, stop: 1 #252525);
+ selection-background-color: #ffaa00;
+}
+
+QComboBox QAbstractItemView
+{
+ border: 2px solid darkgray;
+ selection-background-color: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+
+QComboBox::drop-down
+{
+ subcontrol-origin: padding;
+ subcontrol-position: top right;
+ width: 15px;
+
+ border-left-width: 0px;
+ border-left-color: darkgray;
+ border-left-style: solid; /* just a single line */
+ border-top-right-radius: 3px; /* same radius as the QComboBox */
+ border-bottom-right-radius: 3px;
+ }
+
+QComboBox::down-arrow
+{
+ image: url(:/resources/style/down_arrow.png);
+}
+
+QGroupBox:focus
+{
+ border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+
+QTextEdit:focus
+{
+ border: 2px solid QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+}
+
+QScrollBar:horizontal {
+ border: 1px solid #222222;
+ background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848);
+ height: 7px;
+ margin: 0px 16px 0 16px;
+}
+
+QScrollBar::handle:horizontal
+{
+ background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f);
+ min-height: 20px;
+ border-radius: 2px;
+}
+
+QScrollBar::add-line:horizontal {
+ border: 1px solid #1b1b19;
+ border-radius: 2px;
+ background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a);
+ width: 14px;
+ subcontrol-position: right;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:horizontal {
+ border: 1px solid #1b1b19;
+ border-radius: 2px;
+ background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #ffa02f, stop: 1 #d7801a);
+ width: 14px;
+ subcontrol-position: left;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::right-arrow:horizontal, QScrollBar::left-arrow:horizontal
+{
+ border: 1px solid black;
+ width: 1px;
+ height: 1px;
+ background: white;
+}
+
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal
+{
+ background: none;
+}
+
+QScrollBar:vertical
+{
+ background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0.0 #121212, stop: 0.2 #282828, stop: 1 #484848);
+ width: 7px;
+ margin: 16px 0 16px 0;
+ border: 1px solid #222222;
+}
+
+QScrollBar::handle:vertical
+{
+ background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 0.5 #d7801a, stop: 1 #ffa02f);
+ min-height: 20px;
+ border-radius: 2px;
+}
+
+QScrollBar::add-line:vertical
+{
+ border: 1px solid #1b1b19;
+ border-radius: 2px;
+ background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffa02f, stop: 1 #d7801a);
+ height: 14px;
+ subcontrol-position: bottom;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::sub-line:vertical
+{
+ border: 1px solid #1b1b19;
+ border-radius: 2px;
+ background: QLinearGradient( x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #d7801a, stop: 1 #ffa02f);
+ height: 14px;
+ subcontrol-position: top;
+ subcontrol-origin: margin;
+}
+
+QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical
+{
+ border: 1px solid black;
+ width: 1px;
+ height: 1px;
+ background: white;
+}
+
+
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical
+{
+ background: none;
+}
+
+QTextEdit
+{
+ background-color: #242424;
+}
+
+QPlainTextEdit
+{
+ background-color: #242424;
+}
+
+QHeaderView::section
+{
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop: 0.5 #505050, stop: 0.6 #434343, stop:1 #656565);
+ color: white;
+ padding-left: 4px;
+ border: 1px solid #6c6c6c;
+}
+
+QCheckBox:disabled
+{
+ color: #414141;
+}
+
+QDockWidget::title
+{
+ padding-left: 10px;
+ spacing: 3px; /* spacing between items in the tool bar */
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232);
+}
+
+QDockWidget::close-button, QDockWidget::float-button
+{
+ text-align: center;
+ spacing: 1px; /* spacing between items in the tool bar */
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #323232, stop: 0.5 #242424, stop:1 #323232);
+}
+
+QDockWidget::close-button:hover, QDockWidget::float-button:hover
+{
+ background: #242424;
+}
+
+QDockWidget::close-button:pressed, QDockWidget::float-button:pressed
+{
+ padding: 1px -1px -1px 1px;
+}
+
+QMainWindow::separator
+{
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434);
+ color: white;
+ padding-left: 4px;
+ border: 1px solid #4c4c4c;
+ spacing: 3px; /* spacing between items in the tool bar */
+}
+
+QMainWindow::separator:hover
+{
+
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #d7801a, stop:0.5 #b56c17 stop:1 #ffa02f);
+ color: white;
+ padding-left: 4px;
+ border: 1px solid #6c6c6c;
+ spacing: 3px; /* spacing between items in the tool bar */
+}
+
+QToolBar::handle
+{
+ spacing: 3px; /* spacing between items in the tool bar */
+ background: url(:/resources/style/handle.png);
+}
+
+QMenu::separator
+{
+ height: 2px;
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:0 #161616, stop: 0.5 #151515, stop: 0.6 #212121, stop:1 #343434);
+ color: white;
+ padding-left: 4px;
+ margin-left: 10px;
+ margin-right: 5px;
+}
+
+QProgressBar
+{
+ border: 2px solid grey;
+ border-radius: 5px;
+ text-align: center;
+}
+
+QProgressBar::chunk
+{
+ background-color: #d7801a;
+ width: 2.15px;
+ margin: 0.5px;
+}
+
+QTabBar::tab {
+ color: #b1b1b1;
+ border: 1px solid #444;
+ border-bottom-style: none;
+ background-color: #323232;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-top: 3px;
+ padding-bottom: 2px;
+ margin-right: -1px;
+}
+
+QTabWidget::pane {
+ border: 1px solid #444;
+ top: 1px;
+}
+
+QTabBar::tab:last
+{
+ margin-right: 0; /* the last selected tab has nothing to overlap with on the right */
+ border-top-right-radius: 3px;
+}
+
+QTabBar::tab:first:!selected
+{
+ margin-left: 0px; /* the last selected tab has nothing to overlap with on the right */
+ border-top-left-radius: 3px;
+}
+
+QTabBar::tab:!selected
+{
+ color: #b1b1b1;
+ border-bottom-style: solid;
+ margin-top: 3px;
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:.4 #343434);
+}
+
+QTabBar::tab:selected
+{
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ margin-bottom: 0px;
+}
+
+QTabBar::tab:!selected:hover
+{
+ border-top-left-radius: 3px;
+ border-top-right-radius: 3px;
+ background-color: QLinearGradient(x1:0, y1:0, x2:0, y2:1, stop:1 #212121, stop:0.4 #343434, stop:0.2 #343434, stop:0.1 #ffaa00);
+}
+
+QRadioButton::indicator:checked, QRadioButton::indicator:unchecked{
+ color: #b1b1b1;
+ background-color: #323232;
+ border: 1px solid #b1b1b1;
+ border-radius: 6px;
+}
+
+QRadioButton::indicator:checked
+{
+ background-color: qradialgradient(
+ cx: 0.5, cy: 0.5,
+ fx: 0.5, fy: 0.5,
+ radius: 1.0,
+ stop: 0.25 #ffaa00,
+ stop: 0.3 #323232
+ );
+}
+
+QCheckBox::indicator{
+ color: #b1b1b1;
+ background-color: #323232;
+ border: 1px solid #b1b1b1;
+ width: 9px;
+ height: 9px;
+}
+
+QRadioButton::indicator
+{
+ border-radius: 6px;
+}
+
+QRadioButton::indicator:hover, QCheckBox::indicator:hover
+{
+ border: 1px solid #ffaa00;
+}
+
+QCheckBox::indicator:checked
+{
+ image:url(:/resources/style/checkbox.png);
+}
+
+QCheckBox::indicator:disabled, QRadioButton::indicator:disabled
+{
+ border: 1px solid #444;
+}
diff --git a/examples/studio3d/widgetviewer/resources/style/down_arrow.png b/examples/studio3d/widgetviewer/resources/style/down_arrow.png
new file mode 100644
index 00000000..db581cb7
--- /dev/null
+++ b/examples/studio3d/widgetviewer/resources/style/down_arrow.png
Binary files differ
diff --git a/examples/studio3d/widgetviewer/resources/style/handle.png b/examples/studio3d/widgetviewer/resources/style/handle.png
new file mode 100644
index 00000000..fd50400f
--- /dev/null
+++ b/examples/studio3d/widgetviewer/resources/style/handle.png
Binary files differ
diff --git a/examples/studio3d/widgetviewer/widgetviewer.pro b/examples/studio3d/widgetviewer/widgetviewer.pro
new file mode 100644
index 00000000..3959f894
--- /dev/null
+++ b/examples/studio3d/widgetviewer/widgetviewer.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+QT += widgets studio3d
+
+TARGET = widgetviewer
+
+target.path = $$[QT_INSTALL_EXAMPLES]/studio3d/$$TARGET
+INSTALLS += target
+
+HEADERS += mainwindow.h
+FORMS += mainwindow.ui
+SOURCES += \
+ main.cpp \
+ mainwindow.cpp
+RESOURCES += widgetviewer.qrc
diff --git a/examples/studio3d/widgetviewer/widgetviewer.qrc b/examples/studio3d/widgetviewer/widgetviewer.qrc
new file mode 100644
index 00000000..f9c5b44a
--- /dev/null
+++ b/examples/studio3d/widgetviewer/widgetviewer.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/">
+ <file>resources/style/dark.qss</file>
+ <file>resources/style/checkbox.png</file>
+ <file>resources/style/down_arrow.png</file>
+ <file>resources/style/handle.png</file>
+ </qresource>
+</RCC>