Use simpler approach to generate texture image for billboards

This commit is contained in:
Nyall Dawson 2025-09-10 14:16:08 +10:00
parent 9bb5086975
commit 17f3665635
2 changed files with 27 additions and 15 deletions

View File

@ -25,7 +25,7 @@
#include "qgspoint3dbillboardmaterial.h"
#include "moc_qgspoint3dbillboardmaterial.cpp"
#include "qgsterraintextureimage_p.h"
#include "qgsimagetexture.h"
#include "qgssymbollayerutils.h"
#include "qgsmarkersymbol.h"
#include "qgs3drendercontext.h"
@ -104,14 +104,15 @@ QSizeF QgsPoint3DBillboardMaterial::windowSize() const
return mViewportSize->value().value<QSizeF>();
}
void QgsPoint3DBillboardMaterial::setTexture2DFromImage( QImage image, double size )
void QgsPoint3DBillboardMaterial::setTexture2DFromImage( const QImage &image )
{
// Create texture image
const QgsRectangle randomExtent = QgsRectangle( rand(), rand(), rand(), rand() );
QgsTerrainTextureImage *billboardTextureImage = new QgsTerrainTextureImage( image, randomExtent, QStringLiteral( "billboard material." ) );
const QImage flippedSymbolImage = image.mirrored();
setTexture2DFromTextureImage( billboardTextureImage );
setSize( QSizeF( size + size, size + size ) );
// Create texture image
QgsImageTexture *textureImage = new QgsImageTexture( flippedSymbolImage );
setTexture2DFromTextureImage( textureImage );
setSize( QSizeF( image.size().width() * 2, image.size().height() * 2 ) );
}
void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DRenderContext &context, bool selected )
@ -121,7 +122,7 @@ void QgsPoint3DBillboardMaterial::useDefaultSymbol( const Qgs3DRenderContext &co
setTexture2DFromSymbol( defaultSymbol.get(), context, selected );
}
void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected )
QImage QgsPoint3DBillboardMaterial::renderSymbolToImage( const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected )
{
QgsRenderContext context2D;
context2D.setSelectionColor( context.selectionColor() );
@ -139,9 +140,13 @@ void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( QgsMarkerSymbol *marke
const double extraPixel = minimumExtraSize > pixelSize * strokeRatio ? minimumExtraSize : pixelSize * strokeRatio;
const int pixelWithExtra = std::ceil( pixelSize + extraPixel );
const QPixmap symbolPixmap = QgsSymbolLayerUtils::symbolPreviewPixmap( markerSymbol, QSize( pixelWithExtra, pixelWithExtra ), 0, &context2D, selected );
const QImage symbolImage = symbolPixmap.toImage();
const QImage flippedSymbolImage = symbolImage.mirrored();
setTexture2DFromImage( flippedSymbolImage, pixelWithExtra );
return symbolPixmap.toImage();
}
void QgsPoint3DBillboardMaterial::setTexture2DFromSymbol( const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected )
{
const QImage symbolImage = renderSymbolToImage( markerSymbol, context, selected );
setTexture2DFromImage( symbolImage );
}
void QgsPoint3DBillboardMaterial::setTexture2DFromTextureImage( Qt3DRender::QAbstractTextureImage *textureImage )

View File

@ -55,13 +55,20 @@ class QgsPoint3DBillboardMaterial : public QgsMaterial
//! Set default symbol for the texture with \a context and \a selected parameter for rendering.
void useDefaultSymbol( const Qgs3DRenderContext &context, bool selected = false );
/**
* Renders a marker symbol to an image.
*
* \since QGIS 4.0
*/
static QImage renderSymbolToImage( const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected = false );
//! Set \a markerSymbol for the texture with \a context and \a selected parameter for rendering.
void setTexture2DFromSymbol( QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected = false );
void setTexture2DFromSymbol( const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected = false );
//! Set the texture2D of the billboard from an \a image.
void setTexture2DFromImage( const QImage &image );
private:
//! Set the texture2D of the billboard from \a image with \a size.
void setTexture2DFromImage( QImage image, double size = 100 );
//! Set texture2D from \a textureImage
void setTexture2DFromTextureImage( Qt3DRender::QAbstractTextureImage *textureImage );