mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 04:30:05 +00:00 
			
		
		
		
	Draw a triangle on the map
This commit is contained in:
		
							parent
							
								
									b1e00cca83
								
							
						
					
					
						commit
						79ab14ab95
					
				
					 6 changed files with 250 additions and 364 deletions
				
			
		|  | @ -1,5 +1,7 @@ | |||
| #include "map_widget.hpp" | ||||
| 
 | ||||
| #include <scwx/qt/map/triangle_layer.hpp> | ||||
| 
 | ||||
| #include <QApplication> | ||||
| #include <QColor> | ||||
| #include <QDebug> | ||||
|  | @ -44,8 +46,26 @@ void MapWidget::changeStyle() | |||
|    { | ||||
|       currentStyleIndex = 0; | ||||
|    } | ||||
| } | ||||
| void MapWidget::AddLayers() | ||||
| { | ||||
|    // QMapboxGL::addCustomLayer will take ownership of the QScopedPointer
 | ||||
|    QScopedPointer<QMapbox::CustomLayerHostInterface> pHost(new TriangleLayer()); | ||||
| 
 | ||||
|    sourceAdded_ = false; | ||||
|    QString before = "ferry"; | ||||
| 
 | ||||
|    for (const QString& layer : map_->layerIds()) | ||||
|    { | ||||
|       // Draw below tunnels, ferries and roads
 | ||||
|       if (layer.startsWith("tunnel") || layer.startsWith("ferry") || | ||||
|           layer.startsWith("road")) | ||||
|       { | ||||
|          before = layer; | ||||
|          break; | ||||
|       } | ||||
|    } | ||||
| 
 | ||||
|    map_->addCustomLayer("triangle", pHost, before); | ||||
| } | ||||
| 
 | ||||
