mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 03:40: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,2 +1,8 @@
|
|||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
set_property(DIRECTORY
|
||||
APPEND
|
||||
PROPERTY CMAKE_CONFIGURE_DEPENDS
|
||||
scwx-qt.cmake)
|
||||
|
||||
include(scwx-qt.cmake)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ set(CMAKE_AUTORCC ON)
|
|||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
find_package(Boost)
|
||||
|
||||
# QtCreator supports the following variables for Android, which are identical to qmake Android variables.
|
||||
# Check https://doc.qt.io/qt/deployment-android.html for more information.
|
||||
# They need to be set before the find_package( ...) calls below.
|
||||
|
|
@ -47,8 +49,10 @@ set(HDR_MAIN source/scwx/qt/main/main_window.hpp)
|
|||
set(SRC_MAIN source/scwx/qt/main/main.cpp
|
||||
source/scwx/qt/main/main_window.cpp)
|
||||
set(UI_MAIN source/scwx/qt/main/main_window.ui)
|
||||
set(HDR_MAP source/scwx/qt/map/map_widget.hpp)
|
||||
set(SRC_MAP source/scwx/qt/map/map_widget.cpp)
|
||||
set(HDR_MAP source/scwx/qt/map/map_widget.hpp
|
||||
source/scwx/qt/map/triangle_layer.hpp)
|
||||
set(SRC_MAP source/scwx/qt/map/map_widget.cpp
|
||||
source/scwx/qt/map/triangle_layer.cpp)
|
||||
|
||||
set(TS_FILES ts/scwx_en_US.ts)
|
||||
|
||||
|
|
@ -76,4 +80,6 @@ target_include_directories(scwx-qt PRIVATE ${scwx-qt_SOURCE_DIR}/source)
|
|||
|
||||
target_link_libraries(scwx-qt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||
qmapboxgl)
|
||||
Boost::log
|
||||
qmapboxgl
|
||||
opengl32)
|
||||
|
|
|
|||
|
|
@ -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