Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Split skybox class into 2 classes for HDR and 6 faces
  • Loading branch information
NEDJIMAbelgacem committed Aug 1, 2020
1 parent db75d88 commit 3ddf03b
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 230 deletions.
6 changes: 3 additions & 3 deletions src/3d/qgs3dmapscene.cpp
Expand Up @@ -205,8 +205,8 @@ Qgs3DMapScene::Qgs3DMapScene( const Qgs3DMapSettings &map, QgsAbstract3DEngine *
// 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 );
mSkybox = new QgsSkyboxEntity( "file:///home/nedjima/dev/cpp/abandoned_tank_farm_04_1k.hdr", this );
// mSkybox = new QgsCubeFacesSkyboxEntity( "file:///home/nedjima/dev/cpp/Standard-Cube-Map2/cube_map", ".png", this );
mSkybox = new QgsHDRSkyboxEntity( "file:///home/nedjima/dev/cpp/ballroom_8k.hdr", this );
// mSkybox->setEnabled(false);

// docs say frustum culling must be disabled for skybox.
Expand Down Expand Up @@ -879,6 +879,6 @@ void Qgs3DMapScene::onSkyboxSettingsChanged( const QgsSkyboxSettings &settings )
}
if ( settings.getIsSkyboxEnabled() )
{
mSkybox = new QgsSkyboxEntity( settings.getSkyboxBaseName(), settings.getSkyboxExtension() );
// mSkybox = new QgsSkyboxEntity( settings.getSkyboxBaseName(), settings.getSkyboxExtension() );
}
}
186 changes: 75 additions & 111 deletions src/3d/qgsskyboxentity.cpp
Expand Up @@ -23,25 +23,17 @@
#include <Qt3DRender/QGeometry>
#include <Qt3DRender/QAttribute>

QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extension, QNode *parent )
QgsSkyboxEntity::QgsSkyboxEntity( QNode *parent )
: Qt3DCore::QEntity( parent )
, mEffect( new Qt3DRender::QEffect( this ) )
, mMaterial( new Qt3DRender::QMaterial( 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( this ) )
, mExtension( extension )
, mBaseName( baseName )
, mHDRTexturePath( QString() )
, mIsUsingHDR( 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 );
Expand All @@ -53,8 +45,6 @@ QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extens

mGl3Technique->addFilterKey( mFilterKey );

mGl3RenderPass->setShaderProgram( mGl3Shader );

Qt3DRender::QCullFace *cullFront = new Qt3DRender::QCullFace();
cullFront->setMode( Qt3DRender::QCullFace::Front );
Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest();
Expand All @@ -80,135 +70,109 @@ QgsSkyboxEntity::QgsSkyboxEntity( const QString &baseName, const QString &extens
mMesh->setXZMeshResolution( QSize( 2, 2 ) );
mMesh->setYZMeshResolution( QSize( 2, 2 ) );

// TODO: change the kybox position according to
// TODO: change the kybox position according to camera
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform( this );
transform->setTranslation( QVector3D( 0.0f, 0.0f, 0.0f ) );
transform->setScale( 1000.0f );
addComponent( transform );

addComponent( mMesh );
addComponent( mMaterial );

reloadTexture();
}

QgsSkyboxEntity::QgsSkyboxEntity( const QString &hdrTexturePath, Qt3DCore::QNode *parent )
: Qt3DCore::QEntity( parent )
, mEffect( new Qt3DRender::QEffect( this ) )
, mMaterial( new Qt3DRender::QMaterial( 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( this ) )
// HDR skybox

QgsHDRSkyboxEntity::QgsHDRSkyboxEntity( const QString &hdrTexturePath, QNode *parent )
: QgsSkyboxEntity( parent )
, mHDRTexturePath( hdrTexturePath )
, mIsUsingHDR( true )
, mLoadedTexture( new Qt3DRender::QTextureLoader( parent ) )
, mGlShader( new Qt3DRender::QShaderProgram( this ) )
{
mGl3Shader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.vert" ) ) ) );
mGl3Shader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_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 );
mLoadedTexture->setGenerateMipMaps( false );
mGlShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.vert" ) ) ) );
mGlShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.frag" ) ) ) );
mGl3RenderPass->setShaderProgram( mGlShader );

mGl3Technique->addRenderPass( mGl3RenderPass );

mEffect->addTechnique( mGl3Technique );
mTextureParameter->setName( "skyboxTexture" );
mTextureParameter->setValue( QVariant::fromValue( mLoadedTexture ) );

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 ) );
reloadTexture();
}

// TODO: change the kybox position according to
Qt3DCore::QTransform *transform = new Qt3DCore::QTransform( this );
transform->setTranslation( QVector3D( 0.0f, 0.0f, 0.0f ) );
transform->setScale( 1000.0f );
addComponent( transform );
void QgsHDRSkyboxEntity::reloadTexture()
{
mLoadedTexture->setSource( QUrl( mHDRTexturePath ) );
}

