QGIS API Documentation 3.99.0-Master (8e76e220402)
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/QTextureDataUpdate>
28
29#include "moc_qgsmapoverlayentity.cpp"
30
32
33QgsMapOverlayEntity::QgsMapOverlayEntity( QgsWindow3DEngine *engine, QgsOverlayTextureRenderView *debugTextureRenderView, Qgs3DMapSettings *mapSettings, Qt3DCore::QNode *parent )
34 : QgsOverlayTextureEntity( new Qt3DRender::QTexture2D(), debugTextureRenderView->overlayLayer(), parent )
35 , mEngine( engine )
36 , mMapSettings( mapSettings )
37 , mTextureGenerator( new QgsMapOverlayTextureGenerator( *mapSettings, SIZE() ) )
38{
39 Qt3DRender::QTexture2D *mapTexture = mTextureParameter->value().value<Qt3DRender::QTexture2D *>();
40 mapTexture->setFormat( Qt3DRender::QAbstractTexture::RGBA8_UNorm );
41 mapTexture->setWidth( SIZE() );
42 mapTexture->setHeight( SIZE() );
43 mapTexture->setGenerateMipMaps( false );
44 mapTexture->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
45 mapTexture->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
46 mapTexture->setWrapMode( Qt3DRender::QTextureWrapMode( Qt3DRender::QTextureWrapMode::ClampToEdge ) );
47
48 mIsDepth->setValue( false );
49 mFlipTextureY->setValue( false );
50
51 mImageDataPtr = Qt3DRender::QTextureImageDataPtr::create();
52 mImageDataPtr->setTarget( QOpenGLTexture::Target2D );
53 mImageDataPtr->setFormat( QOpenGLTexture::RGB8_UNorm );
54 mImageDataPtr->setPixelFormat( QOpenGLTexture::RGB );
55 mImageDataPtr->setPixelType( QOpenGLTexture::UInt8 );
56
57 mImageDataPtr->setWidth( SIZE() );
58 mImageDataPtr->setHeight( SIZE() );
59 mImageDataPtr->setDepth( 1 );
60 mImageDataPtr->setLayers( 1 );
61 mImageDataPtr->setMipLevels( 1 );
62 mImageDataPtr->setFaces( 1 );
63
64 onSizeChanged();
65 connect( mEngine, &QgsWindow3DEngine::sizeChanged, this, &QgsMapOverlayEntity::onSizeChanged );
66
67 connect( mTextureGenerator, &QgsMapOverlayTextureGenerator::textureReady, this, &QgsMapOverlayEntity::onTextureReady );
68
69 connectToLayersRepaintRequest();
70 connect( mapSettings, &Qgs3DMapSettings::layersChanged, this, &QgsMapOverlayEntity::onLayersChanged );
71}
72
73QgsMapOverlayEntity::~QgsMapOverlayEntity()
74{
75 delete mTextureGenerator;
76}
77
78void QgsMapOverlayEntity::update( const QgsRectangle &extent, const QVector<QgsPointXY> &frustumExtent, double rotationDegrees, bool showFrustum )
79{
80 if ( !extent.isEmpty() )
81 {
82 mExtent = extent;
83 mFrustumExtent = frustumExtent;
84 mRotation = rotationDegrees;
85 mShowFrustum = showFrustum;
86 mTextureGenerator->render( extent, frustumExtent, rotationDegrees, showFrustum );
87 }
88}
89
90void QgsMapOverlayEntity::invalidateMapImage()
91{
92 update( mExtent, mFrustumExtent, mRotation, mShowFrustum );
93}
94
95void QgsMapOverlayEntity::onLayersChanged()
96{
97 connectToLayersRepaintRequest();
98 invalidateMapImage();
99}
100
101void QgsMapOverlayEntity::connectToLayersRepaintRequest()
102{
103 for ( QgsMapLayer *layer : std::as_const( mLayers ) )
104 {
105 disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapOverlayEntity::invalidateMapImage );
106 }
107
108 mLayers = mMapSettings->layers();
109
110 for ( QgsMapLayer *layer : std::as_const( mLayers ) )
111 {
112 connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapOverlayEntity::invalidateMapImage );
113 }
114}
115
116void QgsMapOverlayEntity::onTextureReady( const QImage &image )
117{
118 Qt3DRender::QTexture2D *mapTexture = mTextureParameter->value().value<Qt3DRender::QTexture2D *>();
119 if ( mapTexture )
120 {
121 mImageDataPtr->setImage( image );
122 Qt3DRender::QTextureDataUpdate textureDataUpdate;
123 textureDataUpdate.setData( mImageDataPtr );
124 mapTexture->updateData( textureDataUpdate );
125 }
126}
127
128void QgsMapOverlayEntity::onSizeChanged()
129{
130 QWindow *canvas = mEngine->window();
131 const float currentHeightF = static_cast<float>( canvas->height() );
132 const float currentWidthF = static_cast<float>( canvas->width() );
133 const float offsetDim = 20.;
134 const float textureDim = static_cast<float>( SIZE() );
135
136 const QSizeF size( textureDim / currentWidthF, textureDim / currentHeightF );
137 const QSizeF offset( offsetDim / currentWidthF, offsetDim / currentHeightF );
138 setPosition( Qt::Corner::BottomLeftCorner, size, offset );
139}
140
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.