|
32 | 32 | PointEntity::PointEntity( const Map3D &map, QgsVectorLayer *layer, const Point3DSymbol &symbol, Qt3DCore::QNode *parent )
|
33 | 33 | : Qt3DCore::QEntity( parent )
|
34 | 34 | {
|
35 |
| - QgsFeatureRequest request; |
36 |
| - request.setDestinationCrs( map.crs ); |
37 |
| - QList<QVector3D> pos = positions( map, layer, request ); |
| 35 | + addEntityForSelectedPoints( map, layer, symbol ); |
| 36 | + addEntityForNotSelectedPoints( map, layer, symbol ); |
| 37 | +} |
38 | 38 |
|
39 |
| - addComponent( renderer( symbol, pos ) ); |
40 |
| - addComponent( material( map, symbol ) ); |
| 39 | +Qt3DRender::QMaterial *PointEntity::material( const Point3DSymbol &symbol ) const |
| 40 | +{ |
| 41 | + Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey; |
| 42 | + filterKey->setName( "renderingStyle" ); |
| 43 | + filterKey->setValue( "forward" ); |
| 44 | + |
| 45 | + // the fragment shader implements a simplified version of phong shading that uses hardcoded light |
| 46 | + // (instead of whatever light we have defined in the scene) |
| 47 | + // TODO: use phong shading that respects lights from the scene |
| 48 | + Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram; |
| 49 | + shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/instanced.vert" ) ) ); |
| 50 | + shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/instanced.frag" ) ) ); |
| 51 | + |
| 52 | + Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass; |
| 53 | + renderPass->setShaderProgram( shaderProgram ); |
| 54 | + |
| 55 | + Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique; |
| 56 | + technique->addFilterKey( filterKey ); |
| 57 | + technique->addRenderPass( renderPass ); |
| 58 | + technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL ); |
| 59 | + technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile ); |
| 60 | + technique->graphicsApiFilter()->setMajorVersion( 3 ); |
| 61 | + technique->graphicsApiFilter()->setMinorVersion( 2 ); |
| 62 | + |
| 63 | + Qt3DRender::QParameter *ambientParameter = new Qt3DRender::QParameter( QStringLiteral( "ka" ), QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) ); |
| 64 | + Qt3DRender::QParameter *diffuseParameter = new Qt3DRender::QParameter( QStringLiteral( "kd" ), QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) ); |
| 65 | + Qt3DRender::QParameter *specularParameter = new Qt3DRender::QParameter( QStringLiteral( "ks" ), QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) ); |
| 66 | + Qt3DRender::QParameter *shininessParameter = new Qt3DRender::QParameter( QStringLiteral( "shininess" ), 150.0f ); |
| 67 | + |
| 68 | + diffuseParameter->setValue( symbol.material.diffuse() ); |
| 69 | + ambientParameter->setValue( symbol.material.ambient() ); |
| 70 | + specularParameter->setValue( symbol.material.specular() ); |
| 71 | + shininessParameter->setValue( symbol.material.shininess() ); |
| 72 | + |
| 73 | + QMatrix4x4 transformMatrix = symbol.transform; |
| 74 | + QMatrix3x3 normalMatrix = transformMatrix.normalMatrix(); // transponed inverse of 3x3 sub-matrix |
| 75 | + |
| 76 | + // QMatrix3x3 is not supported for passing to shaders, so we pass QMatrix4x4 |
| 77 | + float *n = normalMatrix.data(); |
| 78 | + QMatrix4x4 normalMatrix4( |
| 79 | + n[0], n[3], n[6], 0, |
| 80 | + n[1], n[4], n[7], 0, |
| 81 | + n[2], n[5], n[8], 0, |
| 82 | + 0, 0, 0, 0 ); |
| 83 | + |
| 84 | + Qt3DRender::QParameter *paramInst = new Qt3DRender::QParameter; |
| 85 | + paramInst->setName( "inst" ); |
| 86 | + paramInst->setValue( transformMatrix ); |
| 87 | + |
| 88 | + Qt3DRender::QParameter *paramInstNormal = new Qt3DRender::QParameter; |
| 89 | + paramInstNormal->setName( "instNormal" ); |
| 90 | + paramInstNormal->setValue( normalMatrix4 ); |
| 91 | + |
| 92 | + Qt3DRender::QEffect *effect = new Qt3DRender::QEffect; |
| 93 | + effect->addTechnique( technique ); |
| 94 | + effect->addParameter( paramInst ); |
| 95 | + effect->addParameter( paramInstNormal ); |
| 96 | + |
| 97 | + effect->addParameter( ambientParameter ); |
| 98 | + effect->addParameter( diffuseParameter ); |
| 99 | + effect->addParameter( specularParameter ); |
| 100 | + effect->addParameter( shininessParameter ); |
| 101 | + |
| 102 | + Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial; |
| 103 | + material->setEffect( effect ); |
| 104 | + |
| 105 | + return material; |
41 | 106 | }
|
42 | 107 |
|
43 |
| -PointEntity::PointEntity( const Map3D &map, QgsVectorLayer *layer, const Point3DSymbol &symbol, bool sel, Qt3DCore::QNode *parent ) |
44 |
| - : Qt3DCore::QEntity( parent ) |
| 108 | +void PointEntity::addEntityForSelectedPoints( const Map3D &map, QgsVectorLayer *layer, const Point3DSymbol &symbol ) |
45 | 109 | {
|
46 |
| - QgsFeatureRequest request; |
47 |
| - request.setDestinationCrs( map.crs ); |
| 110 | + // build the default material |
| 111 | + Qt3DRender::QMaterial *mat = material( symbol ); |
48 | 112 |
|
49 |
| - if ( sel ) |
50 |
| - request.setFilterFids( layer->selectedFeatureIds() ); |
51 |
| - else |
| 113 | + // update the material with selection colors |
| 114 | + Q_FOREACH ( Qt3DRender::QParameter *param, mat->effect()->parameters() ) |
52 | 115 | {
|
53 |
| - QgsFeatureIds notSelected = layer->allFeatureIds(); |
54 |
| - notSelected.subtract( layer->selectedFeatureIds() ); |
55 |
| - request.setFilterFids( notSelected ); |
| 116 | + if ( param->name() == "kd" ) // diffuse |
| 117 | + param->setValue( map.selectionColor() ); |
| 118 | + else if ( param->name() == "ka" ) // ambient |
| 119 | + param->setValue( map.selectionColor().darker() ); |
56 | 120 | }
|
57 | 121 |
|
58 |
| - QList<QVector3D> pos = positions( map, layer, request ); |
| 122 | + // build the feature request to select features |
| 123 | + QgsFeatureRequest req; |
| 124 | + req.setDestinationCrs( map.crs ); |
| 125 | + req.setFilterFids( layer->selectedFeatureIds() ); |
| 126 | + |
| 127 | + // build the entity |
| 128 | + PointEntityNode *entity = new PointEntityNode( map, layer, symbol, req ); |
| 129 | + entity->addComponent( mat ); |
| 130 | + entity->setParent( this ); |
| 131 | +} |
| 132 | + |
| 133 | +void PointEntity::addEntityForNotSelectedPoints( const Map3D &map, QgsVectorLayer *layer, const Point3DSymbol &symbol ) |
| 134 | +{ |
| 135 | + // build the default material |
| 136 | + Qt3DRender::QMaterial *mat = material( symbol ); |
| 137 | + |
| 138 | + // build the feature request to select features |
| 139 | + QgsFeatureRequest req; |
| 140 | + req.setDestinationCrs( map.crs ); |
| 141 | + |
| 142 | + QgsFeatureIds notSelected = layer->allFeatureIds(); |
| 143 | + notSelected.subtract( layer->selectedFeatureIds() ); |
| 144 | + req.setFilterFids( notSelected ); |
59 | 145 |
|
| 146 | + // build the entity |
| 147 | + PointEntityNode *entity = new PointEntityNode( map, layer, symbol, req ); |
| 148 | + entity->addComponent( mat ); |
| 149 | + entity->setParent( this ); |
| 150 | +} |
| 151 | + |
| 152 | +PointEntityNode::PointEntityNode( const Map3D &map, QgsVectorLayer *layer, const Point3DSymbol &symbol, const QgsFeatureRequest &req, Qt3DCore::QNode *parent ) |
| 153 | + : Qt3DCore::QEntity( parent ) |
| 154 | +{ |
| 155 | + QList<QVector3D> pos = positions( map, layer, req ); |
60 | 156 | addComponent( renderer( symbol, pos ) );
|
61 |
| - addComponent( material( map, symbol, sel ) ); |
62 | 157 | }
|
63 | 158 |
|
64 |
| -Qt3DRender::QGeometryRenderer *PointEntity::renderer( const Point3DSymbol &symbol, const QList<QVector3D> &positions ) const |
| 159 | +Qt3DRender::QGeometryRenderer *PointEntityNode::renderer( const Point3DSymbol &symbol, const QList<QVector3D> &positions ) const |
65 | 160 | {
|
66 | 161 | int count = positions.count();
|
67 | 162 |
|
@@ -168,82 +263,7 @@ Qt3DRender::QGeometryRenderer *PointEntity::renderer( const Point3DSymbol &symbo
|
168 | 263 | return renderer;
|
169 | 264 | }
|
170 | 265 |
|
171 |
| -Qt3DRender::QMaterial *PointEntity::material( const Map3D &map, const Point3DSymbol &symbol, bool sel ) const |
172 |
| -{ |
173 |
| - Qt3DRender::QFilterKey *filterKey = new Qt3DRender::QFilterKey; |
174 |
| - filterKey->setName( "renderingStyle" ); |
175 |
| - filterKey->setValue( "forward" ); |
176 |
| - |
177 |
| - // the fragment shader implements a simplified version of phong shading that uses hardcoded light |
178 |
| - // (instead of whatever light we have defined in the scene) |
179 |
| - // TODO: use phong shading that respects lights from the scene |
180 |
| - Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram; |
181 |
| - shaderProgram->setVertexShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/instanced.vert" ) ) ); |
182 |
| - shaderProgram->setFragmentShaderCode( Qt3DRender::QShaderProgram::loadSource( QUrl( "qrc:/shaders/instanced.frag" ) ) ); |
183 |
| - |
184 |
| - Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass; |
185 |
| - renderPass->setShaderProgram( shaderProgram ); |
186 |
| - |
187 |
| - Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique; |
188 |
| - technique->addFilterKey( filterKey ); |
189 |
| - technique->addRenderPass( renderPass ); |
190 |
| - technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL ); |
191 |
| - technique->graphicsApiFilter()->setProfile( Qt3DRender::QGraphicsApiFilter::CoreProfile ); |
192 |
| - technique->graphicsApiFilter()->setMajorVersion( 3 ); |
193 |
| - technique->graphicsApiFilter()->setMinorVersion( 2 ); |
194 |
| - |
195 |
| - Qt3DRender::QParameter *ambientParameter = new Qt3DRender::QParameter( QStringLiteral( "ka" ), QColor::fromRgbF( 0.05f, 0.05f, 0.05f, 1.0f ) ); |
196 |
| - Qt3DRender::QParameter *diffuseParameter = new Qt3DRender::QParameter( QStringLiteral( "kd" ), QColor::fromRgbF( 0.7f, 0.7f, 0.7f, 1.0f ) ); |
197 |
| - Qt3DRender::QParameter *specularParameter = new Qt3DRender::QParameter( QStringLiteral( "ks" ), QColor::fromRgbF( 0.01f, 0.01f, 0.01f, 1.0f ) ); |
198 |
| - Qt3DRender::QParameter *shininessParameter = new Qt3DRender::QParameter( QStringLiteral( "shininess" ), 150.0f ); |
199 |
| - |
200 |
| - diffuseParameter->setValue( symbol.material.diffuse() ); |
201 |
| - ambientParameter->setValue( symbol.material.ambient() ); |
202 |
| - specularParameter->setValue( symbol.material.specular() ); |
203 |
| - shininessParameter->setValue( symbol.material.shininess() ); |
204 |
| - |
205 |
| - if ( sel ) |
206 |
| - { |
207 |
| - diffuseParameter->setValue( map.selectionColor() ); |
208 |
| - ambientParameter->setValue( map.selectionColor().darker() ); |
209 |
| - } |
210 |
| - |
211 |
| - QMatrix4x4 transformMatrix = symbol.transform; |
212 |
| - QMatrix3x3 normalMatrix = transformMatrix.normalMatrix(); // transponed inverse of 3x3 sub-matrix |
213 |
| - |
214 |
| - // QMatrix3x3 is not supported for passing to shaders, so we pass QMatrix4x4 |
215 |
| - float *n = normalMatrix.data(); |
216 |
| - QMatrix4x4 normalMatrix4( |
217 |
| - n[0], n[3], n[6], 0, |
218 |
| - n[1], n[4], n[7], 0, |
219 |
| - n[2], n[5], n[8], 0, |
220 |
| - 0, 0, 0, 0 ); |
221 |
| - |
222 |
| - Qt3DRender::QParameter *paramInst = new Qt3DRender::QParameter; |
223 |
| - paramInst->setName( "inst" ); |
224 |
| - paramInst->setValue( transformMatrix ); |
225 |
| - |
226 |
| - Qt3DRender::QParameter *paramInstNormal = new Qt3DRender::QParameter; |
227 |
| - paramInstNormal->setName( "instNormal" ); |
228 |
| - paramInstNormal->setValue( normalMatrix4 ); |
229 |
| - |
230 |
| - Qt3DRender::QEffect *effect = new Qt3DRender::QEffect; |
231 |
| - effect->addTechnique( technique ); |
232 |
| - effect->addParameter( paramInst ); |
233 |
| - effect->addParameter( paramInstNormal ); |
234 |
| - |
235 |
| - effect->addParameter( ambientParameter ); |
236 |
| - effect->addParameter( diffuseParameter ); |
237 |
| - effect->addParameter( specularParameter ); |
238 |
| - effect->addParameter( shininessParameter ); |
239 |
| - |
240 |
| - Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial; |
241 |
| - material->setEffect( effect ); |
242 |
| - |
243 |
| - return material; |
244 |
| -} |
245 |
| - |
246 |
| -QList<QVector3D> PointEntity::positions( const Map3D &map, const QgsVectorLayer *layer, const QgsFeatureRequest &request ) const |
| 266 | +QList<QVector3D> PointEntityNode::positions( const Map3D &map, const QgsVectorLayer *layer, const QgsFeatureRequest &request ) const |
247 | 267 | {
|
248 | 268 | QList<QVector3D> positions;
|
249 | 269 | QgsFeature f;
|
|
0 commit comments