| void MapWidget::keyPressEvent(QKeyEvent* ev) | ||||
|  | @ -55,362 +75,9 @@ void MapWidget::keyPressEvent(QKeyEvent* ev) | |||
|    case Qt::Key_S: changeStyle(); break; | ||||
|    case Qt::Key_L: | ||||
|    { | ||||
|       if (sourceAdded_) | ||||
|       for (const QString& layer : map_->layerIds()) | ||||
|       { | ||||
|          return; | ||||
|       } | ||||
| 
 | ||||
|       sourceAdded_ = true; | ||||
| 
 | ||||
|       // Not in all styles, but will work on streets
 | ||||
|       QString before = "waterway-label"; | ||||
| 
 | ||||
|       QFile geojson(":source1.geojson"); | ||||
|       geojson.open(QIODevice::ReadOnly); | ||||
| 
 | ||||
|       // The data source for the route line and markers
 | ||||
|       QVariantMap routeSource; | ||||
|       routeSource["type"] = "geojson"; | ||||
|       routeSource["data"] = geojson.readAll(); | ||||
|       map_->addSource("routeSource", routeSource); | ||||
| 
 | ||||
|       // The route case, painted before the route
 | ||||
|       QVariantMap routeCase; | ||||
|       routeCase["id"]     = "routeCase"; | ||||
|       routeCase["type"]   = "line"; | ||||
|       routeCase["source"] = "routeSource"; | ||||
|       map_->addLayer(routeCase, before); | ||||
| 
 | ||||
|       map_->setPaintProperty("routeCase", "line-color", QColor("white")); | ||||
|       map_->setPaintProperty("routeCase", "line-width", 20.0); | ||||
|       map_->setLayoutProperty("routeCase", "line-join", "round"); | ||||
|       map_->setLayoutProperty("routeCase", "line-cap", "round"); | ||||
| 
 | ||||
|       // The route, painted on top of the route case
 | ||||
|       QVariantMap route; | ||||
|       route["id"]     = "route"; | ||||
|       route["type"]   = "line"; | ||||
|       route["source"] = "routeSource"; | ||||
|       map_->addLayer(route, before); | ||||
| 
 | ||||
|       map_->setPaintProperty("route", "line-color", QColor("blue")); | ||||
|       map_->setPaintProperty("route", "line-width", 8.0); | ||||
|       map_->setLayoutProperty("route", "line-join", "round"); | ||||
|       map_->setLayoutProperty("route", "line-cap", "round"); | ||||
| 
 | ||||
|       QVariantList lineDashArray; | ||||
|       lineDashArray.append(1); | ||||
|       lineDashArray.append(2); | ||||
| 
 | ||||
|       map_->setPaintProperty("route", "line-dasharray", lineDashArray); | ||||
| 
 | ||||
|       // Markers at the beginning and end of the route
 | ||||
|       map_->addImage("label-arrow", QImage(":label-arrow.svg")); | ||||
|       map_->addImage("label-background", QImage(":label-background.svg")); | ||||
| 
 | ||||
|       QVariantMap markerArrow; | ||||
|       markerArrow["id"]     = "markerArrow"; | ||||
|       markerArrow["type"]   = "symbol"; | ||||
|       markerArrow["source"] = "routeSource"; | ||||
|       map_->addLayer(markerArrow); | ||||
| 
 | ||||
|       map_->setLayoutProperty("markerArrow", "icon-image", "label-arrow"); | ||||
|       map_->setLayoutProperty("markerArrow", "icon-size", 0.5); | ||||
|       map_->setLayoutProperty("markerArrow", "icon-ignore-placement", true); | ||||
| 
 | ||||
|       QVariantList arrowOffset; | ||||
|       arrowOffset.append(0.0); | ||||
|       arrowOffset.append(-15.0); | ||||
|       map_->setLayoutProperty("markerArrow", "icon-offset", arrowOffset); | ||||
| 
 | ||||
|       QVariantMap markerBackground; | ||||
|       markerBackground["id"]     = "markerBackground"; | ||||
|       markerBackground["type"]   = "symbol"; | ||||
|       markerBackground["source"] = "routeSource"; | ||||
|       map_->addLayer(markerBackground); | ||||
| 
 | ||||
|       map_->setLayoutProperty( | ||||
|          "markerBackground", "icon-image", "label-background"); | ||||
|       map_->setLayoutProperty("markerBackground", "text-field", "{name}"); | ||||
|       map_->setLayoutProperty("markerBackground", "icon-text-fit", "both"); | ||||
|       map_->setLayoutProperty( | ||||
|          "markerBackground", "icon-ignore-placement", true); | ||||
|       map_->setLayoutProperty( | ||||
|          "markerBackground", "text-ignore-placement", true); | ||||
|       map_->setLayoutProperty("markerBackground", "text-anchor", "left"); | ||||
|       map_->setLayoutProperty("markerBackground", "text-size", 16.0); | ||||
|       map_->setLayoutProperty("markerBackground", "text-padding", 0.0); | ||||
|       map_->setLayoutProperty("markerBackground", "text-line-height", 1.0); | ||||
|       map_->setLayoutProperty("markerBackground", "text-max-width", 8.0); | ||||
| 
 | ||||
|       QVariantList iconTextFitPadding; | ||||
|       iconTextFitPadding.append(15.0); | ||||
|       iconTextFitPadding.append(10.0); | ||||
|       iconTextFitPadding.append(15.0); | ||||
|       iconTextFitPadding.append(10.0); | ||||
|       map_->setLayoutProperty( | ||||
|          "markerBackground", "icon-text-fit-padding", iconTextFitPadding); | ||||
| 
 | ||||
|       QVariantList backgroundOffset; | ||||
|       backgroundOffset.append(-0.5); | ||||
|       backgroundOffset.append(-1.5); | ||||
|       map_->setLayoutProperty( | ||||
|          "markerBackground", "text-offset", backgroundOffset); | ||||
| 
 | ||||
|       map_->setPaintProperty("markerBackground", "text-color", QColor("white")); | ||||
| 
 | ||||
|       QVariantList filterExpression; | ||||
|       filterExpression.append("=="); | ||||
|       filterExpression.append("$type"); | ||||
|       filterExpression.append("Point"); | ||||
| 
 | ||||
|       QVariantList filter; | ||||
|       filter.append(filterExpression); | ||||
| 
 | ||||
|       map_->setFilter("markerArrow", filter); | ||||
|       map_->setFilter("markerBackground", filter); | ||||
| 
 | ||||
|       // Tilt the labels when tilting the map and make them larger
 | ||||
|       map_->setLayoutProperty("road-label-large", "text-size", 30.0); | ||||
|       map_->setLayoutProperty( | ||||
|          "road-label-large", "text-pitch-alignment", "viewport"); | ||||
| 
 | ||||
|       map_->setLayoutProperty("road-label-medium", "text-size", 30.0); | ||||
|       map_->setLayoutProperty( | ||||
|          "road-label-medium", "text-pitch-alignment", "viewport"); | ||||
| 
 | ||||
|       map_->setLayoutProperty( | ||||
|          "road-label-small", "text-pitch-alignment", "viewport"); | ||||
|       map_->setLayoutProperty("road-label-small", "text-size", 30.0); | ||||
| 
 | ||||
|       // Buildings extrusion
 | ||||
|       QVariantMap buildings; | ||||
|       buildings["id"]           = "3d-buildings"; | ||||
|       buildings["source"]       = "composite"; | ||||
|       buildings["source-layer"] = "building"; | ||||
|       buildings["type"]         = "fill-extrusion"; | ||||
|       buildings["minzoom"]      = 15.0; | ||||
|       map_->addLayer(buildings); | ||||
| 
 | ||||
|       QVariantList buildingsFilterExpression; | ||||
|       buildingsFilterExpression.append("=="); | ||||
|       buildingsFilterExpression.append("extrude"); | ||||
|       buildingsFilterExpression.append("true"); | ||||
| 
 | ||||
|       QVariantList buildingsFilter; | ||||
|       buildingsFilter.append(buildingsFilterExpression); | ||||
| 
 | ||||
|       map_->setFilter("3d-buildings", buildingsFilterExpression); | ||||
| 
 | ||||
|       QString fillExtrusionColorJSON = R"JSON( | ||||
|               [ | ||||
|                 "interpolate", | ||||
|                 ["linear"], | ||||
|                 ["get", "height"], | ||||
|                   0.0, "blue", | ||||
|                  20.0, "royalblue", | ||||
|                  40.0, "cyan", | ||||
|                  60.0, "lime", | ||||
|                  80.0, "yellow", | ||||
|                 100.0, "red" | ||||
|               ] | ||||
|             )JSON"; | ||||
| 
 | ||||
