25#include <Qt3DRender/QBlendEquation>
26#include <Qt3DRender/QBlendEquationArguments>
27#include <Qt3DRender/QEffect>
28#include <Qt3DRender/QGraphicsApiFilter>
29#include <Qt3DRender/QNoDepthMask>
30#include <Qt3DRender/QParameter>
31#include <Qt3DRender/QRenderPass>
32#include <Qt3DRender/QShaderProgram>
33#include <Qt3DRender/QTechnique>
35#include "moc_qgspoint3dbillboardmaterial.cpp"
37using namespace Qt::StringLiterals;
40 : mSize( new
Qt3DRender::QParameter(
"BB_SIZE", QSizeF( 100, 100 ), this ) )
41 , mScaleMode( scaleMode )
48 addParameter( mSize );
54 mViewportSize =
new Qt3DRender::QParameter(
"WIN_SCALE", QSizeF( 800, 600 ),
this );
55 addParameter( mViewportSize );
64 mTexture2D =
new Qt3DRender::QParameter(
"tex0", QVariant(),
this );
65 addParameter( mTexture2D );
68 Qt3DRender::QBlendEquationArguments *blendState =
new Qt3DRender::QBlendEquationArguments;
69 blendState->setSourceRgb( Qt3DRender::QBlendEquationArguments::SourceAlpha );
70 blendState->setDestinationRgb( Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha );
72 Qt3DRender::QBlendEquation *blendEquation =
new Qt3DRender::QBlendEquation;
73 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
76 Qt3DRender::QShaderProgram *shaderProgram =
new Qt3DRender::QShaderProgram(
this );
78 const QUrl urlVert( u
"qrc:/shaders/billboards.vert"_s );
79 QStringList vertexShaderDefines;
83 vertexShaderDefines << u
"TEXTURE_ATLAS"_s;
88 vertexShaderDefines << u
"TEXTURE_ATLAS_PIXEL_OFFSETS"_s;
93 vertexShaderDefines << u
"PER_INSTANCE_SIZE"_s;
98 vertexShaderDefines << u
"VERTICAL_OFFSET"_s;
99 mVerticalOffset =
new Qt3DRender::QParameter(
"VERT_OFFSET", 0.0,
this );
100 addParameter( mVerticalOffset );
103 switch ( mScaleMode )
108 vertexShaderDefines << u
"PERSPECTIVE_SCALE"_s;
112 const QByteArray vertexShaderCode = Qt3DRender::QShaderProgram::loadSource( urlVert );
114 shaderProgram->setVertexShaderCode( finalVertexShaderCode );
116 shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/billboards.frag"_s ) ) );
119 Qt3DRender::QRenderPass *renderPass =
new Qt3DRender::QRenderPass(
this );
120 renderPass->setShaderProgram( shaderProgram );
121 renderPass->addRenderState( blendState );
122 renderPass->addRenderState( blendEquation );
125 Qt3DRender::QFilterKey *filterKey =
new Qt3DRender::QFilterKey;
126 filterKey->setName( u
"renderingStyle"_s );
127 filterKey->setValue(
"forward" );
130 Qt3DRender::QTechnique *technique =
new Qt3DRender::QTechnique;
131 technique->addRenderPass( renderPass );
132 technique->addFilterKey( filterKey );
133 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
134 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
135 technique->graphicsApiFilter()->setMajorVersion( 3 );
136 technique->graphicsApiFilter()->setMinorVersion( 1 );
139 Qt3DRender::QEffect *effect =
new Qt3DRender::QEffect(
this );
140 effect->addTechnique( technique );
149 mSize->setValue(
size );
154 return mSize->value().value<QSizeF>();
159 if ( mVerticalOffset )
161 mVerticalOffset->setValue( offset );
169 mViewportSize->setValue(
size );
177 return mViewportSize->value().value<QSizeF>();
189 setTexture2DFromTextureImage( textureImage );
191 setSize( QSizeF( image.size().width(), image.size().height() ) );
209 std::unique_ptr< QgsMarkerSymbol > clonedSymbol( markerSymbol->
clone() );
210 clonedSymbol->startRender( context2D );
212 constexpr int BUFFER_SIZE_PIXELS = 2;
214 const QRectF bounds = markerSymbol->
bounds( QPointF( 0, 0 ), context2D );
216 QImage image(
static_cast< int >( std::ceil( bounds.size().width() ) ) + 2 * BUFFER_SIZE_PIXELS,
static_cast< int >( std::ceil( bounds.size().height() ) ) + 2 * BUFFER_SIZE_PIXELS, QImage::Format_ARGB32_Premultiplied );
217 image.fill( Qt::transparent );
219 QPainter painter( &image );
222 clonedSymbol->renderPoint( QPointF( -bounds.left() + BUFFER_SIZE_PIXELS, -bounds.top() + BUFFER_SIZE_PIXELS ),
nullptr, context2D, -1, selected );
226 clonedSymbol->stopRender( context2D );
236void QgsPoint3DBillboardMaterial::setTexture2DFromTextureImage( Qt3DRender::QAbstractTextureImage *textureImage )
239 Qt3DRender::QTexture2D *texture2D =
new Qt3DRender::QTexture2D(
this );
240 texture2D->setGenerateMipMaps(
false );
241 texture2D->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
242 texture2D->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
243 texture2D->setFormat( Qt3DRender::QAbstractTexture::SRGB8_Alpha8 );
246 texture2D->addTextureImage( textureImage );
248 mTexture2D->setValue( QVariant::fromValue( texture2D ) );
BillboardScaleMode
3D billboard scaling modes.
@ ViewIndependent
Billboard has a fixed pixel size on the screen, regardless of the camera distance.
@ Perspective
Billboard size is scaled with perspective distance from camera, using world units.
@ Antialiasing
Use antialiasing while drawing.
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
Rendering context for preparation of 3D entities.
QColor selectionColor() const
Returns color used for selected features.
double outputDpi() const
Returns DPI used for conversion between real world units (e.g.
static QByteArray addDefinesToShaderCode(const QByteArray &shaderCode, const QStringList &defines)
Inserts some define macros into a shader source code.
Holds an image that can be used as a texture in the 3D view.
A marker symbol type, for rendering Point and MultiPoint geometries.
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
QRectF bounds(QPointF point, QgsRenderContext &context, const QgsFeature &feature=QgsFeature()) const
Returns the approximate bounding box of the marker symbol, which includes the bounding box of all sym...
void setCastsShadows(bool enabled)
Sets whether the material should cast shadows.
void useDefaultSymbol(const Qgs3DRenderContext &context, bool selected=false)
Set default symbol for the texture with context and selected parameter for rendering.
QFlags< ExtraAttribute > ExtraAttributes
static QImage renderSymbolToImage(const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected=false)
Renders a marker symbol to an image.
void setVerticalOffset(float offset)
Set the vertical offset.
QSizeF windowSize() const
Returns the size of the view port.
void setTexture2DFromImage(const QImage &image)
Set the texture2D of the billboard from an image.
~QgsPoint3DBillboardMaterial() override
QSizeF size() const
Returns the billboard size.
QgsPoint3DBillboardMaterial(ExtraAttributes attributes=ExtraAttributes(), Qgis::BillboardScaleMode scaleMode=Qgis::BillboardScaleMode::ViewIndependent)
Constructor for QgsPoint3DBillboardMaterial, using the specified additional attributes.
void setTexture2DFromSymbol(const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected=false)
Set markerSymbol for the texture with context and selected parameter for rendering.
void setViewportSize(const QSizeF size)
Set the size of the view port.
void setSize(const QSizeF size)
Set the billboard size.
Contains information about the context of a rendering operation.
void setScaleFactor(double factor)
Sets the scaling factor for the render to convert painter units to physical sizes.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected).
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
void setSelectionColor(const QColor &color)
Sets the color to use when rendering selected features.
static QgsSymbol * defaultSymbol(Qgis::GeometryType geomType)
Returns a new default symbol for the specified geometry type.