QGIS API Documentation  3.20.0-Odense (decaadbb31)
qgsskyboxentity.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsskyboxentity.cpp
3  --------------------------------------
4  Date : August 2020
5  Copyright : (C) 2020 by Belgacem Nedjima
6  Email : gb uderscore nedjima at esi dot dz
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsskyboxentity.h"
17 
18 #include <Qt3DCore/QEntity>
19 #include <Qt3DExtras/QCuboidMesh>
20 #include <Qt3DRender/QEffect>
21 #include <Qt3DRender/QMaterial>
22 #include <Qt3DRender/QShaderProgram>
23 #include <Qt3DRender/QFilterKey>
24 #include <Qt3DRender/QRenderPass>
25 #include <Qt3DRender/QTechnique>
26 #include <Qt3DRender/QGraphicsApiFilter>
27 #include <Qt3DRender/QCullFace>
28 #include <Qt3DRender/QDepthTest>
29 #include <Qt3DRender/QSeamlessCubemap>
30 #include <Qt3DRender/QParameter>
31 #include <Qt3DRender/QTextureImage>
32 #include <QUrl>
33 
34 #include "qgsimagecache.h"
35 #include "qgsimagetexture.h"
36 #include "qgsproject.h"
37 
39  : Qt3DCore::QEntity( parent )
40  , mEffect( new Qt3DRender::QEffect( this ) )
41  , mMaterial( new Qt3DRender::QMaterial( this ) )
42  , mGl3Technique( new Qt3DRender::QTechnique( this ) )
43  , mFilterKey( new Qt3DRender::QFilterKey( this ) )
44  , mGl3RenderPass( new Qt3DRender::QRenderPass( this ) )
45  , mMesh( new Qt3DExtras::QCuboidMesh( this ) )
46  , mGammaStrengthParameter( new Qt3DRender::QParameter( QStringLiteral( "gammaStrength" ), 0.0f ) )
47  , mTextureParameter( new Qt3DRender::QParameter( this ) )
48 {
49  mGl3Technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
50  mGl3Technique->graphicsApiFilter()->setMajorVersion( 3 );
51  mGl3Technique->graphicsApiFilter()->setMinorVersion( 3 );
52  mGl3Technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
53 
54  mFilterKey->setParent( mEffect );
55  mFilterKey->setName( QStringLiteral( "renderingStyle" ) );
56  mFilterKey->setValue( QStringLiteral( "forward" ) );
57 
58  mGl3Technique->addFilterKey( mFilterKey );
59 
60  Qt3DRender::QCullFace *cullFront = new Qt3DRender::QCullFace();
61  cullFront->setMode( Qt3DRender::QCullFace::Front );
62  Qt3DRender::QDepthTest *depthTest = new Qt3DRender::QDepthTest();
63  depthTest->setDepthFunction( Qt3DRender::QDepthTest::LessOrEqual );
64  Qt3DRender::QSeamlessCubemap *seamlessCubemap = new Qt3DRender::QSeamlessCubemap();
65 
66  mGl3RenderPass->addRenderState( cullFront );
67  mGl3RenderPass->addRenderState( depthTest );
68  mGl3RenderPass->addRenderState( seamlessCubemap );
69 
70  mGl3Technique->addRenderPass( mGl3RenderPass );
71 
72  mEffect->addTechnique( mGl3Technique );
73 
74  mMaterial->setEffect( mEffect );
75  mMaterial->addParameter( mGammaStrengthParameter );
76  mMaterial->addParameter( mTextureParameter );
77 
78  mMesh->setXYMeshResolution( QSize( 2, 2 ) );
79  mMesh->setXZMeshResolution( QSize( 2, 2 ) );
80  mMesh->setYZMeshResolution( QSize( 2, 2 ) );
81 
82  addComponent( mMesh );
83  addComponent( mMaterial );
84 }
85 
86 // Panoramic skybox
87 
88 QgsPanoramicSkyboxEntity::QgsPanoramicSkyboxEntity( const QString &texturePath, QNode *parent )
89  : QgsSkyboxEntity( parent )
90  , mTexturePath( texturePath )
91  , mLoadedTexture( new Qt3DRender::QTextureLoader( parent ) )
92  , mGlShader( new Qt3DRender::QShaderProgram( this ) )
93 {
94  mLoadedTexture->setGenerateMipMaps( false );
95  mGlShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.vert" ) ) ) );
96  mGlShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/hdr_skybox.frag" ) ) ) );
97  mGl3RenderPass->setShaderProgram( mGlShader );
98 
99  mTextureParameter->setName( "skyboxTexture" );
100  mTextureParameter->setValue( QVariant::fromValue( mLoadedTexture ) );
101 
102  reloadTexture();
103 }
104 
105 void QgsPanoramicSkyboxEntity::reloadTexture()
106 {
107  mLoadedTexture->setSource( QUrl::fromUserInput( mTexturePath ) );
108 }
109 
110 // 6 faces skybox
111 
112 QgsCubeFacesSkyboxEntity::QgsCubeFacesSkyboxEntity( const QString &posX, const QString &posY, const QString &posZ, const QString &negX, const QString &negY, const QString &negZ, Qt3DCore::QNode *parent )
113  : QgsSkyboxEntity( parent )
114  , mGlShader( new Qt3DRender::QShaderProgram() )
115  , mCubeMap( new Qt3DRender::QTextureCubeMap( this ) )
116 {
117  init();
118  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveX] = posX;
119  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveY] = posY;
120  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveZ] = posZ;
121  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeX] = negX;
122  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeY] = negY;
123  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeZ] = negZ;
124  reloadTexture();
125 }
126 
127 void QgsCubeFacesSkyboxEntity::init()
128 {
129  mGlShader->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.vert" ) ) ) );
130  mGlShader->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/skybox.frag" ) ) ) );
131  mGl3RenderPass->setShaderProgram( mGlShader );
132 
133  mCubeMap->setMagnificationFilter( Qt3DRender::QTextureCubeMap::Linear );
134  mCubeMap->setMinificationFilter( Qt3DRender::QTextureCubeMap::Linear );
135  mCubeMap->setGenerateMipMaps( false );
136  mCubeMap->setWrapMode( Qt3DRender::QTextureWrapMode( Qt3DRender::QTextureWrapMode::Repeat ) );
137 
138  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveX] = QString();
139  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveY] = QString();
140  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapPositiveZ] = QString();
141  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeX] = QString();
142  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeY] = QString();
143  mCubeFacesPaths[Qt3DRender::QTextureCubeMap::CubeMapNegativeZ] = QString();
144 
145  mTextureParameter->setName( "skyboxTexture" );
146  mTextureParameter->setValue( QVariant::fromValue( mCubeMap ) );
147 }
148 
149 void QgsCubeFacesSkyboxEntity::reloadTexture()
150 {
151  for ( Qt3DRender::QAbstractTextureImage *textureImage : mFacesTextureImages )
152  {
153  mCubeMap->removeTextureImage( textureImage );
154  delete textureImage;
155  }
156  mFacesTextureImages.clear();
157 
158  for ( auto it = mCubeFacesPaths.begin(); it != mCubeFacesPaths.end(); ++it )
159  {
160  Qt3DRender::QTextureCubeMap::CubeMapFace face = it.key();
161  QString texturePath = it.value();
162  Qt3DRender::QTextureImage *image = new Qt3DRender::QTextureImage( this );
163  image->setFace( face );
164  image->setMirrored( false );
165  image->setSource( QUrl::fromUserInput( texturePath ) );
166  mCubeMap->addTextureImage( image );
167  mFacesTextureImages.push_back( image );
168  }
169 }
QgsCubeFacesSkyboxEntity(const QString &posX, const QString &posY, const QString &posZ, const QString &negX, const QString &negY, const QString &negZ, Qt3DCore::QNode *parent=nullptr)
Constructs a skybox from 6 different images.
QgsPanoramicSkyboxEntity(const QString &texturePath, Qt3DCore::QNode *parent=nullptr)
Construct a skybox from a panoramic 360 image.
Base class for all skybox types.
QgsSkyboxEntity(QNode *parent=nullptr)
Constructor.
Qt3DRender::QRenderPass * mGl3RenderPass
Qt3DRender::QParameter * mGammaStrengthParameter
Qt3DRender::QFilterKey * mFilterKey
Qt3DRender::QEffect * mEffect
Qt3DExtras::QCuboidMesh * mMesh
Qt3DRender::QParameter * mTextureParameter
Qt3DRender::QMaterial * mMaterial
Qt3DRender::QTechnique * mGl3Technique