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 , mViewportSize( new
Qt3DRender::QParameter(
"WIN_SCALE", QSizeF( 800, 600 ), this ) )
43 addParameter( mSize );
44 addParameter( mViewportSize );
47 mTexture2D =
new Qt3DRender::QParameter(
"tex0", QVariant(),
this );
48 addParameter( mTexture2D );
51 Qt3DRender::QBlendEquationArguments *blendState =
new Qt3DRender::QBlendEquationArguments;
52 blendState->setSourceRgb( Qt3DRender::QBlendEquationArguments::SourceAlpha );
53 blendState->setDestinationRgb( Qt3DRender::QBlendEquationArguments::OneMinusSourceAlpha );
55 Qt3DRender::QBlendEquation *blendEquation =
new Qt3DRender::QBlendEquation;
56 blendEquation->setBlendFunction( Qt3DRender::QBlendEquation::Add );
59 Qt3DRender::QShaderProgram *shaderProgram =
new Qt3DRender::QShaderProgram(
this );
61 const QUrl urlVert( u
"qrc:/shaders/billboards.vert"_s );
62 const QUrl urlGeom( u
"qrc:/shaders/billboards.geom"_s );
68 shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( urlVert ) );
69 shaderProgram->setGeometryShaderCode( Qt3DRender::QShaderProgram::loadSource( urlGeom ) );
74 const QByteArray vertexShaderCode = Qt3DRender::QShaderProgram::loadSource( urlVert );
76 shaderProgram->setVertexShaderCode( finalVertexShaderCode );
78 const QByteArray geomShaderCode = Qt3DRender::QShaderProgram::loadSource( urlGeom );
80 shaderProgram->setGeometryShaderCode( finalGeomShaderCode );
85 const QByteArray vertexShaderCode = Qt3DRender::QShaderProgram::loadSource( urlVert );
87 shaderProgram->setVertexShaderCode( finalVertexShaderCode );
89 const QByteArray geomShaderCode = Qt3DRender::QShaderProgram::loadSource( urlGeom );
91 shaderProgram->setGeometryShaderCode( finalGeomShaderCode );
95 shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( u
"qrc:/shaders/billboards.frag"_s ) ) );
98 Qt3DRender::QRenderPass *renderPass =
new Qt3DRender::QRenderPass(
this );
99 renderPass->setShaderProgram( shaderProgram );
100 renderPass->addRenderState( blendState );
101 renderPass->addRenderState( blendEquation );
104 Qt3DRender::QFilterKey *filterKey =
new Qt3DRender::QFilterKey;
105 filterKey->setName( u
"renderingStyle"_s );
106 filterKey->setValue(
"forward" );
109 Qt3DRender::QTechnique *technique =
new Qt3DRender::QTechnique;
110 technique->addRenderPass( renderPass );
111 technique->addFilterKey( filterKey );
112 technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL );
113 technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile );
114 technique->graphicsApiFilter()->setMajorVersion( 3 );
115 technique->graphicsApiFilter()->setMinorVersion( 1 );
118 Qt3DRender::QEffect *effect =
new Qt3DRender::QEffect(
this );
119 effect->addTechnique( technique );
128 mSize->setValue(
size );
133 return mSize->value().value<QSizeF>();
138 mViewportSize->setValue(
size );
143 return mViewportSize->value().value<QSizeF>();
150 setTexture2DFromTextureImage( textureImage );
152 setSize( QSizeF( image.size().width(), image.size().height() ) );
170 std::unique_ptr< QgsMarkerSymbol > clonedSymbol( markerSymbol->
clone() );
171 clonedSymbol->startRender( context2D );
173 constexpr int BUFFER_SIZE_PIXELS = 2;
175 const QRectF bounds = markerSymbol->
bounds( QPointF( 0, 0 ), context2D );
177 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 );
178 image.fill( Qt::transparent );
180 QPainter painter( &image );
183 clonedSymbol->renderPoint( QPointF( -bounds.left() + BUFFER_SIZE_PIXELS, -bounds.top() + BUFFER_SIZE_PIXELS ),
nullptr, context2D, -1, selected );
187 clonedSymbol->stopRender( context2D );
197void QgsPoint3DBillboardMaterial::setTexture2DFromTextureImage( Qt3DRender::QAbstractTextureImage *textureImage )
200 Qt3DRender::QTexture2D *texture2D =
new Qt3DRender::QTexture2D(
this );
201 texture2D->setGenerateMipMaps(
false );
202 texture2D->setMagnificationFilter( Qt3DRender::QTexture2D::Linear );
203 texture2D->setMinificationFilter( Qt3DRender::QTexture2D::Linear );
204 texture2D->setFormat( Qt3DRender::QAbstractTexture::SRGB8_Alpha8 );
207 texture2D->addTextureImage( textureImage );
209 mTexture2D->setValue( QVariant::fromValue( texture2D ) );
@ 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 useDefaultSymbol(const Qgs3DRenderContext &context, bool selected=false)
Set default symbol for the texture with context and selected parameter for rendering.
static QImage renderSymbolToImage(const QgsMarkerSymbol *markerSymbol, const Qgs3DRenderContext &context, bool selected=false)
Renders a marker symbol to an image.
@ SingleTexture
Use a single repeated texture for all billboards. Billboard positions should be set using QgsBillboar...
@ AtlasTexture
Use a texture atlas, so each billboard has a different texture. Billboard positions and texture data ...
@ AtlasTextureWithPixelOffsets
Use a texture atlas, so each billboard has a different texture. Billboards have pixel-sized offsets f...
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.
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.
QgsPoint3DBillboardMaterial(Mode mode=Mode::SingleTexture)
Constructor for QgsPoint3DBillboardMaterial, using the specified mode.
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.