summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2018-10-25 17:54:56 +0300
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2018-11-02 09:54:56 +0000
commit3ddad604c29761f1069fe88b27e6f9d44c0dbe82 (patch)
tree4d600fde9849f9cc87180a469d84c64785cb53de
parent74e92c8d0d879dc0bc5bc3dd9612f7a65dbf349c (diff)
Implement scene camera tab
The scene camera tab on the bottom dockable area provides a zoomable pixel perfect view of the scene camera. Task-number: QT3DS-709 Change-Id: I7d96464e8208b9e57a1bd980fc6b71656028e49a Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp7
-rw-r--r--src/Authoring/Client/Code/Core/Utility/StudioPreferences.h2
-rw-r--r--src/Authoring/Studio/Application/StudioApp.cpp1
-rw-r--r--src/Authoring/Studio/MainFrm.cpp17
-rw-r--r--src/Authoring/Studio/MainFrm.h2
-rw-r--r--src/Authoring/Studio/MainFrm.ui15
-rw-r--r--src/Authoring/Studio/Palettes/PaletteManager.cpp39
-rw-r--r--src/Authoring/Studio/Palettes/PaletteManager.h24
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp205
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h69
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp160
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h69
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp155
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h80
-rw-r--r--src/Authoring/Studio/Palettes/scenecamera/scenecameraview.ui86
-rw-r--r--src/Authoring/Studio/Qt3DStudio.pro14
-rw-r--r--src/Authoring/Studio/Render/IStudioRenderer.h2
-rw-r--r--src/Authoring/Studio/Render/StudioRenderer.cpp46
-rw-r--r--src/Authoring/Studio/Render/StudioRendererTranslation.cpp116
-rw-r--r--src/Authoring/Studio/Render/StudioRendererTranslation.h14
-rw-r--r--src/Authoring/Studio/UI/PlayerWnd.cpp2
-rw-r--r--src/Authoring/Studio/UI/PlayerWnd.h2
22 files changed, 1042 insertions, 85 deletions
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
index 2b609ecf..0ebb5d90 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.cpp
@@ -56,6 +56,7 @@ static QColor s_textColor;
static QColor s_masterColor;
static QColor s_disabledColor;
static QColor s_dataInputColor;
+static QColor s_matteColor;
static QLinearGradient s_welcomeBackgroundGradient;
static QColor s_timelineRowColorNormal;
@@ -142,6 +143,7 @@ void CStudioPreferences::loadPreferences(const QString &filePath)
s_masterColor = QColor("#5caa15");
s_disabledColor = QColor("#727476");
s_dataInputColor = QColor("#ff5102");
+ s_matteColor = QColor("#222222");
s_welcomeBackgroundGradient = QLinearGradient(0.0, 0.0, 1.0, 0.0);
s_welcomeBackgroundGradient.setColorAt(0.0, QColor("#343E55"));
@@ -884,6 +886,11 @@ QColor CStudioPreferences::dataInputColor()
return s_dataInputColor;
}
+QColor CStudioPreferences::matteColor()
+{
+ return s_matteColor;
+}
+
QLinearGradient CStudioPreferences::welcomeBackgroundGradient()
{
return s_welcomeBackgroundGradient;
diff --git a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
index 8f086a86..6bee5cbf 100644
--- a/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
+++ b/src/Authoring/Client/Code/Core/Utility/StudioPreferences.h
@@ -169,6 +169,8 @@ public:
static QColor masterColor();
static QColor disabledColor();
static QColor dataInputColor();
+ static QColor matteColor();
+
static QLinearGradient welcomeBackgroundGradient();
static QColor timelineRowColorNormal();
diff --git a/src/Authoring/Studio/Application/StudioApp.cpp b/src/Authoring/Studio/Application/StudioApp.cpp
index 4fe62850..824bce17 100644
--- a/src/Authoring/Studio/Application/StudioApp.cpp
+++ b/src/Authoring/Studio/Application/StudioApp.cpp
@@ -69,6 +69,7 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(res);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
SharedTools::QtSingleApplication guiApp(QStringLiteral("Qt3DStudio"), argc, argv);
#if defined(Q_OS_MACOS)
diff --git a/src/Authoring/Studio/MainFrm.cpp b/src/Authoring/Studio/MainFrm.cpp
index 8b7b5644..8c321dad 100644
--- a/src/Authoring/Studio/MainFrm.cpp
+++ b/src/Authoring/Studio/MainFrm.cpp
@@ -176,6 +176,7 @@ CMainFrame::CMainFrame()
connect(m_ui->actionProject, &QAction::triggered, this, &CMainFrame::OnViewProject);
connect(m_ui->actionSlide, &QAction::triggered, this, &CMainFrame::OnViewSlide);
connect(m_ui->actionTimeline, &QAction::triggered, this, &CMainFrame::OnViewTimeline);
+ connect(m_ui->actionSceneCamera, &QAction::triggered, this, &CMainFrame::onViewSceneCamera);
connect(m_ui->actionBounding_Boxes, &QAction::triggered,
this, &CMainFrame::OnViewBoundingBoxes);
connect(m_ui->actionPivot_Point, &QAction::triggered, this, &CMainFrame::OnViewPivotPoint);
@@ -269,6 +270,7 @@ CMainFrame::CMainFrame()
OnUpdateViewWireframe();
OnUpdateViewTooltips();
OnUpdateViewTimeline();
+ onUpdateViewSceneCamera();
OnUpdateViewInspector();
OnUpdateViewAction();
OnUpdateViewBasicObjects();
@@ -1634,6 +1636,21 @@ void CMainFrame::OnUpdateViewTimeline()
m_paletteManager->IsControlVisible(CPaletteManager::CONTROLTYPE_TIMELINE));
}
+void CMainFrame::onViewSceneCamera()
+{
+ m_paletteManager->ToggleControl(CPaletteManager::CONTROLTYPE_SCENECAMERA);
+ onUpdateViewSceneCamera();
+}
+
+void CMainFrame::onUpdateViewSceneCamera()
+{
+ const bool cameraVisible = m_paletteManager->IsControlVisible(
+ CPaletteManager::CONTROLTYPE_SCENECAMERA);
+ m_ui->actionSceneCamera->setChecked(cameraVisible);
+ g_StudioApp.getRenderer().setFullSizePreview(cameraVisible);
+ g_StudioApp.getRenderer().RequestRender();
+}
+
//==============================================================================
/**
* Called when the View Inspector Palette menu item is chosen.
diff --git a/src/Authoring/Studio/MainFrm.h b/src/Authoring/Studio/MainFrm.h
index a51b4620..a4bcb30f 100644
--- a/src/Authoring/Studio/MainFrm.h
+++ b/src/Authoring/Studio/MainFrm.h
@@ -198,6 +198,8 @@ public:
void OnUpdateViewSlide();
void OnViewTimeline();
void OnUpdateViewTimeline();
+ void onViewSceneCamera();
+ void onUpdateViewSceneCamera();
void OnEditCameraZoomExtent();
void OnEditCameraPan();
diff --git a/src/Authoring/Studio/MainFrm.ui b/src/Authoring/Studio/MainFrm.ui
index 86f9c1d7..958f92eb 100644
--- a/src/Authoring/Studio/MainFrm.ui
+++ b/src/Authoring/Studio/MainFrm.ui
@@ -116,6 +116,7 @@ Project palette using Import functionality.</string>
<addaction name="actionProject"/>
<addaction name="actionSlide"/>
<addaction name="actionTimeline"/>
+ <addaction name="actionSceneCamera"/>
<addaction name="separator"/>
<addaction name="actionBounding_Boxes"/>
<addaction name="actionPivot_Point"/>
@@ -1010,6 +1011,20 @@ Project palette using Import functionality.</string>
<string>Disable Lighting from Scene Lights in Edit Views</string>
</property>
</action>
+ <action name="actionSceneCamera">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Scene Camera</string>
+ </property>
+ <property name="toolTip">
+ <string>Scene Camera</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Shift+F</string>
+ </property>
+ </action>
</widget>
<customwidgets>
<customwidget>
diff --git a/src/Authoring/Studio/Palettes/PaletteManager.cpp b/src/Authoring/Studio/Palettes/PaletteManager.cpp
index f6774060..bb6cf84d 100644
--- a/src/Authoring/Studio/Palettes/PaletteManager.cpp
+++ b/src/Authoring/Studio/Palettes/PaletteManager.cpp
@@ -44,6 +44,7 @@
#include "ProjectView.h"
#include "TabOrderHandler.h"
#include "StudioPreferences.h"
+#include "scenecameraview.h"
#include <QtWidgets/qdockwidget.h>
#include <QtWidgets/qboxlayout.h>
@@ -65,24 +66,24 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
inMainFrame->setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
m_projectDock = new QDockWidget(QObject::tr("Project"), inMainFrame);
- m_projectDock->setObjectName("project");
+ m_projectDock->setObjectName(QStringLiteral("project"));
m_projectDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea
| Qt::BottomDockWidgetArea);
m_slideDock = new QDockWidget(QObject::tr("Slide"), inMainFrame);
- m_slideDock->setObjectName("slide");
+ m_slideDock->setObjectName(QStringLiteral("slide"));
m_slideDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
// Slide palette has a fixed size hint
auto slideView = new SlideView(m_slideDock);
slideView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_slideDock->setWidget(slideView);
inMainFrame->addDockWidget(Qt::LeftDockWidgetArea, m_slideDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_SLIDE, m_slideDock));
+ m_ControlList.insert({CONTROLTYPE_SLIDE, m_slideDock});
QObject::connect(m_slideDock, &QDockWidget::dockLocationChanged, slideView,
&SlideView::onDockLocationChange);
m_basicObjectsDock = new QDockWidget(QObject::tr("Basic Objects"), inMainFrame);
- m_basicObjectsDock->setObjectName("basic_objects");
+ m_basicObjectsDock->setObjectName(QStringLiteral("basic_objects"));
m_basicObjectsDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea
| Qt::BottomDockWidgetArea);
// Basic objects palette has a fixed size hint
@@ -91,10 +92,10 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
m_basicObjectsDock->setWidget(basicObjectsView);
inMainFrame->addDockWidget(Qt::LeftDockWidgetArea, m_basicObjectsDock);
inMainFrame->tabifyDockWidget(m_basicObjectsDock, m_slideDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_BASICOBJECTS, m_basicObjectsDock));
+ m_ControlList.insert({CONTROLTYPE_BASICOBJECTS, m_basicObjectsDock});
m_timelineDock = new QDockWidget(QObject::tr("Timeline"));
- m_timelineDock->setObjectName("timeline");
+ m_timelineDock->setObjectName(QStringLiteral("timeline"));
m_timelineDock->setAllowedAreas(Qt::BottomDockWidgetArea);
// Give the preferred size as percentages of the mainframe size
@@ -113,7 +114,20 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
m_timelineDock->setWidget(timeLineWidgetControl);
inMainFrame->addDockWidget(Qt::BottomDockWidgetArea, m_timelineDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_TIMELINE, m_timelineDock));
+ m_ControlList.insert({CONTROLTYPE_TIMELINE, m_timelineDock});
+
+ m_cameraDock = new QDockWidget(QObject::tr("Scene Camera"));
+ m_cameraDock->setObjectName(QStringLiteral("scenecamera"));
+ m_cameraDock->setAllowedAreas(Qt::BottomDockWidgetArea | Qt::LeftDockWidgetArea
+ | Qt::RightDockWidgetArea);
+
+ m_cameraWidget = new SceneCameraView(inMainFrame, m_cameraDock);
+ m_cameraWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+
+ m_cameraDock->setWidget(m_cameraWidget);
+ inMainFrame->addDockWidget(Qt::BottomDockWidgetArea, m_cameraDock);
+ inMainFrame->tabifyDockWidget(m_timelineDock, m_cameraDock);
+ m_ControlList.insert({CONTROLTYPE_SCENECAMERA, m_cameraDock});
// Give the preferred size as percentages of the mainframe size
m_projectView = new ProjectView(QSize(defaultRightDockWidth, defaultProjectHeight),
@@ -121,10 +135,10 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
m_projectView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_projectDock->setWidget(m_projectView);
inMainFrame->addDockWidget(Qt::RightDockWidgetArea, m_projectDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_PROJECT, m_projectDock));
+ m_ControlList.insert({CONTROLTYPE_PROJECT, m_projectDock});
m_actionDock = new QDockWidget(QObject::tr("Action"), inMainFrame);
- m_actionDock->setObjectName("action");
+ m_actionDock->setObjectName(QStringLiteral("action"));
m_actionDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea
| Qt::BottomDockWidgetArea);
// Give the preferred size as percentages of the mainframe size
@@ -134,10 +148,10 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
actionView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
m_actionDock->setWidget(actionView);
inMainFrame->addDockWidget(Qt::RightDockWidgetArea, m_actionDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_ACTION, m_actionDock));
+ m_ControlList.insert({CONTROLTYPE_ACTION, m_actionDock});
m_inspectorDock = new QDockWidget(QObject::tr("Inspector"), inMainFrame);
- m_inspectorDock->setObjectName("inspector_control");
+ m_inspectorDock->setObjectName(QStringLiteral("inspector_control"));
m_inspectorDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea
| Qt::BottomDockWidgetArea);
// Give the preferred size as percentages of the mainframe size
@@ -148,7 +162,7 @@ CPaletteManager::CPaletteManager(CMainFrame *inMainFrame, QObject *parent)
m_inspectorDock->setWidget(inspectorView);
inMainFrame->addDockWidget(Qt::RightDockWidgetArea, m_inspectorDock);
inMainFrame->tabifyDockWidget(m_inspectorDock, m_actionDock);
- m_ControlList.insert(std::make_pair(CONTROLTYPE_INSPECTOR, m_inspectorDock));
+ m_ControlList.insert({CONTROLTYPE_INSPECTOR, m_inspectorDock});
m_inspectorDock->raise();
@@ -280,5 +294,6 @@ void CPaletteManager::EnablePalettes()
m_timelineDock->setEnabled(true);
m_actionDock->setEnabled(true);
m_inspectorDock->setEnabled(true);
+ m_cameraDock->setEnabled(true);
}
diff --git a/src/Authoring/Studio/Palettes/PaletteManager.h b/src/Authoring/Studio/Palettes/PaletteManager.h
index 3d924e1c..0b061898 100644
--- a/src/Authoring/Studio/Palettes/PaletteManager.h
+++ b/src/Authoring/Studio/Palettes/PaletteManager.h
@@ -48,6 +48,7 @@ class TimeLineToolbar;
class TimelineView;
class ProjectView;
class TimelineWidget;
+class SceneCameraView;
QT_FORWARD_DECLARE_CLASS(QDockWidget)
@@ -59,20 +60,15 @@ class CPaletteManager : public QObject
{
Q_OBJECT
public:
- // Do NOT change the order/values of this enum, these
- // values are stored in the registry
enum EControlTypes {
- CONTROLTYPE_NONE = 0, ///<
- CONTROLTYPE_ACTION = 1, ///<
- CONTROLTYPE_BASICOBJECTS = 3, ///<
- CONTROLTYPE_INSPECTOR = 4, ///<
- CONTROLTYPE_SLIDE = 6, ///<
- CONTROLTYPE_TIMELINE = 7, ///<
- CONTROLTYPE_PROJECT = 9, ///<
-
- CONTROLTYPE_MAXCONTROLS = 32, ///< the maximum number of palettes( a string of this length
- ///is saved in the registry, changing this value will require
- ///an upgrade process )
+ CONTROLTYPE_NONE = 0,
+ CONTROLTYPE_ACTION,
+ CONTROLTYPE_BASICOBJECTS,
+ CONTROLTYPE_INSPECTOR,
+ CONTROLTYPE_SLIDE,
+ CONTROLTYPE_TIMELINE,
+ CONTROLTYPE_PROJECT,
+ CONTROLTYPE_SCENECAMERA,
};
protected:
@@ -89,10 +85,12 @@ protected:
QDockWidget *m_timelineDock;
QDockWidget *m_actionDock;
QDockWidget *m_inspectorDock;
+ QDockWidget *m_cameraDock;
TimelineView *m_timelineView;
ProjectView *m_projectView = nullptr;
TimelineWidget *m_timelineWidget;
+ SceneCameraView *m_cameraWidget;
public:
CPaletteManager(CMainFrame *inMainFrame, QObject *parent = nullptr);
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp
new file mode 100644
index 00000000..e4ca5680
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.cpp
@@ -0,0 +1,205 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "scenecameraglwidget.h"
+#include "StudioApp.h"
+#include "IStudioRenderer.h"
+#include "WGLRenderContext.h"
+#include "StudioPreferences.h"
+
+#include <QtGui/qopenglshaderprogram.h>
+#include <QtGui/qopengltexture.h>
+#include <QtGui/qopenglbuffer.h>
+#include <QtGui/qopenglvertexarrayobject.h>
+
+const QVector4D defaultTextureOffset = QVector4D(0.0f, 0.0f, 1.0f, 1.0f);
+const QVector2D defaultGeometryOffset = QVector2D(1.0f, 1.0f);
+
+SceneCameraGlWidget::SceneCameraGlWidget(QWidget *parent)
+ : QOpenGLWidget(parent)
+ , m_textureOffset(defaultTextureOffset)
+ , m_geometryOffset(defaultGeometryOffset)
+{
+ QSurfaceFormat format = CWGLRenderContext::selectSurfaceFormat(this);
+ format.setSamples(1); // We want pixel perfect view, not aliased one
+ setFormat(format);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+}
+
+SceneCameraGlWidget::~SceneCameraGlWidget()
+{
+ cleanup();
+}
+
+void SceneCameraGlWidget::initializeGL()
+{
+ initializeOpenGLFunctions();
+ QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed,
+ this, &SceneCameraGlWidget::cleanup);
+
+ m_program = new QOpenGLShaderProgram();
+ if (!m_program->addShaderFromSourceCode(
+ QOpenGLShader::Vertex,
+ "attribute highp vec2 aVertex;\n"
+ "attribute highp vec2 aUV;\n"
+ "uniform highp vec4 uTexOffset;\n"
+ "uniform highp vec4 uGeomOffset;\n"
+ "varying highp vec2 vUV;\n"
+ "void main(void)\n"
+ "{\n"
+ " gl_Position = vec4(uGeomOffset.xy + aVertex * uGeomOffset.zw, 0.0, 1.0);\n"
+ " vUV = vec2(uTexOffset.z * aUV.x + uTexOffset.x,\n"
+ " uTexOffset.w * aUV.y + uTexOffset.y);\n"
+ "}")) {
+ qWarning() << __FUNCTION__ << "Failed to add vertex shader for scene camera preview";
+ return;
+ }
+ if (!m_program->addShaderFromSourceCode(
+ QOpenGLShader::Fragment,
+ "varying highp vec2 vUV;\n"
+ "uniform sampler2D uSampler;\n"
+ "void main(void) {\n"
+ " lowp vec4 oc = texture2D(uSampler, vUV);\n"
+ " gl_FragColor = vec4(oc);\n"
+ "}")) {
+
+ qWarning() << __FUNCTION__ << "Failed to add fragment shader for scene camera preview";
+ return;
+ }
+ if (!m_program->link()) {
+ qWarning() << __FUNCTION__ << "Failed to link program for scene camera preview";
+ return;
+ }
+ if (!m_program->bind()) {
+ qWarning() << __FUNCTION__ << "Failed to bind program for scene camera preview";
+ return;
+ } else {
+ GLint vertexAtt = GLint(m_program->attributeLocation("aVertex"));
+ GLint uvAtt = GLint(m_program->attributeLocation("aUV"));
+ m_uniformTextureOffset = GLint(m_program->uniformLocation("uTexOffset"));
+ m_uniformGeometryOffset = GLint(m_program->uniformLocation("uGeomOffset"));
+ m_program->setUniformValue("uSampler", 0);
+
+ m_vao = new QOpenGLVertexArrayObject;
+ if (m_vao->create()) {
+ m_vao->bind();
+ m_vertexBuffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
+ if (m_vertexBuffer->create() && m_vertexBuffer->bind()) {
+ GLfloat vertexBuffer[] = {-1.0f, 1.0f,
+ -1.0f, -1.0f,
+ 1.0f, 1.0f,
+ 1.0f, -1.0f};
+ m_vertexBuffer->allocate(vertexBuffer, 8 * sizeof(GLfloat));
+ glEnableVertexAttribArray(vertexAtt);
+ glVertexAttribPointer(vertexAtt, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ } else {
+ qWarning() << __FUNCTION__
+ << "Failed to create/bind vertex buffer for scene camera preview";
+ return;
+ }
+ m_uvBuffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
+ if (m_uvBuffer->create() && m_uvBuffer->bind()) {
+ GLfloat uvBuffer[] = {0.0f, 1.0f,
+ 0.0f, 0.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f};
+ m_uvBuffer->allocate(uvBuffer, 8 * sizeof(GLfloat));
+ glEnableVertexAttribArray(uvAtt);
+ glVertexAttribPointer(uvAtt, 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
+ } else {
+ qWarning() << __FUNCTION__
+ << "Failed to create/bind UV buffer for scene camera preview";
+ return;
+ }
+
+ m_vao->release();
+ } else {
+ qWarning() << __FUNCTION__ << "Failed to create/bind vertex array object";
+ return;
+ }
+ }
+
+ const QColor matteColor = CStudioPreferences::matteColor();
+ glClearColor(matteColor.redF(), matteColor.greenF(), matteColor.blueF(), 1.0f);
+}
+
+void SceneCameraGlWidget::paintGL()
+{
+ Q3DStudio::IStudioRenderer &renderer(g_StudioApp.getRenderer());
+ if (renderer.IsInitialized()) {
+ m_vao->bind();
+
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_BLEND);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ QSize fboSize;
+ qt3ds::QT3DSU32 textureId;
+ renderer.getFullSizePreviewFbo(fboSize, textureId);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, GLuint(textureId));
+
+ m_program->setUniformValueArray(m_uniformTextureOffset, &m_textureOffset, 1);
+ m_program->setUniformValueArray(m_uniformGeometryOffset, &m_geometryOffset, 1);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+
+ m_vao->release();
+ }
+}
+
+void SceneCameraGlWidget::resizeGL(int, int)
+{
+ // We need to update immediately to avoid flicker
+ update();
+}
+
+void SceneCameraGlWidget::cleanup()
+{
+ makeCurrent();
+
+ delete m_program;
+ delete m_vertexBuffer;
+ delete m_uvBuffer;
+ delete m_vao;
+ m_program = nullptr;
+ m_vertexBuffer = nullptr;
+ m_uvBuffer = nullptr;
+ m_vao = nullptr;
+ m_uniformTextureOffset = 0;
+ m_uniformGeometryOffset = 0;
+ m_textureOffset = defaultTextureOffset;
+ m_geometryOffset = defaultGeometryOffset;
+
+ doneCurrent();
+}
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h
new file mode 100644
index 00000000..93becf19
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraglwidget.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_CAMERA_GLWIDGET_H
+#define SCENE_CAMERA_GLWIDGET_H
+
+#include <QtWidgets/qopenglwidget.h>
+#include <QtGui/qopenglfunctions.h>
+#include <QtGui/qvector2d.h>
+#include <QtGui/qvector4d.h>
+
+QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
+QT_FORWARD_DECLARE_CLASS(QOpenGLBuffer)
+QT_FORWARD_DECLARE_CLASS(QOpenGLVertexArrayObject)
+
+class SceneCameraGlWidget : public QOpenGLWidget, QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ explicit SceneCameraGlWidget(QWidget *parent = nullptr);
+ ~SceneCameraGlWidget();
+
+ void setTextureOffset(const QVector4D &offset) { m_textureOffset = offset; }
+ void setGeometryOffset(const QVector4D &offset) { m_geometryOffset = offset; }
+
+protected:
+ void initializeGL() override;
+ void paintGL() override;
+ void resizeGL(int, int) override;
+
+private:
+ void cleanup();
+
+ QOpenGLShaderProgram *m_program = nullptr;
+ QOpenGLBuffer *m_vertexBuffer = nullptr;
+ QOpenGLBuffer *m_uvBuffer = nullptr;
+ QOpenGLVertexArrayObject *m_vao = nullptr;
+ GLint m_uniformTextureOffset = 0;
+ GLint m_uniformGeometryOffset = 0;
+ QVector4D m_textureOffset;
+ QVector4D m_geometryOffset;
+};
+
+#endif
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp
new file mode 100644
index 00000000..035e242c
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "Qt3DSCommonPrecompile.h"
+#include "scenecamerascrollarea.h"
+#include "scenecameraglwidget.h"
+#include "Core.h"
+
+#include <QtWidgets/qscrollbar.h>
+#include <QtGui/qevent.h>
+
+SceneCameraScrollArea::SceneCameraScrollArea(QWidget *parent)
+ : QAbstractScrollArea(parent)
+{
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ m_glWidget = new SceneCameraGlWidget(this);
+}
+
+SceneCameraScrollArea::~SceneCameraScrollArea()
+{
+}
+
+void SceneCameraScrollArea::setZoom(qreal zoom, const QPoint &zoomPoint)
+{
+ // Calculate the actual presentation point
+ qreal oldH = (horizontalScrollBar()->value() + zoomPoint.x()) / m_zoom;
+ qreal oldV = (verticalScrollBar()->value() + zoomPoint.y()) / m_zoom;
+
+ m_zoom = zoom;
+
+ recalculateScrollRanges();
+
+ // Move the scrollbars so that the actual presentation point stays in the same location
+ horizontalScrollBar()->setValue(qRound(oldH * m_zoom - zoomPoint.x()));
+ verticalScrollBar()->setValue(qRound(oldV * m_zoom - zoomPoint.y()));
+
+ recalculateOffsets();
+
+ Q_EMIT needUpdate();
+}
+
+void SceneCameraScrollArea::setPresentationSize(const QSize &size)
+{
+ if (m_presentationSize != size) {
+ m_presentationSize = size;
+ recalculateScrollRanges();
+ recalculateOffsets();
+ }
+}
+
+void SceneCameraScrollArea::recalculateScrollRanges()
+{
+ const QSizeF presSize = zoomedPresentationSize();
+
+ const QSize viewSize = viewport()->size();
+ horizontalScrollBar()->setRange(0, int(presSize.width() - viewSize.width()));
+ verticalScrollBar()->setRange(0, int(presSize.height() - viewSize.height()));
+ horizontalScrollBar()->setPageStep(viewSize.width());
+ verticalScrollBar()->setPageStep(viewSize.height());
+}
+
+void SceneCameraScrollArea::recalculateOffsets()
+{
+ // Texture offset vector contains normalized rect of the viewable area of the texture
+ const QSize viewSize = viewport()->size();
+ const qreal fullWidth = qreal(horizontalScrollBar()->maximum() + viewSize.width());
+ const qreal fullHeight = qreal(verticalScrollBar()->maximum() + viewSize.height());
+ QVector4D textureOffset(
+ float(horizontalScrollBar()->value() / fullWidth),
+ float((verticalScrollBar()->maximum() - verticalScrollBar()->value()) / fullHeight),
+ float(viewSize.width() / fullWidth), float(viewSize.height() / fullHeight));
+
+ m_glWidget->setTextureOffset(textureOffset);
+
+ // The geometry offset is adjusted to keep aspect ratio when view area is larger than
+ // zoomed width/height. Since the geometry of the quad is in range [-1, 1], the width/height of
+ // the offset is just a direct multiplier to the coordinate.
+ // XY contain the subpixel offset to ensure we don't get artifacts depending on pixel alignment.
+ const QSizeF presSize = zoomedPresentationSize();
+ float subPixelX = 0.0f;
+ float subPixelY = 0.0f;
+ qreal normWidth = 1.0;
+ qreal normHeight = 1.0;
+ if (presSize.width() < fullWidth) {
+ qreal diffX = (fullWidth - qRound(presSize.width())) / 2.0;
+ subPixelX = float((diffX - qRound(diffX)) / fullWidth);
+ normWidth = presSize.width() / fullWidth;
+ }
+ if (presSize.height() < fullHeight) {
+ qreal diffY = (fullHeight - qRound(presSize.height())) / 2.0;
+ subPixelY = float((diffY - qRound(diffY)) / fullHeight);
+ normHeight = presSize.height() / fullHeight;
+ }
+
+ QVector4D geometryOffset(subPixelX, subPixelY, float(normWidth), float(normHeight));
+ m_glWidget->setGeometryOffset(geometryOffset);
+}
+
+void SceneCameraScrollArea::scrollContentsBy(int, int)
+{
+ recalculateOffsets();
+ Q_EMIT needUpdate();
+}
+
+void SceneCameraScrollArea::showEvent(QShowEvent *event)
+{
+ QAbstractScrollArea::showEvent(event);
+
+ recalculateScrollRanges();
+ recalculateOffsets();
+ resizeGlWidget();
+}
+
+void SceneCameraScrollArea::resizeGlWidget()
+{
+ m_glWidget->resize(viewport()->size());
+}
+
+QSizeF SceneCameraScrollArea::zoomedPresentationSize()
+{
+ // Multiply QSize components separately to avoid rounding to integers
+ QSizeF size = QSizeF(m_presentationSize.width() * m_zoom,
+ m_presentationSize.height() * m_zoom);
+ return size;
+}
+
+void SceneCameraScrollArea::resizeEvent(QResizeEvent *event)
+{
+ QAbstractScrollArea::resizeEvent(event);
+
+ recalculateScrollRanges();
+ recalculateOffsets();
+ resizeGlWidget();
+}
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h
new file mode 100644
index 00000000..682dc430
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecamerascrollarea.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENE_CAMERA_SCROLL_AREA
+#define SCENE_CAMERA_SCROLL_AREA
+
+#include <QtWidgets/qabstractscrollarea.h>
+
+class SceneCameraGlWidget;
+
+class SceneCameraScrollArea : public QAbstractScrollArea
+{
+ Q_OBJECT
+
+public:
+ SceneCameraScrollArea(QWidget *parent = nullptr);
+ virtual ~SceneCameraScrollArea();
+
+ SceneCameraGlWidget *glWidget() const { return m_glWidget; }
+
+ void setZoom(qreal zoom, const QPoint &zoomPoint);
+ void setPresentationSize(const QSize &size);
+ void recalculateScrollRanges();
+ void recalculateOffsets();
+
+Q_SIGNALS:
+ void needUpdate();
+
+protected:
+ void resizeEvent(QResizeEvent *event) override;
+ void scrollContentsBy(int, int) override;
+ void showEvent(QShowEvent *event) override;
+
+private:
+ void resizeGlWidget();
+ QSizeF zoomedPresentationSize();
+
+protected:
+ SceneCameraGlWidget *m_glWidget = nullptr;
+ qreal m_zoom = 1.0;
+ QSize m_presentationSize;
+};
+
+#endif
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp
new file mode 100644
index 00000000..56410dd9
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "scenecameraview.h"
+#include "ui_scenecameraview.h"
+#include "scenecameraglwidget.h"
+#include "StudioApp.h"
+#include "Core.h"
+#include "StudioProjectSettings.h"
+#include "MainFrm.h"
+#include "PlayerWnd.h"
+#include "MouseCursor.h"
+#include "ResourceCache.h"
+
+#include <QtCore/qlocale.h>
+#include <QtGui/qevent.h>
+#include <QtWidgets/qscrollbar.h>
+
+const QPoint invalidMousePoint = QPoint(-999999, -999999);
+
+SceneCameraView::SceneCameraView(CMainFrame *mainFrame, QWidget *parent) :
+ QWidget(parent)
+ , m_ui(new Ui::SceneCameraView)
+ , m_mousePressPointLeft(invalidMousePoint)
+ , m_mousePressPointRight(invalidMousePoint)
+{
+ m_ui->setupUi(this);
+
+ m_cursorPan = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_PAN);
+ m_cursorZoom = CResourceCache::GetInstance()->GetCursor(CMouseCursor::CURSOR_EDIT_CAMERA_ZOOM);
+
+ // Limit the preview framerate a bit to limit amount of updates when dragging the slider
+ m_updateTimer.setInterval(0);
+ m_updateTimer.setSingleShot(true);
+
+ connect(m_ui->zoomSlider, &QSlider::valueChanged,
+ this, &SceneCameraView::handleSliderValueChange);
+ connect(mainFrame->GetPlayerWnd(), &CPlayerWnd::newFrame,
+ this, &SceneCameraView::requestUpdate);
+ connect(m_ui->scrollArea, &SceneCameraScrollArea::needUpdate,
+ this, &SceneCameraView::requestUpdate);
+ connect(&m_updateTimer, &QTimer::timeout, this, &SceneCameraView::doUpdate);
+}
+
+SceneCameraView::~SceneCameraView()
+{
+ delete m_ui;
+}
+
+void SceneCameraView::wheelEvent(QWheelEvent *e)
+{
+ m_zoomPoint = m_ui->scrollArea->viewport()->mapFrom(this, e->pos());
+ m_ui->zoomSlider->setValue(m_ui->zoomSlider->value() + (e->angleDelta().y() / 60));
+}
+
+void SceneCameraView::resizeEvent(QResizeEvent *e)
+{
+ m_zoomPoint = m_ui->scrollArea->viewport()->geometry().center();
+
+ QWidget::resizeEvent(e);
+}
+
+void SceneCameraView::mousePressEvent(QMouseEvent *e)
+{
+ // Panning can be done with left or middle button. Left is more natural and we don't need it
+ // for selection. Alt+middle pans in edit camera mode, so middle button is also supported for
+ // panning.
+ if (m_mousePressPointRight == invalidMousePoint
+ && (e->button() == Qt::LeftButton || e->button() == Qt::MidButton)) {
+ m_mousePressPointLeft = e->pos();
+ m_mousePressScrollValues = QPoint(m_ui->scrollArea->horizontalScrollBar()->value(),
+ m_ui->scrollArea->verticalScrollBar()->value());
+ setCursor(m_cursorPan);
+ } else if (m_mousePressPointLeft == invalidMousePoint && e->button() == Qt::RightButton) {
+ m_mousePressPointRight = e->pos();
+ m_mousePressZoomValue = m_ui->zoomSlider->value();
+ setCursor(m_cursorZoom);
+ }
+}
+
+void SceneCameraView::mouseMoveEvent(QMouseEvent *e)
+{
+ if (m_mousePressPointLeft != invalidMousePoint) {
+ const QPoint delta = e->pos() - m_mousePressPointLeft;
+ m_ui->scrollArea->horizontalScrollBar()->setValue(m_mousePressScrollValues.x() - delta.x());
+ m_ui->scrollArea->verticalScrollBar()->setValue(m_mousePressScrollValues.y() - delta.y());
+ }
+ if (m_mousePressPointRight != invalidMousePoint) {
+ const qreal delta = qreal(e->pos().y() - m_mousePressPointRight.y());
+ m_zoomPoint = m_mousePressPointRight;
+ m_ui->zoomSlider->setValue(m_mousePressZoomValue - delta / 2.0);
+ }
+}
+
+void SceneCameraView::mouseReleaseEvent(QMouseEvent *e)
+{
+ if (m_mousePressPointLeft != invalidMousePoint
+ && e->button() == Qt::LeftButton || e->button() == Qt::MidButton) {
+ m_mousePressPointLeft = invalidMousePoint;
+ setCursor(Qt::ArrowCursor);
+ } else if (m_mousePressPointRight != invalidMousePoint) {
+ m_zoomPoint = m_ui->scrollArea->viewport()->geometry().center();
+ m_mousePressPointRight = invalidMousePoint;
+ m_mousePressZoomValue = 0;
+ setCursor(Qt::ArrowCursor);
+ }
+}
+
+void SceneCameraView::handleSliderValueChange()
+{
+ static const QString formatTemplate = tr("%1x");
+ const qreal zoom = qreal(m_ui->zoomSlider->value()) / 10.0;
+ m_ui->slideValueLabel->setText(formatTemplate.arg(QLocale(QLocale::C).toString(zoom)));
+ m_ui->scrollArea->setZoom(zoom, m_zoomPoint);
+ m_zoomPoint = m_ui->scrollArea->viewport()->geometry().center();
+}
+
+void SceneCameraView::doUpdate()
+{
+ // There is no event for presentation size change, so update every frame to catch the change
+ m_ui->scrollArea->setPresentationSize(
+ g_StudioApp.GetCore()->GetStudioProjectSettings()->getPresentationSize());
+ m_ui->scrollArea->glWidget()->update();
+}
+
+void SceneCameraView::requestUpdate()
+{
+ if (!m_updateTimer.isActive())
+ m_updateTimer.start();
+}
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h
new file mode 100644
index 00000000..e2bfb05b
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt 3D Studio.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SCENECAMERAVIEW_H
+#define SCENECAMERAVIEW_H
+
+#include <QtWidgets/qwidget.h>
+#include <QtCore/qtimer.h>
+
+#ifdef QT_NAMESPACE
+using namespace QT_NAMESPACE;
+#endif
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+class SceneCameraView;
+}
+QT_END_NAMESPACE
+
+class CMainFrame;
+
+class SceneCameraView : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit SceneCameraView(CMainFrame *mainFrame, QWidget *parent = 0);
+ ~SceneCameraView();
+
+protected:
+ void wheelEvent(QWheelEvent *e) override;
+ void resizeEvent(QResizeEvent *e) override;
+ void mousePressEvent(QMouseEvent *e) override;
+ void mouseMoveEvent(QMouseEvent *e) override;
+ void mouseReleaseEvent(QMouseEvent *e) override;
+
+private:
+ void handleSliderValueChange();
+ void doUpdate();
+ void requestUpdate();
+
+ Ui::SceneCameraView *m_ui = nullptr;
+
+ QTimer m_updateTimer;
+ QPoint m_zoomPoint;
+ QPoint m_mousePressPointLeft;
+ QPoint m_mousePressPointRight;
+ QPoint m_mousePressScrollValues;
+ int m_mousePressZoomValue = 0;
+
+ QCursor m_cursorPan;
+ QCursor m_cursorZoom;
+};
+
+#endif // SCENECAMERAVIEW_H
diff --git a/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.ui b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.ui
new file mode 100644
index 00000000..73bd6e19
--- /dev/null
+++ b/src/Authoring/Studio/Palettes/scenecamera/scenecameraview.ui
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>SceneCameraView</class>
+ <widget class="QWidget" name="SceneCameraView">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="SceneCameraScrollArea" name="scrollArea" native="true"/>
+ </item>
+ <item>
+ <widget class="QWidget" name="widget" native="true">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QSlider" name="zoomSlider">
+ <property name="maximumSize">
+ <size>
+ <width>300</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ <property name="minimum">
+ <number>10</number>
+ </property>
+ <property name="maximum">
+ <number>200</number>
+ </property>
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="slideValueLabel">
+ <property name="text">
+ <string>1.0</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>165</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>SceneCameraScrollArea</class>
+ <extends>QWidget</extends>
+ <header>scenecamerascrollarea.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/Authoring/Studio/Qt3DStudio.pro b/src/Authoring/Studio/Qt3DStudio.pro
index 6f91c0b1..fa7978fe 100644
--- a/src/Authoring/Studio/Qt3DStudio.pro
+++ b/src/Authoring/Studio/Qt3DStudio.pro
@@ -37,6 +37,7 @@ INCLUDEPATH += \
Palettes/Timeline \
Palettes/TimelineGraphicsView \
Palettes/TimelineGraphicsView/ui \
+ Palettes/scenecamera \
Render \
UI \
Utils \
@@ -217,7 +218,10 @@ HEADERS += \
Application/PresentationFile.h \
Palettes/Project/ChooseImagePropertyDlg.h \
Application/StudioTutorialPageIndicator.h \
- Palettes/Inspector/MaterialRefView.h
+ Palettes/Inspector/MaterialRefView.h \
+ Palettes/scenecamera/scenecameraview.h \
+ Palettes/scenecamera/scenecamerascrollarea.h \
+ Palettes/scenecamera/scenecameraglwidget.h
FORMS += \
MainFrm.ui \
@@ -236,7 +240,8 @@ FORMS += \
UI/GLVersionDlg.ui \
UI/StartupDlg.ui \
Palettes/Project/EditPresentationIdDlg.ui \
- Palettes/Project/ChooseImagePropertyDlg.ui
+ Palettes/Project/ChooseImagePropertyDlg.ui \
+ Palettes/scenecamera/scenecameraview.ui
SOURCES += \
Application/AboutDlg.cpp \
@@ -388,7 +393,10 @@ SOURCES += \
Application/PresentationFile.cpp \
Palettes/Project/ChooseImagePropertyDlg.cpp \
Application/StudioTutorialPageIndicator.cpp \
- Palettes/Inspector/MaterialRefView.cpp
+ Palettes/Inspector/MaterialRefView.cpp \
+ Palettes/scenecamera/scenecameraview.cpp \
+ Palettes/scenecamera/scenecamerascrollarea.cpp \
+ Palettes/scenecamera/scenecameraglwidget.cpp
RESOURCES += \
MainFrm.qrc \
diff --git a/src/Authoring/Studio/Render/IStudioRenderer.h b/src/Authoring/Studio/Render/IStudioRenderer.h
index 9e8e1a8b..55214cc9 100644
--- a/src/Authoring/Studio/Render/IStudioRenderer.h
+++ b/src/Authoring/Studio/Render/IStudioRenderer.h
@@ -56,6 +56,7 @@ public:
virtual void Initialize(QWidget *inWindow) = 0;
virtual void SetViewRect(const QRect &inRect) = 0;
+ virtual void setFullSizePreview(bool enabled) = 0;
virtual void GetEditCameraList(QStringList &outCameras) = 0;
virtual void SetPolygonFillModeEnabled(bool inEnableFillMode) = 0;
@@ -77,6 +78,7 @@ public:
// synchronously render the content
virtual void RenderNow() = 0;
+ virtual void getFullSizePreviewFbo(QSize &outFboDim, qt3ds::QT3DSU32 &outFboTexture) = 0;
virtual void MakeContextCurrent() = 0;
virtual void ReleaseContext() = 0;
diff --git a/src/Authoring/Studio/Render/StudioRenderer.cpp b/src/Authoring/Studio/Render/StudioRenderer.cpp
index a3850618..92860459 100644
--- a/src/Authoring/Studio/Render/StudioRenderer.cpp
+++ b/src/Authoring/Studio/Render/StudioRenderer.cpp
@@ -117,6 +117,7 @@ struct SRendererImpl : public IStudioRenderer,
QHash<QString, StudioSubPresentation> m_subpresentations;
QScopedPointer<Q3DSQmlStreamProxy> m_proxy;
QMap<QString, int> m_initialFrameMap;
+ bool m_fullSizePreview = false;
SRendererImpl()
: m_Dispatch(*g_StudioApp.GetCore()->GetDispatch())
@@ -362,6 +363,12 @@ struct SRendererImpl : public IStudioRenderer,
m_RenderContext->EndRender();
}
}
+
+ void setFullSizePreview(bool enabled) override
+ {
+ m_fullSizePreview = enabled;
+ }
+
// Request that this object renders. May be ignored if a transaction
// is ongoing so we don't get multiple rendering per transaction.
void RequestRender() override
@@ -382,6 +389,25 @@ struct SRendererImpl : public IStudioRenderer,
Render();
}
+ void getFullSizePreviewFbo(QSize &outFboDim, qt3ds::QT3DSU32 &outFboTexture) override
+ {
+ if (m_Translation) {
+ outFboDim = QSize(m_Translation->m_previewFullSizeFboDimensions.x,
+ m_Translation->m_previewFullSizeFboDimensions.y);
+ // The handle is a void * so first cast to size_t to avoid truncating pointer warning
+ if (m_Translation->m_previewFullSizeTexture) {
+ outFboTexture = static_cast<qt3ds::QT3DSU32>(reinterpret_cast<size_t>(
+ m_Translation->m_previewFullSizeTexture->GetTextureObjectHandle()));
+ } else {
+ outFboTexture = 0;
+ }
+
+ } else {
+ outFboDim = QSize(0, 0);
+ outFboTexture = 0;
+ }
+ }
+
void MakeContextCurrent() override
{
m_RenderContext->BeginRender();
@@ -401,8 +427,9 @@ struct SRendererImpl : public IStudioRenderer,
if (m_Translation) {
preview = CStudioPreferences::showEditModePreview()
&& m_Translation->m_EditCameraEnabled
- && !m_Translation->GetPreviewViewportDimensions().isZero();
- m_Translation->PreRender(preview);
+ && !m_Translation->GetPreviewViewportDimensions(false).isZero();
+ m_Translation->PreRender(preview || m_fullSizePreview,
+ m_fullSizePreview && !preview);
}
NVRenderContext &theContext = m_RenderContext->GetRenderContext();
theContext.SetDepthWriteEnabled(true);
@@ -410,12 +437,19 @@ struct SRendererImpl : public IStudioRenderer,
qt3ds::render::NVRenderClearValues::Color
| qt3ds::render::NVRenderClearValues::Depth));
if (m_Translation) {
- // draw scene preview view screen display area layer
if (preview) {
- m_Translation->Render(0, false, true, false);
- m_Translation->PreRender(false);
+ // draw scene preview view screen display area layer
+ m_Translation->Render(0, false, true, false, false);
+ m_Translation->PreRender(m_fullSizePreview, m_fullSizePreview);
+ }
+ if (m_fullSizePreview) {
+ // We need separate full size preview for Scene camera tab even if we are
+ // rendering the scene normally, since we don't want the guides or widgets
+ m_Translation->Render(0, false, true, true, false);
+ m_Translation->PreRender(false, false);
}
- m_Translation->Render(m_PickResult.GetWidgetId(), m_GuidesEnabled, false, preview);
+ m_Translation->Render(m_PickResult.GetWidgetId(), m_GuidesEnabled, false,
+ m_fullSizePreview, preview);
}
m_RenderContext->EndRender();
diff --git a/src/Authoring/Studio/Render/StudioRendererTranslation.cpp b/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
index 7ddaff39..81403ccc 100644
--- a/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
+++ b/src/Authoring/Studio/Render/StudioRendererTranslation.cpp
@@ -2058,27 +2058,30 @@ void STranslation::MarkDirty(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
RequestRender();
}
-QT3DSVec2 STranslation::GetPreviewViewportDimensions()
+QT3DSVec2 STranslation::GetPreviewViewportDimensions(bool fullSize)
{
CStudioProjectSettings *theSettings = m_Doc.GetCore()->GetStudioProjectSettings();
QSize thePresSize = theSettings->getPresentationSize();
- QT3DSVec2 vp(GetViewportDimensions());
- if (vp.x < m_previewViewportSize || vp.y < m_previewViewportSize)
- return QT3DSVec2(0.0f);
QT3DSVec2 ret(thePresSize.width(), thePresSize.height());
- const float aspect = ret.x / ret.y;
- if (aspect > 1.0) {
- ret.x = m_previewViewportSize;
- ret.y = m_previewViewportSize / aspect;
- } else {
- ret.x = m_previewViewportSize * aspect;
- ret.y = m_previewViewportSize;
+ if (!fullSize) {
+ QT3DSVec2 vp(GetViewportDimensions());
+ if (vp.x < m_previewViewportSize || vp.y < m_previewViewportSize) {
+ ret = QT3DSVec2(0.0f);
+ } else {
+ const float aspect = ret.x / ret.y;
+ if (aspect > 1.0) {
+ ret.x = m_previewViewportSize;
+ ret.y = m_previewViewportSize / aspect;
+ } else {
+ ret.x = m_previewViewportSize * aspect;
+ ret.y = m_previewViewportSize;
+ }
+ }
}
-
return ret;
}
-void STranslation::PreRender(bool scenePreviewPass)
+void STranslation::PreRender(bool scenePreviewPass, bool fullSizePreview)
{
// Run through the entire asset graph and mark active or inactive if we have an
// associated render representation.
@@ -2094,12 +2097,15 @@ void STranslation::PreRender(bool scenePreviewPass)
QT3DSVec2 theViewportDims(GetViewportDimensions());
if (scenePreviewPass) {
m_Context.SetScaleMode(qt3ds::render::ScaleModes::FitSelected);
- theViewportDims = GetPreviewViewportDimensions();
+ theViewportDims = GetPreviewViewportDimensions(fullSizePreview);
} else {
m_Context.SetScaleMode(qt3ds::render::ScaleModes::ExactSize);
}
- m_Context.SetMatteColor(QT3DSVec4(.13f, .13f, .13f, 1.0f));
+ static const QT3DSVec4 matteColor(CStudioPreferences::matteColor().redF(),
+ CStudioPreferences::matteColor().greenF(),
+ CStudioPreferences::matteColor().blueF(), 1.0f);
+ m_Context.SetMatteColor(matteColor);
// Ensure the camera points where it should
if (m_EditCameraEnabled && !scenePreviewPass) {
m_EditCameraInfo.ApplyToCamera(m_EditCamera, theViewportDims);
@@ -2351,14 +2357,14 @@ struct SVerticalGuideFactory : public IGuideElementFactory
}
};
-qt3ds::render::NVRenderRect STranslation::GetPreviewViewport()
+qt3ds::render::NVRenderRect STranslation::GetPreviewViewport(bool fullSize)
{
- QT3DSVec2 vp = GetPreviewViewportDimensions();
+ QT3DSVec2 vp = GetPreviewViewportDimensions(fullSize);
return qt3ds::render::NVRenderRect(0, 0, vp.x, vp.y);
}
void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPass,
- bool overlayPreview)
+ bool fullsizePreview, bool overlayPreview)
{
// For now, we just render.
// Next step will be to get the bounding boxes and such setup.
@@ -2372,39 +2378,47 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
if (scenePreviewPass) {
qt3ds::render::NVRenderContext &renderContext(m_Context.GetRenderContext());
- QT3DSVec2 previewDims(GetPreviewViewportDimensions());
- if (m_previewFboDimensions != previewDims) {
- m_previewFboDimensions = previewDims;
- if (m_previewFbo)
- m_Context.GetResourceManager().Release(*m_previewFbo);
- if (m_previewRenderBuffer)
- m_Context.GetResourceManager().Release(*m_previewRenderBuffer);
- if (m_previewTexture)
- m_Context.GetResourceManager().Release(*m_previewTexture);
- m_previewFbo = nullptr;
- m_previewRenderBuffer = nullptr;
- m_previewTexture = nullptr;
+ QT3DSVec2 previewDims(GetPreviewViewportDimensions(fullsizePreview));
+ QT3DSVec2 &previewFboDimensions
+ = fullsizePreview ? m_previewFullSizeFboDimensions : m_previewFboDimensions;
+ NVScopedRefCounted<qt3ds::render::NVRenderFrameBuffer> &previewFbo
+ = fullsizePreview ? m_previewFullSizeFbo : m_previewFbo;
+ NVScopedRefCounted<qt3ds::render::NVRenderRenderBuffer> &previewRenderBuffer
+ = fullsizePreview ? m_previewFullSizeRenderBuffer : m_previewRenderBuffer;
+ NVScopedRefCounted<qt3ds::render::NVRenderTexture2D> &previewTexture
+ = fullsizePreview ? m_previewFullSizeTexture : m_previewTexture;
+ if (previewFboDimensions != previewDims) {
+ previewFboDimensions = previewDims;
+ if (previewFbo)
+ m_Context.GetResourceManager().Release(*previewFbo);
+ if (previewRenderBuffer)
+ m_Context.GetResourceManager().Release(*previewRenderBuffer);
+ if (previewTexture)
+ m_Context.GetResourceManager().Release(*previewTexture);
+ previewFbo = nullptr;
+ previewRenderBuffer = nullptr;
+ previewTexture = nullptr;
}
- if (!m_previewFbo)
- m_previewFbo = m_Context.GetResourceManager().AllocateFrameBuffer();
- if (!m_previewTexture) {
- m_previewTexture = renderContext.CreateTexture2D();
- m_previewTexture->SetTextureData(qt3ds::foundation::NVDataRef<qt3ds::QT3DSU8>(),
+ if (!previewFbo)
+ previewFbo = m_Context.GetResourceManager().AllocateFrameBuffer();
+ if (!previewTexture) {
+ previewTexture = renderContext.CreateTexture2D();
+ previewTexture->SetTextureData(qt3ds::foundation::NVDataRef<qt3ds::QT3DSU8>(),
0, previewDims.x, previewDims.y,
qt3ds::render::NVRenderTextureFormats::RGBA8);
- m_previewFbo->Attach(
+ previewFbo->Attach(
qt3ds::render::NVRenderFrameBufferAttachments::Color0,
- qt3ds::render::NVRenderTextureOrRenderBuffer(*m_previewTexture));
+ qt3ds::render::NVRenderTextureOrRenderBuffer(*previewTexture));
}
- if (!m_previewRenderBuffer) {
- m_previewRenderBuffer = m_Context.GetResourceManager().AllocateRenderBuffer(
+ if (!previewRenderBuffer) {
+ previewRenderBuffer = m_Context.GetResourceManager().AllocateRenderBuffer(
previewDims.x, previewDims.y,
qt3ds::render::NVRenderRenderBufferFormats::Depth24);
- m_previewFbo->Attach(
+ previewFbo->Attach(
qt3ds::render::NVRenderFrameBufferAttachments::Depth,
- qt3ds::render::NVRenderTextureOrRenderBuffer(*m_previewRenderBuffer));
+ qt3ds::render::NVRenderTextureOrRenderBuffer(*previewRenderBuffer));
}
- renderContext.SetRenderTarget(m_previewFbo);
+ renderContext.SetRenderTarget(previewFbo);
} else {
// Render the bounding boxes and extra widgets.
// This is called *before* the render because these sort of appendages need to be added
@@ -2573,12 +2587,12 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
}
Option<NVRenderRect> viewport = m_Context.GetRenderContext().GetViewport();
if (scenePreviewPass) {
- m_Context.GetRenderContext().SetViewport(GetPreviewViewport());
+ m_Context.GetRenderContext().SetViewport(GetPreviewViewport(fullsizePreview));
m_Context.SetSceneColor(Option<QT3DSVec4>());
}
m_Scene->PrepareForRender(scenePreviewPass
- ? GetPreviewViewportDimensions()
+ ? GetPreviewViewportDimensions(fullsizePreview)
: GetViewportDimensions(), m_Context);
m_Context.RunRenderTasks();
@@ -2596,7 +2610,7 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
}
m_Scene->Render(scenePreviewPass
- ? GetPreviewViewportDimensions()
+ ? GetPreviewViewportDimensions(fullsizePreview)
: GetViewportDimensions(), m_Context, SScene::DoNotClear);
if (!scenePreviewPass && m_editModeCamerasAndLights.size() > 0) {
@@ -2705,11 +2719,11 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
if (overlayPreview) {
// Draw the overlay framebuffer
qt3ds::render::NVRenderContext &renderContext(m_Context.GetRenderContext());
- renderContext.SetViewport(GetPreviewViewport());
+ renderContext.SetViewport(GetPreviewViewport(false));
qt3ds::render::SCamera camera;
camera.MarkDirty(qt3ds::render::NodeTransformDirtyFlag::TransformIsDirty);
camera.m_Flags.SetOrthographic(true);
- QT3DSVec2 previewDims(GetPreviewViewportDimensions());
+ QT3DSVec2 previewDims(GetPreviewViewportDimensions(false));
camera.CalculateGlobalVariables(
render::NVRenderRectF(0, 0, previewDims.x, previewDims.y), previewDims);
QT3DSMat44 theVP;
@@ -2721,6 +2735,14 @@ void STranslation::Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPa
m_Context.GetRenderer().RenderQuad(previewDims, theVP, *m_previewTexture);
}
+ // Hack: For some reason, the m_previewFullSizeTexture is only valid later if it is
+ // actually drawn somewhere during the main render pass, so draw a dummy quad with it
+ if (!scenePreviewPass && m_previewFullSizeTexture) {
+ m_Context.GetRenderContext().SetViewport(NVRenderRect(0, 0, 0, 0));
+ m_Context.GetRenderer().RenderQuad(QT3DSVec2(0.0f), QT3DSMat44(),
+ *m_previewFullSizeTexture);
+ }
+
if (scenePreviewPass)
m_Context.GetRenderContext().SetRenderTarget(nullptr);
diff --git a/src/Authoring/Studio/Render/StudioRendererTranslation.h b/src/Authoring/Studio/Render/StudioRendererTranslation.h
index cabed632..5c9e1cd8 100644
--- a/src/Authoring/Studio/Render/StudioRendererTranslation.h
+++ b/src/Authoring/Studio/Render/StudioRendererTranslation.h
@@ -409,6 +409,11 @@ namespace studio {
NVScopedRefCounted<qt3ds::render::NVRenderRenderBuffer> m_previewRenderBuffer;
QT3DSVec2 m_previewFboDimensions;
+ NVScopedRefCounted<qt3ds::render::NVRenderTexture2D> m_previewFullSizeTexture;
+ NVScopedRefCounted<qt3ds::render::NVRenderFrameBuffer> m_previewFullSizeFbo;
+ NVScopedRefCounted<qt3ds::render::NVRenderRenderBuffer> m_previewFullSizeRenderBuffer;
+ QT3DSVec2 m_previewFullSizeFboDimensions;
+
STranslation(IStudioRenderer &inRenderer, IQt3DSRenderContext &inContext);
void MarkBeginComponentSeconds(qt3dsdm::Qt3DSDMSlideHandle) { ++m_ComponentSecondsDepth; }
@@ -491,8 +496,8 @@ namespace studio {
void SetViewport(QT3DSF32 inWidth, QT3DSF32 inHeight) { m_Viewport = QT3DSVec2(inWidth, inHeight); }
QT3DSVec2 GetViewportDimensions() { return m_Viewport; }
- QT3DSVec2 GetPreviewViewportDimensions();
- qt3ds::render::NVRenderRect GetPreviewViewport();
+ QT3DSVec2 GetPreviewViewportDimensions(bool fullSize);
+ qt3ds::render::NVRenderRect GetPreviewViewport(bool fullSize);
void ClearDirtySet()
{
@@ -514,8 +519,9 @@ namespace studio {
void
DeactivateScan(SGraphObjectTranslator &inParent,
qt3dsdm::Qt3DSDMInstanceHandle inAliasHandle = qt3dsdm::Qt3DSDMInstanceHandle());
- void PreRender(bool scenePreviewPass);
- void Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPass, bool overlayPreview);
+ void PreRender(bool scenePreviewPass, bool fullSizePreview);
+ void Render(int inWidgetId, bool inDrawGuides, bool scenePreviewPass, bool fullsizePreview,
+ bool overlayPreview);
void EndRender();
void DoPrepareForDrag(SNode *inSelectedNode);
void ResetWidgets();
diff --git a/src/Authoring/Studio/UI/PlayerWnd.cpp b/src/Authoring/Studio/UI/PlayerWnd.cpp
index 5e1f0c51..a528cea1 100644
--- a/src/Authoring/Studio/UI/PlayerWnd.cpp
+++ b/src/Authoring/Studio/UI/PlayerWnd.cpp
@@ -242,6 +242,8 @@ void CPlayerWnd::paintGL()
Q3DStudio::IStudioRenderer &theRenderer(g_StudioApp.getRenderer());
// Don't use request render here, this has to be synchronous inside paintGL
theRenderer.RenderNow();
+
+ Q_EMIT newFrame();
}
qreal CPlayerWnd::fixedDevicePixelRatio() const
diff --git a/src/Authoring/Studio/UI/PlayerWnd.h b/src/Authoring/Studio/UI/PlayerWnd.h
index 81eec6bc..de005220 100644
--- a/src/Authoring/Studio/UI/PlayerWnd.h
+++ b/src/Authoring/Studio/UI/PlayerWnd.h
@@ -50,6 +50,7 @@ public:
~CPlayerWnd();
void setContainerWnd(CPlayerContainerWnd *inSceneView);
+ CPlayerContainerWnd *containerWnd() const { return m_containerWnd; }
QSize sizeHint() const override;
@@ -70,6 +71,7 @@ protected:
Q_SIGNALS:
void dropReceived();
+ void newFrame();
protected:
void mouseMoveEvent(QMouseEvent *event) override;