Skip to content

Commit

Permalink
skybox rendering initial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
NEDJIMAbelgacem committed Jul 30, 2020
1 parent 0346107 commit 2d4346c
Show file tree
Hide file tree
Showing 16 changed files with 654 additions and 35 deletions.
3 changes: 2 additions & 1 deletion src/3d/CMakeLists.txt
Expand Up @@ -27,6 +27,7 @@ SET(QGIS_3D_SRCS
qgsvectorlayerchunkloader_p.cpp
qgsmeshlayer3drenderer.cpp
qgswindow3dengine.cpp
qgsskyboxentity.cpp

chunks/qgschunkboundsentity_p.cpp
chunks/qgschunkedentity_p.cpp
Expand Down Expand Up @@ -68,7 +69,6 @@ SET(QGIS_3D_SRCS
mesh/qgsmesh3dentity_p.cpp
mesh/qgsmesh3dmaterial_p.cpp
mesh/qgsmeshterraingenerator.cpp

)

SET(QGIS_3D_HDRS
Expand Down Expand Up @@ -96,6 +96,7 @@ SET(QGIS_3D_HDRS
qgstilingscheme.h
qgsvectorlayer3drenderer.h
qgswindow3dengine.h
qgsskyboxentity.h
symbols/qgsbillboardgeometry.h
symbols/qgsline3dsymbol.h
symbols/qgsmesh3dsymbol.h
Expand Down
39 changes: 23 additions & 16 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -30,6 +30,13 @@
#include <Qt3DExtras/QSkyboxEntity>
#include <Qt3DExtras/QSphereMesh>
#include <Qt3DLogic/QFrameAction>
#include <Qt3DRender/QEffect>
#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QRenderState>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QDepthTest>
#include <QSurface>

#include <QOpenGLContext>
#include <QOpenGLFunctions>
Expand Down Expand Up @@ -61,6 +68,8 @@

#include "qgslinematerial_p.h"

#include "qgsskyboxentity.h"

Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *engine )
: mMap( map )
, mEngine( engine )
Expand Down Expand Up @@ -192,21 +201,20 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *
meshEntity->setParent( this );
#endif

if ( map.hasSkyboxEnabled() )
{
Qt3DExtras::QSkyboxEntity *skybox = new Qt3DExtras::QSkyboxEntity;
skybox->setBaseName( map.skyboxFileBase() );
skybox->setExtension( map.skyboxFileExtension() );
skybox->setParent( this );

// 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
mEngine->setFrustumCullingEnabled( false );

// cppcheck wrongly believes skyBox will leak
// cppcheck-suppress memleak
}
// if ( map.hasSkyboxEnabled() )
// {
// mSkybox = new QgsSkyboxEntity("file:///home/nedjima/dev/cpp/qt3d/examples/qt3d/exampleresources/assets/cubemaps/default/default_specular", ".dds", this);
mSkybox = new QgsSkyboxEntity( "file:///home/nedjima/dev/cpp/Standard-Cube-Map2/cube_map", ".png", this );

// 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
mEngine->setFrustumCullingEnabled( false );
mEngine->setClearColor( QColor( 255, 0, 0 ) );

// cppcheck wrongly believes skyBox will leak
// cppcheck-suppress memleak
// }

// force initial update of chunked entities
onCameraChanged();
Expand Down Expand Up @@ -321,7 +329,6 @@ void Qgs3DMapScene::onCameraChanged()

void Qgs3DMapScene::updateScene()
{
QgsEventTracing::addEvent( QgsEventTracing::Instant, QStringLiteral( "3D" ), QStringLiteral( "Update Scene" ) );

for ( QgsChunkedEntity *entity : qgis::as_const( mChunkEntities ) )
{
Expand Down
3 changes: 3 additions & 0 deletions src/3d/qgs3dmapscene.h
Expand Up @@ -38,6 +38,7 @@ namespace Qt3DLogic
namespace Qt3DExtras
{
class QForwardRenderer;
class QSkyboxEntity;
}

class QgsAbstract3DEngine;
Expand All @@ -48,6 +49,7 @@ class Qgs3DMapScenePickHandler;
class Qgs3DMapSettings;
class QgsTerrainEntity;
class QgsChunkedEntity;
class QgsSkyboxEntity;

#define SIP_NO_FILE

Expand Down Expand Up @@ -165,6 +167,7 @@ class _3D_EXPORT Qgs3DMapScene : public Qt3DCore::QEntity
//! List of light origins in the scene
QList<Qt3DCore::QEntity *> mLightOriginEntities;
QList<QgsMapLayer *> mModelVectorLayers;
QgsSkyboxEntity *mSkybox = nullptr;
};

#endif // QGS3DMAPSCENE_H
181 changes: 181 additions & 0 deletions src/3d/qgsskyboxentity.cpp
@@ -0,0 +1,181 @@
#include "qgsskyboxentity.h"

#include <Qt3DCore/QEntity>
#include <QVector3D>
#include <Qt3DRender/QTexture>
#include <Qt3DExtras/QCuboidMesh>
#include <Qt3DRender/QEffect>
#include <Qt3DRender/QMaterial>
#include <Qt3DRender/QShaderProgram>
#include <Qt3DRender/QFilterKey>
#include <Qt3DRender/QRenderPass>
#include <Qt3DRender/QTechnique>
#include <Qt3DRender/QGraphicsApiFilter>
#include <Qt3DRender/QCullFace>
#include <Qt3DRender/QDepthTest>
#include <Qt3DRender/QSeamlessCubemap>
#include <QTimer>
#include <Qt3DRender/QParameter>
#include <QSurfaceFormat>
#include <Qt3DExtras/QPlaneMesh>
#include <Qt3DExtras/QDiffuseSpecularMaterial>
#include <Qt3DCore/QTransform>
#include <Qt3DRender/QGeometry>
#include <Qt3DRender/QAttribute>

QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extension, QNode *parent )
: Qt3DCore::QEntity( parent )
, mEffect( new Qt3DRender::QEffect( this ) )
, mMaterial( new Qt3DRender::QMaterial( this ) )
, mSkyboxTexture( new Qt3DRender::QTextureCubeMap( this ) )
, mLoadedTexture( new Qt3DRender::QTextureLoader( this ) )
, mGl3Shader( new Qt3DRender::QShaderProgram( this ) )
, mGl3Technique( new Qt3DRender::QTechnique( this ) )
, mFilterKey( new Qt3DRender::QFilterKey( this ) )
, mGl3RenderPass( new Qt3DRender::QRenderPass( this ) )
, mMesh( new Qt3DExtras::QCuboidMesh( this ) )
, mGammaStrengthParameter( new Qt3DRender::QParameter( QStringLiteral( "gammaStrength" ), 0.0f ) )
, mTextureParameter( new Qt3DRender::QParameter( QStringLiteral( "skyboxTexture" ), mSkyboxTexture, this ) )
, mPosXImage( new Qt3DRender::QTextureImage( this ) )
, mPosYImage( new Qt3DRender::QTextureImage( this ) )
, mPosZImage( new Qt3DRender::QTextureImage( this ) )
, mNegXImage( new Qt3DRender::QTextureImage( this ) )
, mNegYImage( new Qt3DRender::QTextureImage( this ) )
, mNegZImage( new Qt3DRender::QTextureImage( this ) )
, mExtension( extension )
, mBaseName( baseName )
, mHasPendingReloadTextureCall( false )
{
mLoadedTexture->setGenerateMipMaps( false );
mGl3Shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.vert" ) ) ) );
mGl3Shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.frag" ) ) ) );

mGl3Technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
mGl3Technique->graphicsApiFilter()->setMajorVersion( 3 );
mGl3Technique->graphicsApiFilter()->setMinorVersion( 3 );
mGl3Technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );

mFilterKey->setParent( mEffect );
mFilterKey->setName( QStringLiteral( "renderingStyle" ) );
mFilterKey->setValue( QStringLiteral( "forward" ) );

mGl3Technique->addFilterKey( mFilterKey );

mGl3RenderPass->setShaderProgram( mGl3Shader );

Qt3DRender::QCullFace *cullFront = new Qt3DRender::QCullFace();
cullFront->setMode( Qt3DRender::QCullFace::Front );
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest();
depthTest->setDepthFunction( Qt3DRender::QDepthTest::LessOrEqual );
Qt3DRender::QSeamlessCubemap *seamlessCubemap = new Qt3DRender::QSeamlessCubemap();

mGl3RenderPass->addRenderState( cullFront );
mGl3RenderPass->addRenderState( depthTest );
mGl3RenderPass->addRenderState( seamlessCubemap );

mGl3Technique->addRenderPass( mGl3RenderPass );

mEffect->addTechnique( mGl3Technique );

mMaterial->setEffect( mEffect );
mMaterial->addParameter( mGammaStrengthParameter );
mMaterial->addParameter( mTextureParameter );

mMesh->setXExtent( 2.0f );
mMesh->setYExtent( 2.0f );
mMesh->setZExtent( 2.0f );
mMesh->setXYMeshResolution( QSize( 2, 2 ) );
mMesh->setXZMeshResolution( QSize( 2, 2 ) );
mMesh->setYZMeshResolution( QSize( 2, 2 ) );

Qt3DCore::QTransform *transform = new Qt3DCore::QTransform( this );
transform->setTranslation( QVector3D( 0.0f, 0.0f, 0.0f ) );
transform->setScale( 1.0f );
addComponent( transform );

mPosXImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapPositiveX );
mPosXImage->setMirrored( false );
mPosYImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapPositiveY );
mPosYImage->setMirrored( false );
mPosZImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapPositiveZ );
mPosZImage->setMirrored( false );
mNegXImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapNegativeX );
mNegXImage->setMirrored( false );
mNegYImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapNegativeY );
mNegYImage->setMirrored( false );
mNegZImage->setFace( Qt3DRender::QTextureCubeMap::CubeMapNegativeZ );
mNegZImage->setMirrored( false );