|       map_->setPaintProperty( | ||||
|          "3d-buildings", "fill-extrusion-color", fillExtrusionColorJSON); | ||||
|       map_->setPaintProperty("3d-buildings", "fill-extrusion-opacity", .6); | ||||
| 
 | ||||
|       QVariantMap extrusionHeight; | ||||
|       extrusionHeight["type"]     = "identity"; | ||||
|       extrusionHeight["property"] = "height"; | ||||
| 
 | ||||
|       map_->setPaintProperty( | ||||
|          "3d-buildings", "fill-extrusion-height", extrusionHeight); | ||||
| 
 | ||||
|       QVariantMap extrusionBase; | ||||
|       extrusionBase["type"]     = "identity"; | ||||
|       extrusionBase["property"] = "min_height"; | ||||
| 
 | ||||
|       map_->setPaintProperty( | ||||
|          "3d-buildings", "fill-extrusion-base", extrusionBase); | ||||
|    } | ||||
|    break; | ||||
|    case Qt::Key_1: | ||||
|    { | ||||
|       if (symbolAnnotationId_.isNull()) | ||||
|       { | ||||
|          QMapbox::Coordinate       coordinate = map_->coordinate(); | ||||
|          QMapbox::SymbolAnnotation symbol {coordinate, "default_marker"}; | ||||
|          map_->addAnnotationIcon("default_marker", | ||||
|                                  QImage(":default_marker.svg")); | ||||
|          symbolAnnotationId_ = map_->addAnnotation( | ||||
|             QVariant::fromValue<QMapbox::SymbolAnnotation>(symbol)); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          map_->removeAnnotation(symbolAnnotationId_.toUInt()); | ||||
|          symbolAnnotationId_.clear(); | ||||
|       } | ||||
|    } | ||||
|    break; | ||||
|    case Qt::Key_2: | ||||
|    { | ||||
|       if (lineAnnotationId_.isNull()) | ||||
|       { | ||||
|          QMapbox::Coordinates coordinates; | ||||
|          coordinates.push_back(map_->coordinateForPixel({0, 0})); | ||||
|          coordinates.push_back(map_->coordinateForPixel( | ||||
|             {qreal(size().width()), qreal(size().height())})); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollection collection; | ||||
|          collection.push_back(coordinates); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollections lineGeometry; | ||||
|          lineGeometry.push_back(collection); | ||||
| 
 | ||||
|          QMapbox::ShapeAnnotationGeometry annotationGeometry( | ||||
|             QMapbox::ShapeAnnotationGeometry::LineStringType, lineGeometry); | ||||
| 
 | ||||
|          QMapbox::LineAnnotation line; | ||||
|          line.geometry     = annotationGeometry; | ||||
|          line.opacity      = 0.5f; | ||||
|          line.width        = 1.0f; | ||||
|          line.color        = Qt::red; | ||||
|          lineAnnotationId_ = map_->addAnnotation( | ||||
|             QVariant::fromValue<QMapbox::LineAnnotation>(line)); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          map_->removeAnnotation(lineAnnotationId_.toUInt()); | ||||
|          lineAnnotationId_.clear(); | ||||
|       } | ||||
|    } | ||||
|    break; | ||||
|    case Qt::Key_3: | ||||
|    { | ||||
|       if (fillAnnotationId_.isNull()) | ||||
|       { | ||||
|          QMapbox::Coordinates coordinates; | ||||
|          coordinates.push_back( | ||||
|             map_->coordinateForPixel({qreal(size().width()), 0})); | ||||
|          coordinates.push_back(map_->coordinateForPixel( | ||||
|             {qreal(size().width()), qreal(size().height())})); | ||||
|          coordinates.push_back( | ||||
|             map_->coordinateForPixel({0, qreal(size().height())})); | ||||
|          coordinates.push_back(map_->coordinateForPixel({0, 0})); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollection collection; | ||||
|          collection.push_back(coordinates); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollections fillGeometry; | ||||
|          fillGeometry.push_back(collection); | ||||
| 
 | ||||
|          QMapbox::ShapeAnnotationGeometry annotationGeometry( | ||||
|             QMapbox::ShapeAnnotationGeometry::PolygonType, fillGeometry); | ||||
| 
 | ||||
|          QMapbox::FillAnnotation fill; | ||||
|          fill.geometry     = annotationGeometry; | ||||
|          fill.opacity      = 0.5f; | ||||
|          fill.color        = Qt::green; | ||||
|          fill.outlineColor = QVariant::fromValue<QColor>(QColor(Qt::black)); | ||||
|          fillAnnotationId_ = map_->addAnnotation( | ||||
|             QVariant::fromValue<QMapbox::FillAnnotation>(fill)); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          map_->removeAnnotation(fillAnnotationId_.toUInt()); | ||||
|          fillAnnotationId_.clear(); | ||||
|       } | ||||
|    } | ||||
|    break; | ||||
|    case Qt::Key_5: | ||||
|    { | ||||
|       if (map_->layerExists("circleLayer")) | ||||
|       { | ||||
|          map_->removeLayer("circleLayer"); | ||||
|          map_->removeSource("circleSource"); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          QMapbox::Coordinates coordinates; | ||||
|          coordinates.push_back(map_->coordinate()); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollection collection; | ||||
|          collection.push_back(coordinates); | ||||
| 
 | ||||
|          QMapbox::CoordinatesCollections point; | ||||
|          point.push_back(collection); | ||||
| 
 | ||||
|          QMapbox::Feature feature(QMapbox::Feature::PointType, point, {}, {}); | ||||
| 
 | ||||
|          QVariantMap circleSource; | ||||
|          circleSource["type"] = "geojson"; | ||||
|          circleSource["data"] = QVariant::fromValue<QMapbox::Feature>(feature); | ||||
|          map_->addSource("circleSource", circleSource); | ||||
| 
 | ||||
|          QVariantMap circle; | ||||
|          circle["id"]     = "circleLayer"; | ||||
|          circle["type"]   = "circle"; | ||||
|          circle["source"] = "circleSource"; | ||||
|          map_->addLayer(circle); | ||||
| 
 | ||||
|          map_->setPaintProperty("circleLayer", "circle-radius", 10.0); | ||||
|          map_->setPaintProperty("circleLayer", "circle-color", QColor("black")); | ||||
|       } | ||||
|    } | ||||
|    break; | ||||
|    case Qt::Key_6: | ||||
|    { | ||||
|       if (map_->layerExists("innerCirclesLayer") || | ||||
|           map_->layerExists("outerCirclesLayer")) | ||||
|       { | ||||
|          map_->removeLayer("innerCirclesLayer"); | ||||
|          map_->removeLayer("outerCirclesLayer"); | ||||
|          map_->removeSource("innerCirclesSource"); | ||||
|          map_->removeSource("outerCirclesSource"); | ||||
|       } | ||||
|       else | ||||
|       { | ||||
|          auto makePoint = [&](double dx, double dy, const QString& color) { | ||||
|             auto coordinate = map_->coordinate(); | ||||
|             coordinate.first += dx; | ||||
|             coordinate.second += dy; | ||||
|             return QMapbox::Feature {QMapbox::Feature::PointType, | ||||
|                                      {{{coordinate}}}, | ||||
|                                      {{"color", color}}, | ||||
|                                      {}}; | ||||
|          }; | ||||
| 
 | ||||
|          // multiple features by QVector<QMapbox::Feature>
 | ||||
|          QVector<QMapbox::Feature> inner {makePoint(0.001, 0, "red"), | ||||
|                                           makePoint(0, 0.001, "green"), | ||||
|                                           makePoint(0, -0.001, "blue")}; | ||||
| 
 | ||||
|          map_->addSource( | ||||
|             "innerCirclesSource", | ||||
|             {{"type", "geojson"}, {"data", QVariant::fromValue(inner)}}); | ||||
|          map_->addLayer({{"id", "innerCirclesLayer"}, | ||||
|                          {"type", "circle"}, | ||||
|                          {"source", "innerCirclesSource"}}); | ||||
| 
 | ||||
|          // multiple features by QList<QMapbox::Feature>
 | ||||
|          QList<QMapbox::Feature> outer {makePoint(0.002, 0.002, "cyan"), | ||||
|                                         makePoint(-0.002, 0.002, "magenta"), | ||||
|                                         makePoint(0.002, -0.002, "yellow"), | ||||
|                                         makePoint(-0.002, -0.002, "black")}; | ||||
| 
 | ||||
|          map_->addSource( | ||||
|             "outerCirclesSource", | ||||
|             {{"type", "geojson"}, {"data", QVariant::fromValue(outer)}}); | ||||
|          map_->addLayer({{"id", "outerCirclesLayer"}, | ||||
|                          {"type", "circle"}, | ||||
|                          {"source", "outerCirclesSource"}}); | ||||
| 
 | ||||
|          QVariantList getColor {"get", "color"}; | ||||
|          map_->setPaintProperty("innerCirclesLayer", "circle-radius", 10.0); | ||||
|          map_->setPaintProperty("innerCirclesLayer", "circle-color", getColor); | ||||
|          map_->setPaintProperty("outerCirclesLayer", "circle-radius", 15.0); | ||||
|          map_->setPaintProperty("outerCirclesLayer", "circle-color", getColor); | ||||
|          qDebug() << "Layer: " << layer; | ||||
|       } | ||||
|    } | ||||
|    break; | ||||
|  | @ -512,6 +179,8 @@ void MapWidget::initializeGL() | |||
|       map_->setStyleUrl(styleUrl); | ||||
|       setWindowTitle(QString("Mapbox GL: ") + styleUrl); | ||||
|    } | ||||
| 
 | ||||
