QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
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
88QgsPanoramicSkyboxEntity::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
105void QgsPanoramicSkyboxEntity::reloadTexture()
106{
107 mLoadedTexture->setSource( QUrl::fromUserInput( mTexturePath ) );
108}
109
110// 6 faces skybox
111
112QgsCubeFacesSkyboxEntity::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
127void 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
149void 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 const Qt3DRender::QTextureCubeMap::CubeMapFace face = it.key();
161 const 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