WebGL1 from OpenGL2 legacy renderer
Last updated: 6.8.0-beta.3 / Aug 14th 2024
Prerequisites
Clone the maplibre-native-qt repo
Install Qt 6.8.0-beta.3 with the online installer (not i.e. homebrew), and make sure to select the WebAssembly multi-threaded.
Install Emscripten through the "recommended" path here (again, don't use homebrew). It's important that it's version 3.1.56 for Qt 6.8.0-beta.3 (see here)
./emsdk install 3.1.56
./emsdk activate 3.1.56
source ./emsdk/emsdk_env.sh # in general, if something Emscripten related can't be found, run this again
Make sure to add both emscripten and qt to your path. My .zshrc i.e. looks like this:
export PATH=/Users/admin/Qt/6.8.0/wasm_multithread/bin:$PATH
export PATH="/Users/admin/repos/emsdk/upstream/emscripten:$PATH"
Build QMapLibre
A few manual changes required for now
Before you build QMaplibre, you'll have to make some manual changes in the maplibre-native-qt repo, until this upstread PR lands.
Update the followign in the: HTTPFileSource (maplibre-native-qt/vendor/maplibre-native/platform/qt/src/mbgl/http_file_source.cpp
)
# maplibre-native-qt/vendor/maplibre-native/platform/qt/src/mbgl/http_file_source.cpp
void HTTPFileSource::Impl::onReplyFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
-- const QUrl& url = reply->request().url();
++ const QUrl& url = reply->url();
auto it = m_pending.find(url);
if (it == m_pending.end()) {
-- reply->deleteLater();
++ reply->abort();
return;
}
QByteArray data = reply->readAll();
QVector<HTTPRequest*>& requestsVector = it.value().second;
// Cannot use the iterator to walk the requestsVector
// because calling handleNetworkReply() might get
// requests added to the requestsVector.
while (!requestsVector.isEmpty()) {
requestsVector.takeFirst()->handleNetworkReply(reply, data);
}
m_pending.erase(it);
-- reply->deleteLater();
++ reply->abort();
}
Changing the reply-> url
in the opengl2 branch of Native allow the build to run.
Changing deleteLater();
to abort();
avoids a lot of duplicate requests.
Make the build
Follow the "How to build" here, except add a -DMLN_QT_WITH_LOCATION=OFF
flag.
Effectively you want to make a folder, and from within it run:
qt-cmake ../maplibre-native-qt -GNinja \
-DCMAKE_C_COMPILER_LAUNCHER="ccache" \
-DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
-DCMAKE_INSTALL_PREFIX="../qmaplibre-install-dir" -DMLN_QT_WITH_LOCATION=OFF
ninja
ninja install
Make and run the Widget example
Create a new folder next to maplibre-native-qt, and from within it like following. For debugging use -DCMAKE_BUILD_TYPE="RelWithDebInfo"
qt-cmake ../maplibre-native-qt/examples/widgets \
-G Ninja \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_C_COMPILER_LAUNCHER="ccache" \
-DCMAKE_CXX_COMPILER_LAUNCHER="ccache" \
-DCMAKE_EXE_LINKER_FLAGS="-s EXPORT_NAME=Something" \
-DQMapLibre_DIR=/Users/admin/repos/qmaplibre-install-dir/lib/cmake/QMapLibre \
-DCMAKE_CXX_FLAGS="-Os" # Release optimization, focus on binary size
ninja
emrun --browser=chrome QMapLibreExampleWidgets.html
Result in browser: