18#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
19#include <Qt3DRender/QAttribute>
20#include <Qt3DRender/QBuffer>
25#include <Qt3DCore/QAttribute>
26#include <Qt3DCore/QBuffer>
33#include "moc_qgsbillboardgeometry.cpp"
39 setMode( Mode::PositionOnly );
42void QgsBillboardGeometry::setMode( Mode mode )
47 case Mode::PositionOnly:
48 stride = 3 *
sizeof( float );
50 case Mode::PositionAndTextureData:
51 stride = ( 3 + 2 + 2 ) *
sizeof(
float );
53 case Mode::PositionAndTextureDataWithPixelOffsets:
54 stride = ( 3 + 2 + 2 ) *
sizeof(
float ) + 2 *
sizeof( int );
58 if ( mPositionAttribute && mPositionAttribute->byteStride() == stride )
63 else if ( mPositionAttribute )
65 removeAttribute( mPositionAttribute );
66 delete mPositionAttribute;
67 mPositionAttribute =
nullptr;
71 mPositionAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
72 mPositionAttribute->setBuffer( mVertexBuffer );
73 mPositionAttribute->setVertexBaseType( Qt3DQAttribute::Float );
74 mPositionAttribute->setVertexSize( 3 );
75 mPositionAttribute->setByteOffset( 0 );
76 mPositionAttribute->setByteStride( stride );
77 mPositionAttribute->setName( Qt3DQAttribute::defaultPositionAttributeName() );
78 addAttribute( mPositionAttribute );
82 case Mode::PositionOnly:
84 if ( mAtlasOffsetAttribute )
86 removeAttribute( mAtlasOffsetAttribute );
87 delete mAtlasOffsetAttribute;
88 mAtlasOffsetAttribute =
nullptr;
90 if ( mAtlasSizeAttribute )
92 removeAttribute( mAtlasSizeAttribute );
93 delete mAtlasSizeAttribute;
94 mAtlasSizeAttribute =
nullptr;
96 if ( mAtlasPixelOffsetAttribute )
98 removeAttribute( mAtlasPixelOffsetAttribute );
99 delete mAtlasPixelOffsetAttribute;
100 mAtlasPixelOffsetAttribute =
nullptr;
105 case Mode::PositionAndTextureData:
107 if ( mAtlasPixelOffsetAttribute )
109 removeAttribute( mAtlasPixelOffsetAttribute );
110 delete mAtlasPixelOffsetAttribute;
111 mAtlasPixelOffsetAttribute =
nullptr;
115 mAtlasOffsetAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
116 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
117 mAtlasOffsetAttribute->setVertexBaseType( Qt3DQAttribute::Float );
118 mAtlasOffsetAttribute->setVertexSize( 2 );
119 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
120 mAtlasOffsetAttribute->setByteStride( stride );
121 mAtlasOffsetAttribute->setName( QStringLiteral(
"atlasOffset" ) );
122 addAttribute( mAtlasOffsetAttribute );
125 mAtlasSizeAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
126 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
127 mAtlasSizeAttribute->setVertexBaseType( Qt3DQAttribute::Float );
128 mAtlasSizeAttribute->setVertexSize( 2 );
129 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
130 mAtlasSizeAttribute->setByteStride( stride );
131 mAtlasSizeAttribute->setName( QStringLiteral(
"atlasSize" ) );
132 addAttribute( mAtlasSizeAttribute );
136 case Mode::PositionAndTextureDataWithPixelOffsets:
139 mAtlasOffsetAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
140 mAtlasOffsetAttribute->setBuffer( mVertexBuffer );
141 mAtlasOffsetAttribute->setVertexBaseType( Qt3DQAttribute::Float );
142 mAtlasOffsetAttribute->setVertexSize( 2 );
143 mAtlasOffsetAttribute->setByteOffset( 3 *
sizeof(
float ) );
144 mAtlasOffsetAttribute->setByteStride( stride );
145 mAtlasOffsetAttribute->setName( QStringLiteral(
"atlasOffset" ) );
146 addAttribute( mAtlasOffsetAttribute );
149 mAtlasSizeAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
150 mAtlasSizeAttribute->setBuffer( mVertexBuffer );
151 mAtlasSizeAttribute->setVertexBaseType( Qt3DQAttribute::Float );
152 mAtlasSizeAttribute->setVertexSize( 2 );
153 mAtlasSizeAttribute->setByteOffset( ( 3 + 2 ) *
sizeof(
float ) );
154 mAtlasSizeAttribute->setByteStride( stride );
155 mAtlasSizeAttribute->setName( QStringLiteral(
"atlasSize" ) );
156 addAttribute( mAtlasSizeAttribute );
159 mAtlasPixelOffsetAttribute->setAttributeType( Qt3DQAttribute::VertexAttribute );
160 mAtlasPixelOffsetAttribute->setBuffer( mVertexBuffer );
161 mAtlasPixelOffsetAttribute->setVertexBaseType( Qt3DQAttribute::Int );
162 mAtlasPixelOffsetAttribute->setVertexSize( 2 );
163 mAtlasPixelOffsetAttribute->setByteOffset( ( 3 + 2 + 2 ) *
sizeof(
float ) );
164 mAtlasPixelOffsetAttribute->setByteStride( stride );
165 mAtlasPixelOffsetAttribute->setName( QStringLiteral(
"pixelOffset" ) );
166 addAttribute( mAtlasPixelOffsetAttribute );
174 setMode( Mode::PositionOnly );
176 QByteArray vertexBufferData;
177 vertexBufferData.resize( vertices.size() * 3 *
sizeof(
float ) );
178 float *rawVertexArray =
reinterpret_cast<float *
>( vertexBufferData.data() );
180 for (
const auto &v : vertices )
182 rawVertexArray[idx++] = v.x();
183 rawVertexArray[idx++] = v.y();
184 rawVertexArray[idx++] = v.z();
187 mVertexCount = vertices.count();
188 mVertexBuffer->setData( vertexBufferData );
194#pragma pack( push, 1 )
195struct BillboardVertex
198 float textureAtlasOffset[2];
199 float textureAtlasSize[2];
202struct BillboardVertexWithPixelOffset : BillboardVertex
208template<
typename VertexType>
209QByteArray createVertexBuffer(
const QVector<QgsBillboardGeometry::BillboardAtlasData> &billboards )
212 buffer.resize( billboards.size() *
sizeof( VertexType ) );
213 auto *vertexData =
reinterpret_cast<VertexType *
>( buffer.data() );
218 VertexType &vertex = vertexData[idx++];
220 vertex.position[0] = billboard.position.x();
221 vertex.position[1] = billboard.position.y();
222 vertex.position[2] = billboard.position.z();
224 vertex.textureAtlasOffset[0] = billboard.textureAtlasOffset.x();
225 vertex.textureAtlasOffset[1] = billboard.textureAtlasOffset.y();
227 vertex.textureAtlasSize[0] = billboard.textureAtlasSize.x();
228 vertex.textureAtlasSize[1] = billboard.textureAtlasSize.y();
230 if constexpr ( std::is_same_v<VertexType, BillboardVertexWithPixelOffset> )
232 vertex.pixelOffset[0] = billboard.pixelOffset.x();
233 vertex.pixelOffset[1] = billboard.pixelOffset.y();
242 if ( includePixelOffsets )
243 setMode( Mode::PositionAndTextureDataWithPixelOffsets );
245 setMode( Mode::PositionAndTextureData );
248 QByteArray vertexBufferData;
249 if ( includePixelOffsets )
251 vertexBufferData = createVertexBuffer<BillboardVertexWithPixelOffset>( billboards );
255 vertexBufferData = createVertexBuffer<BillboardVertex>( billboards );
258 mVertexCount = billboards.count();
259 mVertexBuffer->setData( vertexBufferData );
void countChanged(int count)
Signal when the number of points changed.
void setBillboardData(const QVector< QgsBillboardGeometry::BillboardAtlasData > &billboards, bool includePixelOffsets=false)
Set the position and texture data for the billboard.
void setPositions(const QVector< QVector3D > &vertices)
Sets the vertex positions for the billboards.
QgsBillboardGeometry(Qt3DCore::QNode *parent=nullptr)
Constructor of QgsBillboardGeometry.
Qt3DCore::QAttribute Qt3DQAttribute
Qt3DCore::QBuffer Qt3DQBuffer
Contains the billboard positions and texture information.