mSkyboxTexture->setMagnificationFilter( Qt3DRender::QTextureCubeMap::Linear );
mSkyboxTexture->setMinificationFilter( Qt3DRender::QTextureCubeMap::Linear );
mSkyboxTexture->setGenerateMipMaps( false );
mSkyboxTexture->setWrapMode( Qt3DRender::QTextureWrapMode( Qt3DRender::QTextureWrapMode::Repeat ) );

mSkyboxTexture->addTextureImage( mPosXImage );
mSkyboxTexture->addTextureImage( mPosYImage );
mSkyboxTexture->addTextureImage( mPosZImage );
mSkyboxTexture->addTextureImage( mNegXImage );
mSkyboxTexture->addTextureImage( mNegYImage );
mSkyboxTexture->addTextureImage( mNegZImage );

addComponent( mMesh );
addComponent( mMaterial );

reloadTexture();
}

void QgsSkyboxEntity::reloadTexture()
{
if ( !mHasPendingReloadTextureCall )
{
mHasPendingReloadTextureCall = true;
// QTimer::singleShot(10, [this] {
if ( mExtension == QStringLiteral( ".dds" ) )
{
mLoadedTexture->setSource( QUrl( mBaseName + mExtension ) );
mTextureParameter->setValue( QVariant::fromValue( mLoadedTexture ) );
}
else
{
mPosXImage->setSource( QUrl( mBaseName + QStringLiteral( "_posx" ) + mExtension ) );
mPosYImage->setSource( QUrl( mBaseName + QStringLiteral( "_posy" ) + mExtension ) );
mPosZImage->setSource( QUrl( mBaseName + QStringLiteral( "_posz" ) + mExtension ) );
mNegXImage->setSource( QUrl( mBaseName + QStringLiteral( "_negx" ) + mExtension ) );
mNegYImage->setSource( QUrl( mBaseName + QStringLiteral( "_negy" ) + mExtension ) );
mNegZImage->setSource( QUrl( mBaseName + QStringLiteral( "_negz" ) + mExtension ) );
mTextureParameter->setValue( QVariant::fromValue( mSkyboxTexture ) );
}
mHasPendingReloadTextureCall = false;
// });
}
}

void QgsSkyboxEntity::setBaseName( const QString &baseName )
{
if ( baseName != mBaseName )
{
mBaseName = baseName;
emit baseNameChanged( baseName );
reloadTexture();
}
}

void QgsSkyboxEntity::setExtension( const QString &extension )
{
if ( extension != mExtension )
{
mExtension = extension;
emit extensionChanged( extension );
reloadTexture();
}
}

void QgsSkyboxEntity::setGammaCorrectEnabled( bool enabled )
{
if ( enabled != isGammaCorrectEnabled() )
{
mGammaStrengthParameter->setValue( enabled ? 1.0f : 0.0f );
emit gammaCorrectEnabledChanged( enabled );
}
}

0 comments on commit 2d4346c

Please sign in to comment.