maplibre / maplibre-native-qt

MapLibre Qt Bindings and Qt Location Plugin
https://maplibre.org/maplibre-native-qt/docs/
35 stars 13 forks source link

Qt WebGL1 demo #49

Open birkskyum opened 1 year ago

birkskyum commented 1 year ago

Ticket to demonstrate utilizing Qt for WebAssembly, to run the OpenGL2 legacy branch of MapLibre Native as a WebGL1 build in the browsers.

Update

This is working now, and the findings are documented in a separate repo:

Working demo here

Build instructions, binaries and more info here.

MapLibre Native WASM overview here

ntadej commented 1 year ago

The code already builds with emscripten (using Qt platform). The problem is threading is generally not supported by wasm yet and the codebase uses a lot of it.

birkskyum commented 1 year ago

Do you have any pointers on how I can run this build? The GL JS is also really slow without the web workers, but it runs.

ntadej commented 1 year ago

No, Qt wasm does not run unfortunately. It crashes somewhere where threading wants to be used as Qt is nominally not built with the support for that (but maybe this has changed since).

You can build it the same as for other Qt platforms, you just use the wasm build of Qt. See https://doc.qt.io/qt-6/wasm.html

ankurvdev commented 1 year ago

FWIW I managed to get it working with a few patches by statically linking with Qt6-wasm built via vcpkg (with pthread and asyncify) The only major issue was getting the QEventLoop to play well with the JS event loop (which arguably is a Qt issue)

amirtu commented 10 months ago

poc Indeed, it is possible to make it work with the above-mentioned way.

wipfli commented 10 months ago

@amirtu do you have a public demo of this?

birkskyum commented 10 months ago

so many opportunities here - let's add a compilation target for this in the repo

birkskyum commented 10 months ago

Qt has some serious implications in terms of licensing (LGPLv3 or commercial license). What paths can we take to end up with a more permission license?

birkskyum commented 9 months ago

Update: In order to get multithreading working properly, we're awaiting bugfix in Qt that'll allow the QNetworkAccessManager to make requests from within threads in wasm. https://bugreports.qt.io/browse/QTBUG-109396

amirtu commented 8 months ago

@amirtu do you have a public demo of this?

https://sophomore.solutions/app.html

UPD.: https://amirtu.netlify.app/mapbox-qt-wasm/app.htm

birkskyum commented 8 months ago

@amirtu do you have a public demo of this?

https://sophomore.solutions/app.html

Tiles are found by zooming to Almaty in Kazakhstan

birkskyum commented 2 months ago

Tried again with latest versions. It says that this check returns false / that vertexArray doesn't exist:

bool Context::supportsVertexArrays() const {
    return vertexArray && vertexArray->genVertexArrays && vertexArray->bindVertexArray &&
           vertexArray->deleteVertexArrays;
}

This check was removed from MapLibre Native a year ago, as part of the shift to OpenGL 3+

https://github.com/maplibre/maplibre-native/commit/8ff6704fc4cc8a44b87af4fc2be60cd9caab7de5#diff-25e92576a5706afc614df2db9c0a00c25bc1636aefb081dde7d2b35aceb6b069L216-L228

Would be interesting to see how this faires after the maplibre-native-qt has been reconciled with latest maplibre-native

birkskyum commented 2 months ago

When the style is downloaded, the callback that should fire isn't firing. That's where things are now.

andreamancuso commented 1 month ago

Hello folks - are there plans to add support for emscripten - no Qt dependencies? I'd like to embed Maplibre Native with Dear Imgui + emscripten.

Looks like this is already achievable as part of https://github.com/maplibre/maplibre-rs ?

birkskyum commented 1 week ago

After two years of working on this, I finally have a POC running!

More info here

https://github.com/user-attachments/assets/09b8dbfc-68cd-446a-90af-41f5a0b13230

ntadej commented 1 week ago

Can you open a draft PR with your fixes/hacks?

birkskyum commented 1 week ago

@ntadej , what gave a visual output in the end was changing this reply-> url in the opengl2 branch of Native. After that the map kept crashing due to duplicate requests, but then changing deleteLater(); to abort(); fixed that.

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();
}

Apart from that I just remove everything else from the example than the map, and added a defaultPitch function, but those changes are less interesting.

ntadej commented 1 week ago

Let's keep this open until it properly works

birkskyum commented 1 week ago

@ntadej , okay, this can be added to CI in september with the stable Qt 6.8 release.

Regarding performance, I find it more feasible to invest in getting a webgl2 build going using the latest OpenGL 3/4 backend from MapLibre Native Core, rather than spending a lot of time optimizing on the opengl2 legacy branch.