|    connect(map_.get(), &QMapboxGL::mapChanged, this, &MapWidget::mapChanged); | ||||
| } | ||||
| 
 | ||||
| void MapWidget::paintGL() | ||||
|  | @ -523,5 +192,13 @@ void MapWidget::paintGL() | |||
|    map_->render(); | ||||
| } | ||||
| 
 | ||||
| void MapWidget::mapChanged(QMapboxGL::MapChange mapChange) | ||||
| { | ||||
|    if (mapChange == QMapboxGL::MapChangeDidFinishLoadingStyle) | ||||
|    { | ||||
|       AddLayers(); | ||||
|    } | ||||
| } | ||||
| 
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
|  |  | |||
|  | @ -38,6 +38,8 @@ private: | |||
|    void initializeGL() override final; | ||||
|    void paintGL() override final; | ||||
| 
 | ||||
|    void AddLayers(); | ||||
| 
 | ||||
|    QPointF lastPos_; | ||||
| 
 | ||||
|    QMapboxGLSettings         settings_; | ||||
|  | @ -45,11 +47,8 @@ private: | |||
| 
 | ||||
|    uint64_t frameDraws_ = 0; | ||||
| 
 | ||||
|    QVariant symbolAnnotationId_; | ||||
|    QVariant lineAnnotationId_; | ||||
|    QVariant fillAnnotationId_; | ||||
| 
 | ||||
