Skip to content
Permalink
Browse files

Add 3D engine base class + window & offscreen implementations

  • Loading branch information
wonder-sk committed Jul 17, 2018
1 parent 02ddffe commit 6448000a778f2b8a9d16db74a63814cf6aa9bf31
@@ -3,15 +3,18 @@

SET(QGIS_3D_SRCS
qgsaabb.cpp
qgsabstract3dengine.cpp
qgs3dmapscene.cpp
qgs3dmapsettings.cpp
qgs3dutils.cpp
qgscameracontroller.cpp
qgsoffscreen3dengine.cpp
qgsphongmaterialsettings.cpp
qgsraycastingutils_p.cpp
qgstessellatedpolygongeometry.cpp
qgstilingscheme.cpp
qgsvectorlayer3drenderer.cpp
qgswindow3dengine.cpp

chunks/qgschunkboundsentity_p.cpp
chunks/qgschunkedentity_p.cpp
@@ -47,7 +50,10 @@ SET(QGIS_3D_MOC_HDRS

qgs3dmapscene.h
qgs3dmapsettings.h
qgsabstract3dengine.h
qgscameracontroller.h
qgsoffscreen3dengine.h
qgswindow3dengine.h

chunks/qgschunkedentity_p.h
chunks/qgschunkloader_p.h
@@ -70,15 +76,18 @@ QT5_ADD_RESOURCES(QGIS_3D_RCC_SRCS shaders.qrc)

SET(QGIS_3D_HDRS
qgsaabb.h
qgsabstract3dengine.h
qgs3dmapscene.h
qgs3dmapsettings.h
qgs3dutils.h
qgscameracontroller.h
qgsoffscreen3dengine.h
qgsphongmaterialsettings.h
qgsraycastingutils_p.h
qgstessellatedpolygongeometry.h
qgstilingscheme.h
qgsvectorlayer3drenderer.h
qgswindow3dengine.h

chunks/qgschunkboundsentity_p.h
chunks/qgschunkedentity_p.h
@@ -29,6 +29,7 @@
#include <QTimer>

#include "qgsaabb.h"
#include "qgsabstract3dengine.h"
#include "qgs3dmapsettings.h"
#include "qgs3dutils.h"
#include "qgsabstract3drenderer.h"
@@ -41,27 +42,29 @@
#include "qgsvectorlayer3drenderer.h"


Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, Qt3DRender::QRenderSettings *renderSettings, Qt3DRender::QCamera *camera, const QRect &viewportRect, Qt3DCore::QNode *parent )
: Qt3DCore::QEntity( parent )
Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *engine )
: Qt3DCore::QEntity()
, mMap( map )
, mForwardRenderer( defaultFrameGraph )
, mEngine( engine )
{

connect( &map, &Qgs3DMapSettings::backgroundColorChanged, this, &Qgs3DMapScene::onBackgroundColorChanged );
onBackgroundColorChanged();

// TODO: strange - setting OnDemand render policy still keeps QGIS busy (Qt 5.9.0)
// actually it is more busy than with the default "Always" policy although there are no changes in the scene.
//renderSettings->setRenderPolicy( Qt3DRender::QRenderSettings::OnDemand );
//mRenderer->renderSettings()->setRenderPolicy( Qt3DRender::QRenderSettings::OnDemand );

#if QT_VERSION >= 0x050900
// we want precise picking of terrain (also bounding volume picking does not seem to work - not sure why)
renderSettings->pickingSettings()->setPickMethod( Qt3DRender::QPickingSettings::TrianglePicking );
mEngine->renderSettings()->pickingSettings()->setPickMethod( Qt3DRender::QPickingSettings::TrianglePicking );
#endif

QRect viewportRect( QPoint( 0, 0 ), mEngine->size() );

// Camera
float aspectRatio = ( float )viewportRect.width() / viewportRect.height();
camera->lens()->setPerspectiveProjection( 45.0f, aspectRatio, 10.f, 10000.0f );
mEngine->camera()->lens()->setPerspectiveProjection( 45.0f, aspectRatio, 10.f, 10000.0f );

mFrameAction = new Qt3DLogic::QFrameAction();
connect( mFrameAction, &Qt3DLogic::QFrameAction::triggered,
@@ -71,10 +74,10 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, Qt3DExtras::QForwardR
// Camera controlling
mCameraController = new QgsCameraController( this ); // attaches to the scene
mCameraController->setViewport( viewportRect );
mCameraController->setCamera( camera );
mCameraController->setCamera( mEngine->camera() );
mCameraController->resetView( 1000 );

addCameraViewCenterEntity( camera );
addCameraViewCenterEntity( mEngine->camera() );

// create terrain entity

@@ -156,7 +159,7 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, Qt3DExtras::QForwardR
// docs say frustum culling must be disabled for skybox.
// it _somehow_ works even when frustum culling is enabled with some camera positions,
// but then when zoomed in more it would disappear - so let's keep frustum culling disabled
defaultFrameGraph->setFrustumCullingEnabled( false );
mEngine->setFrustumCullingEnabled( false );
}

// force initial update of chunked entities
@@ -333,7 +336,7 @@ void Qgs3DMapScene::createTerrainDeferred()

void Qgs3DMapScene::onBackgroundColorChanged()
{
mForwardRenderer->setClearColor( mMap.backgroundColor() );
mEngine->setClearColor( mMap.backgroundColor() );
}

void Qgs3DMapScene::onLayerRenderer3DChanged()
@@ -36,6 +36,7 @@ namespace Qt3DExtras
class QForwardRenderer;
}

class QgsAbstract3DEngine;
class QgsMapLayer;
class QgsCameraController;
class Qgs3DMapSettings;
@@ -52,7 +53,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
Q_OBJECT
public:
//! Constructs a 3D scene based on map settings and Qt 3D renderer configuration
Qgs3DMapScene( const Qgs3DMapSettings &map, Qt3DExtras::QForwardRenderer *defaultFrameGraph, Qt3DRender::QRenderSettings *renderSettings, Qt3DRender::QCamera *camera, const QRect &viewportRect, Qt3DCore::QNode *parent = nullptr );
Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *engine );

