QGIS API Documentation 4.3.0-Master (18b5e825726)
Loading...
Searching...
No Matches
qgsmapoverlayentity.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmapoverlayentity.cpp
3 --------------------------------------
4 Date : July 2025
5 Copyright : (C) 2025 by Jean Felder
6 Email : jean dot felder at oslandia dot com
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 "qgsmapoverlayentity.h"
17
18#include "qgs3dmapsettings.h"
22#include "qgswindow3dengine.h"
23
24#include <QOpenGLTexture>
25#include <QWindow>
26#include <Qt3DExtras/QTextureMaterial>
27#include <Qt3DRender/QParameter>
28#include <Qt3DRender/QTextureDataUpdate>
29
30#include "moc_qgsmapoverlayentity.cpp"
31
33
34QgsMapOverlayEntity::QgsMapOverlayEntity( QgsWindow3DEngine *engine, QgsOverlayTextureRenderView *debugTextureRenderView, Qgs3DMapSettings *mapSettings, Qt3DCore::QNode *parent )
35 : QgsOverlayTextureEntity( new Qt3DRender::QTexture2D(), debugTextureRenderView->overlayLayer(), parent )
36 , mEngine( engine )
37 , mMapSettings( mapSettings )
38 , mTextureGenerator( std::make_unique<QgsMapOverlayTextureGenerator>( *mapSettings, SIZE() ) )
39{
40 Qt3DRender::QTexture2D *mapTexture = mTextureParameter->value().value<Qt3DRender::QTexture2D *>();
41 mapTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA8_UNorm );
42 mapTexture->setWidth( SIZE() );
43 mapTexture->setHeight( SIZE() );
44 mapTexture->setGenerateMipMaps( false );
45 mapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
46 mapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
47 mapTexture->setWrapMode( Qt3DRender::QTextureWrapMode( Qt3DRender::QTextureWrapMode::ClampToEdge ) );
48
49 mIsDepth->setValue( false );
50 mFlipTextureY->setValue( false );
51
52 mImageDataPtr = Qt3DRender::QTextureImageDataPtr::create();
53 mImageDataPtr->setTarget( QOpenGLTexture::Target2D );
54 mImageDataPtr->setFormat( QOpenGLTexture::RGB8_UNorm );
55 mImageDataPtr->setPixelFormat( QOpenGLTexture::RGB );
56 mImageDataPtr->setPixelType( QOpenGLTexture::UInt8 );
57
58 mImageDataPtr->setWidth( SIZE() );
59 mImageDataPtr->setHeight( SIZE() );
60 mImageDataPtr->setDepth( 1 );
61 mImageDataPtr->setLayers( 1 );
62 mImageDataPtr->setMipLevels( 1 );
63 mImageDataPtr->setFaces( 1 );
64
65 onSizeChanged();
66 connect( mEngine, &QgsWindow3DEngine::sizeChanged, this, &QgsMapOverlayEntity::onSizeChanged );
67
68 connect( mTextureGenerator.get(), &QgsMapOverlayTextureGenerator::textureReady, this, &QgsMapOverlayEntity::onTextureReady );
69
70 connectToLayersRepaintRequest();
71 connect( mapSettings, &Qgs3DMapSettings::layersChanged, this, &QgsMapOverlayEntity::onLayersChanged );
72}
73
74QgsMapOverlayEntity::~QgsMapOverlayEntity()
75{}
76
77void QgsMapOverlayEntity::update( const QgsRectangle &extent, const QVector<QgsPointXY> &frustumExtent, double rotationDegrees, bool showFrustum )
78{
79 if ( !extent.isEmpty() )
80 {
81 mExtent = extent;
82 mFrustumExtent = frustumExtent;
83 mRotation = rotationDegrees;
84 mShowFrustum = showFrustum;
85 mTextureGenerator->render( extent, frustumExtent, rotationDegrees, showFrustum );
86 }
87}
88
89void QgsMapOverlayEntity::invalidateMapImage()
90{
91 update( mExtent, mFrustumExtent, mRotation, mShowFrustum );
92}
93
94void QgsMapOverlayEntity::onLayersChanged()
95{
96 connectToLayersRepaintRequest();
97 invalidateMapImage();
98}
99
100void QgsMapOverlayEntity::connectToLayersRepaintRequest()
101{
102 for ( QgsMapLayer *layer : std::as_const( mLayers ) )
103 {
104 disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapOverlayEntity::invalidateMapImage );
105 }
106
107 mLayers = mMapSettings->layers();
108
109 for ( QgsMapLayer *layer : std::as_const( mLayers ) )
110 {
111 connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapOverlayEntity::invalidateMapImage );
112 }
113}
114
115void QgsMapOverlayEntity::onTextureReady( const QImage &image )
116{
117 Qt3DRender::QTexture2D *mapTexture = mTextureParameter->value().value<Qt3DRender::QTexture2D *>();
118 if ( mapTexture )
119 {
120 mImageDataPtr->setImage( image );
121 Qt3DRender::QTextureDataUpdate textureDataUpdate;
122 textureDataUpdate.setData( mImageDataPtr );
123 mapTexture->updateData( textureDataUpdate );
124 }
125}
126
127void QgsMapOverlayEntity::onSizeChanged()
128{
129 QWindow *canvas = mEngine->window();
130 const float currentHeightF = static_cast<float>( canvas->height() );
131 const float currentWidthF = static_cast<float>( canvas->width() );
132 const float offsetDim = 20.;
133 const float textureDim = static_cast<float>( SIZE() );
134
135 const QSizeF size( textureDim / currentWidthF, textureDim / currentHeightF );
136 const QSizeF offset( offsetDim / currentWidthF, offsetDim / currentHeightF );
137 setPosition( Qt::Corner::BottomLeftCorner, size, offset );
138}
139
Definition of the world.
void layersChanged()
Emitted when the list of map layers for 3d rendering has changed.
void sizeChanged()
Emitted after a call to setSize().
Base class for all map layer types.
Definition qgsmaplayer.h:83
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
An entity responsible for rendering an overlay texture in 3D view.
Simple render view to preview overlay textures in 3D view.
A rectangle specified with double values.
On-screen 3D engine: it creates an OpenGL window (QWindow) and displays rendered 3D scenes there.