|    bool sourceAdded_ = false; | ||||
| private slots: | ||||
|    void mapChanged(QMapboxGL::MapChange); | ||||
| }; | ||||
| 
 | ||||
| } // namespace qt
 | ||||
|  |  | |||
							
								
								
									
										167
									
								
								scwx-qt/source/scwx/qt/map/triangle_layer.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								scwx-qt/source/scwx/qt/map/triangle_layer.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,167 @@ | |||
| #include <scwx/qt/map/triangle_layer.hpp> | ||||
| 
 | ||||
| #include <QOpenGLFunctions_3_3_Core> | ||||
| 
 | ||||
| #include <boost/log/trivial.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| 
 | ||||
| static const std::string logPrefix_ = "[scwx::map::triangle_layer] "; | ||||
| 
 | ||||
| class TriangleLayerImpl | ||||
| { | ||||
| public: | ||||
|    explicit TriangleLayerImpl() : | ||||
|        gl_(), | ||||
|        shaderProgram_ {GL_INVALID_INDEX}, | ||||
|        vbo_ {GL_INVALID_INDEX}, | ||||
|        vao_ {GL_INVALID_INDEX} | ||||
|    { | ||||
|       gl_.initializeOpenGLFunctions(); | ||||
|    } | ||||
|    ~TriangleLayerImpl() = default; | ||||
| 
 | ||||
|    QOpenGLFunctions_3_3_Core gl_; | ||||
| 
 | ||||
|    GLuint shaderProgram_; | ||||
|    GLuint vbo_; | ||||
|    GLuint vao_; | ||||
| }; | ||||
| 
 | ||||