//! Returns camera controller
QgsCameraController *cameraController() { return mCameraController; }
@@ -87,12 +88,11 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity

private:
const Qgs3DMapSettings &mMap;
QgsAbstract3DEngine *mEngine = nullptr;
//! Provides a way to have a synchronous function executed each frame
Qt3DLogic::QFrameAction *mFrameAction = nullptr;
QgsCameraController *mCameraController = nullptr;
QgsTerrainEntity *mTerrain = nullptr;
//! Forward renderer provided by 3D window
Qt3DExtras::QForwardRenderer *mForwardRenderer = nullptr;
QList<QgsChunkedEntity *> mChunkEntities;
//! Entity that shows view center - useful for debugging camera issues
Qt3DCore::QEntity *mEntityCameraViewCenter = nullptr;
@@ -0,0 +1,16 @@
/***************************************************************************
qgsabstract3dengine.cpp
--------------------------------------
Date : July 2018
Copyright : (C) 2018 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsabstract3dengine.h"
@@ -0,0 +1,52 @@
#ifndef QGSABSTRACT3DENGINE_H
#define QGSABSTRACT3DENGINE_H

#include "qgis_3d.h"

#include <QObject>

class QColor;
class QRect;

namespace Qt3DCore
{
class QEntity;
}

namespace Qt3DRender
{
class QRenderSettings;
class QCamera;
}

/**
* Base class for 3D engine implementation. A 3D engine is responsible for setting up
* rendering with Qt3D. This means mainly:
* - creating Qt3D aspect engine and registering rendering aspect
* - setting up a camera, render settings and frame graph
*
* We have two implementations:
* - QgsWindow3DEngine - used for rendering on display (has a QWindow that can be embedded into QWidget)
* - QgsOffscreen3DEngine - renders scene to images
*
* \since QGIS 3.4
*/
class _3D_EXPORT QgsAbstract3DEngine : public QObject
{
Q_OBJECT
public:

virtual void setClearColor( const QColor &color ) = 0;
virtual void setFrustumCullingEnabled( bool enabled ) = 0;
virtual void setRootEntity( Qt3DCore::QEntity *root ) = 0;

virtual Qt3DRender::QRenderSettings *renderSettings() = 0;
virtual Qt3DRender::QCamera *camera() = 0;
virtual QSize size() const = 0;

signals:
void imageCaptured( const QImage &image );
};


#endif // QGSABSTRACT3DENGINE_H

0 comments on commit 6448000

Please sign in to comment.
You can’t perform that action at this time.