addComponent( mMesh );
addComponent( mMaterial );
// 6 faces skybox

QgsCubeFacesSkyboxEntity::QgsCubeFacesSkyboxEntity( const QString &posX, const QString &posY, const QString &posZ, const QString &negX, const QString &negY, const QString &negZ, Qt3DCore::QNode *parent )
: QgsSkyboxEntity( parent )
, mGlShader( new Qt3DRender::QShaderProgram() )
, mCubeMap( new Qt3DRender::QTextureCubeMap( this ) )
{
init();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveX] = posX;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveY] = posY;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveZ] = posZ;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeX] = negX;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeY] = negY;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeZ] = negZ;
reloadTexture();
}

void QgsSkyboxEntity::reloadTexture()
QgsCubeFacesSkyboxEntity::QgsCubeFacesSkyboxEntity( const QString &baseName, const QString &extension, Qt3DCore::QNode *parent )
: QgsSkyboxEntity( parent )
, mGlShader( new Qt3DRender::QShaderProgram() )
, mCubeMap( new Qt3DRender::QTextureCubeMap( this ) )
{
if ( mSkyboxTextureLoader != nullptr )
delete mSkyboxTextureLoader;
if ( mIsUsingHDR )
{
mSkyboxTextureLoader = new QgsHDRSkyboxTextureLoader( mHDRTexturePath, this );
mTextureParameter->setName( QStringLiteral( "skyboxTexture" ) );
mTextureParameter->setValue( mSkyboxTextureLoader->getTextureParameter() );
}
else if ( mExtension == QStringLiteral( ".dds" ) )
{
mSkyboxTextureLoader = new QgsDDSSkyboxLoader( mBaseName, mExtension, this );
mTextureParameter->setName( QStringLiteral( "skyboxTexture" ) );
mTextureParameter->setValue( mSkyboxTextureLoader->getTextureParameter() );
}
else
{
mSkyboxTextureLoader = new QgsSkyboxTextureColloectionLoader( mBaseName, mExtension, this );
mTextureParameter->setName( QStringLiteral( "skyboxTexture" ) );
mTextureParameter->setValue( mSkyboxTextureLoader->getTextureParameter() );
}
init();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveX] = baseName + QStringLiteral( "_posx" ) + extension;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveY] = baseName + QStringLiteral( "_posy" ) + extension;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveZ] = baseName + QStringLiteral( "_posz" ) + extension;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeX] = baseName + QStringLiteral( "_negx" ) + extension;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeY] = baseName + QStringLiteral( "_negy" ) + extension;
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeZ] = baseName + QStringLiteral( "_negz" ) + extension;
reloadTexture();
}

void QgsSkyboxEntity::setBaseName( const QString &baseName )
void QgsCubeFacesSkyboxEntity::init()
{
if ( baseName != mBaseName )
mGlShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.vert" ) ) ) );
mGlShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.frag" ) ) ) );
mGl3RenderPass->setShaderProgram( mGlShader );

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

mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveX] = QString();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveY] = QString();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveZ] = QString();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeX] = QString();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeY] = QString();
mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeZ] = QString();

for ( auto it = mCubeFacesPaths.begin(); it != mCubeFacesPaths.end(); ++it )
{
mBaseName = baseName;
emit baseNameChanged( baseName );
reloadTexture();
Qt3DRender::QTextureCubeMap::CubeMapFace face = it.key();
Qt3DRender::QTextureImage *image = new Qt3DRender::QTextureImage( this );
image->setFace( face );
image->setMirrored( false );
mCubeFacesTextures[ face ] = image;
mCubeMap->addTextureImage( image );
}
}

void QgsSkyboxEntity::setExtension( const QString &extension )
{
if ( extension != mExtension )
{
mExtension = extension;
emit extensionChanged( extension );
reloadTexture();
}
mTextureParameter->setName( "skyboxTexture" );
mTextureParameter->setValue( QVariant::fromValue( mCubeMap ) );
}

void QgsSkyboxEntity::setGammaCorrectEnabled( bool enabled )
void QgsCubeFacesSkyboxEntity::reloadTexture()
{
if ( enabled != isGammaCorrectEnabled() )
for ( auto it = mCubeFacesTextures.begin(); it != mCubeFacesTextures.end(); ++it )
{
mGammaStrengthParameter->setValue( enabled ? 1.0f : 0.0f );
emit gammaCorrectEnabledChanged( enabled );
Qt3DRender::QTextureImage *image = it.value();
image->setSource( QUrl( mCubeFacesPaths[ it.key() ] ) );
}
}

0 comments on commit 3ddf03b

Please sign in to comment.