| TriangleLayer::TriangleLayer() : p(std::make_unique<TriangleLayerImpl>()) {} | ||||
| TriangleLayer::~TriangleLayer() = default; | ||||
| 
 | ||||
| TriangleLayer::TriangleLayer(TriangleLayer&&) noexcept = default; | ||||
| TriangleLayer& TriangleLayer::operator=(TriangleLayer&&) noexcept = default; | ||||
| 
 | ||||
| void TriangleLayer::initialize() | ||||
| { | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    static const char* vertexShaderSource = | ||||
|       "#version 330 core\n" | ||||
|       "layout (location = 0) in vec3 aPos;" | ||||
|       "void main()" | ||||
|       "{" | ||||
|       "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);" | ||||
|       "}"; | ||||
| 
 | ||||
|    static const char* fragmentShaderSource = | ||||
|       "#version 330 core\n" | ||||
|       "out vec4 FragColor;" | ||||
|       "void main()" | ||||
|       "{" | ||||
|       "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);" | ||||
|       "}"; | ||||
| 
 | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "initialize()"; | ||||
| 
 | ||||
|    GLint success; | ||||
| 
 | ||||
|    // Create a vertex shader
 | ||||
|    GLuint vertexShader = gl.glCreateShader(GL_VERTEX_SHADER); | ||||
| 
 | ||||
|    // Attach the shader source code and compile the shader
 | ||||
|    gl.glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | ||||
|    gl.glCompileShader(vertexShader); | ||||
| 
 | ||||
|    // Check for errors
 | ||||
|    gl.glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | ||||
|    if (!success) | ||||
|    { | ||||
|       char infoLog[512]; | ||||
|       gl.glGetShaderInfoLog(vertexShader, 512, NULL, infoLog); | ||||
|       BOOST_LOG_TRIVIAL(error) | ||||
|          << logPrefix_ << "Vertex shader compilation failed"; | ||||
|    } | ||||
| 
 | ||||
|    // Create a fragment shader
 | ||||
|    GLuint fragmentShader = gl.glCreateShader(GL_FRAGMENT_SHADER); | ||||
| 
 | ||||
|    // Attach the shader source and compile the shader
 | ||||
|    gl.glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | ||||
|    gl.glCompileShader(fragmentShader); | ||||
| 
 | ||||
|    // Check for errors
 | ||||
|    gl.glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | ||||
|    if (!success) | ||||
|    { | ||||
|       char infoLog[512]; | ||||
|       gl.glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog); | ||||
|       BOOST_LOG_TRIVIAL(error) | ||||
|          << logPrefix_ << "Fragment shader compilation failed: " << infoLog; | ||||
|    } | ||||
| 
 | ||||
|    // Create shader program
 | ||||
|    p->shaderProgram_ = gl.glCreateProgram(); | ||||
| 
 | ||||
|    gl.glAttachShader(p->shaderProgram_, vertexShader); | ||||
|    gl.glAttachShader(p->shaderProgram_, fragmentShader); | ||||
|    gl.glLinkProgram(p->shaderProgram_); | ||||
| 
 | ||||
|    // Check for errors
 | ||||
|    gl.glGetProgramiv(p->shaderProgram_, GL_LINK_STATUS, &success); | ||||
|    if (!success) | ||||
|    { | ||||
|       char infoLog[512]; | ||||
|       gl.glGetProgramInfoLog(p->shaderProgram_, 512, NULL, infoLog); | ||||
|       BOOST_LOG_TRIVIAL(error) | ||||
|          << logPrefix_ << "Shader program link failed: " << infoLog; | ||||
|    } | ||||
| 
 | ||||
|    // Delete shaders
 | ||||
|    gl.glDeleteShader(vertexShader); | ||||
|    gl.glDeleteShader(fragmentShader); | ||||
| 
 | ||||
|    // Define 3 (x,y,z) vertices
 | ||||
|    GLfloat vertices[] = { | ||||
|       -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f}; | ||||
| 
 | ||||
|    // Generate a vertex buffer object
 | ||||
|    gl.glGenBuffers(1, &p->vbo_); | ||||
| 
 | ||||
|    // Generate a vertex array object
 | ||||
|    gl.glGenVertexArrays(1, &p->vao_); | ||||
| 
 | ||||
|    // Bind vertex array object
 | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
| 
 | ||||
|    // Copy vertices array in a buffer for OpenGL to use
 | ||||
|    gl.glBindBuffer(GL_ARRAY_BUFFER, p->vbo_); | ||||
|    gl.glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | ||||
| 
 | ||||
|    // Set the vertex attributes pointers
 | ||||
|    gl.glVertexAttribPointer( | ||||
|       0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), static_cast<void*>(0)); | ||||
|    gl.glEnableVertexAttribArray(0); | ||||
| } | ||||
| 
 | ||||
| void TriangleLayer::render(const QMapbox::CustomLayerRenderParameters&) | ||||
| { | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    gl.glUseProgram(p->shaderProgram_); | ||||
|    gl.glBindVertexArray(p->vao_); | ||||
|    gl.glDrawArrays(GL_TRIANGLES, 0, 3); | ||||
| } | ||||
| 
 | ||||
| void TriangleLayer::deinitialize() | ||||
| { | ||||
|    QOpenGLFunctions_3_3_Core& gl = p->gl_; | ||||
| 
 | ||||
|    BOOST_LOG_TRIVIAL(debug) << logPrefix_ << "deinitialize()"; | ||||
| 
 | ||||
|    gl.glDeleteProgram(p->shaderProgram_); | ||||
|    gl.glDeleteVertexArrays(1, &p->vao_); | ||||
|    gl.glDeleteBuffers(1, &p->vbo_); | ||||
| 
 | ||||
|    p->shaderProgram_ = GL_INVALID_INDEX; | ||||
|    p->vao_           = GL_INVALID_INDEX; | ||||
|    p->vbo_           = GL_INVALID_INDEX; | ||||
| } | ||||
| 
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
							
								
								
									
										31
									
								
								scwx-qt/source/scwx/qt/map/triangle_layer.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								scwx-qt/source/scwx/qt/map/triangle_layer.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| #include <qmapboxgl.hpp> | ||||
| 
 | ||||
| namespace scwx | ||||
| { | ||||
| namespace qt | ||||
| { | ||||
| 
 | ||||
| class TriangleLayerImpl; | ||||
| 
 | ||||
| class TriangleLayer : public QMapbox::CustomLayerHostInterface | ||||
| { | ||||
| public: | ||||
|    explicit TriangleLayer(); | ||||
|    ~TriangleLayer(); | ||||
| 
 | ||||
|    TriangleLayer(const TriangleLayer&) = delete; | ||||
|    TriangleLayer& operator=(const TriangleLayer&) = delete; | ||||
| 
 | ||||
|    TriangleLayer(TriangleLayer&&) noexcept; | ||||
|    TriangleLayer& operator=(TriangleLayer&&) noexcept; | ||||
| 
 | ||||
|    void initialize() override final; | ||||
|    void render(const QMapbox::CustomLayerRenderParameters&) override final; | ||||
|    void deinitialize() override final; | ||||
| 
 | ||||
| private: | ||||
|    std::unique_ptr<TriangleLayerImpl> p; | ||||
| }; | ||||
| 
 | ||||
| } // namespace qt
 | ||||
| } // namespace scwx
 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat