[qt] Implement FBO handling

Needed for rendering 3D extrusions properly.
This commit is contained in:
Thiago Marcos P. Santos
2018-01-26 18:20:46 +02:00
parent a4e95c3da3
commit 673730ccd4
8 changed files with 45 additions and 34 deletions

View File

@@ -442,6 +442,9 @@ void MapWindow::initializeGL()
void MapWindow::paintGL()
{
m_frameDraws++;
m_map->resize(size(), size() * pixelRatio());
m_map->resize(size());
#if QT_VERSION >= 0x050400
m_map->setFramebufferObject(defaultFramebufferObject(), size() * pixelRatio());
#endif
m_map->render();
}

View File

@@ -191,8 +191,7 @@ public:
void scaleBy(double scale, const QPointF &center = QPointF());
void rotateBy(const QPointF &first, const QPointF &second);
void resize(const QSize &size, const QSize &framebufferSize);
void setFramebufferObject(quint32 fbo);
void resize(const QSize &size);
double metersPerPixelAtLatitude(double latitude, double zoom) const;
QMapbox::ProjectedMeters projectedMetersForCoordinate(const QMapbox::Coordinate &) const;
@@ -227,9 +226,10 @@ public:
void setFilter(const QString &layer, const QVariant &filter);
// When rendering on a different thread,
// should be called on this thread
// should be called on the render thread.
void createRenderer();
void destroyRenderer();
void setFramebufferObject(quint32 fbo, const QSize &size);
public slots:
void render();

View File

@@ -1047,36 +1047,19 @@ void QMapboxGL::rotateBy(const QPointF &first, const QPointF &second)
}
/*!
Resize the map to \a size and scale to fit at \a framebufferSize. For
high DPI screens, the size will be smaller than the \a framebufferSize.
This fallowing example will double the pixel density of the map for
a given \c size:
\code
map->resize(size / 2, size);
\endcode
Resize the map to \a size_ and scale to fit at the framebuffer. For
high DPI screens, the size will be smaller than the framebuffer.
*/
void QMapboxGL::resize(const QSize& size_, const QSize& framebufferSize)
void QMapboxGL::resize(const QSize& size_)
{
auto size = sanitizedSize(size_);
if (d_ptr->mapObj->getSize() == size)
return;
d_ptr->mapRenderer->updateFramebufferSize(sanitizedSize(framebufferSize));
d_ptr->mapObj->setSize(size);
}
/*!
If Mapbox GL needs to rebind the default \a fbo, it will use the
ID supplied here.
*/
void QMapboxGL::setFramebufferObject(quint32)
{
// FIXME: No-op, implicit.
}
/*!
Adds an \a icon to the annotation icon pool. This can be later used by the annotation
functions to shown any drawing on the map by referencing its \a name.
@@ -1512,6 +1495,20 @@ void QMapboxGL::render()
d_ptr->mapRenderer->render();
}
/*!
If Mapbox GL needs to rebind the default \a fbo, it will use the
ID supplied here. \a size is the size of the framebuffer, which
on high DPI screens is usually bigger than the map size.
*/
void QMapboxGL::setFramebufferObject(quint32 fbo, const QSize& size)
{
if (!d_ptr->mapRenderer) {
createRenderer();
}
d_ptr->mapRenderer->updateFramebuffer(fbo, sanitizedSize(size));
}
/*!
Informs the map that the network connection has been established, causing
all network requests that previously timed out to be retried immediately.

View File

@@ -25,10 +25,9 @@ void QMapboxGLMapRenderer::updateParameters(std::shared_ptr<mbgl::UpdateParamete
m_updateParameters = std::move(newParameters);
}
void QMapboxGLMapRenderer::updateFramebufferSize(const mbgl::Size &size)
void QMapboxGLMapRenderer::updateFramebuffer(quint32 fbo, const mbgl::Size &size)
{
std::lock_guard<std::mutex> lock(m_updateMutex);
m_backend.setFramebufferSize(size);
m_backend.updateFramebuffer(fbo, size);
}
void QMapboxGLMapRenderer::render()

View File

@@ -9,6 +9,8 @@
#include <mbgl/storage/default_file_source.hpp>
#include <mbgl/util/shared_thread_pool.hpp>
#include <QtGlobal>
#include <memory>
#include <mutex>
#include <queue>
@@ -31,11 +33,11 @@ public:
void schedule(std::weak_ptr<mbgl::Mailbox> scheduled) final;
void render();
void updateFramebuffer(quint32 fbo, const mbgl::Size &size);
void setObserver(std::shared_ptr<mbgl::RendererObserver>);
// Thread-safe, called by the Frontend
void updateParameters(std::shared_ptr<mbgl::UpdateParameters>);
void updateFramebufferSize(const mbgl::Size &size);
private:
Q_DISABLE_COPY(QMapboxGLMapRenderer)

View File

@@ -11,7 +11,15 @@
void QMapboxGLRendererBackend::updateAssumedState()
{
assumeFramebufferBinding(ImplicitFramebufferBinding);
assumeViewport(0, 0, { 800, 600 });
assumeViewport(0, 0, m_size);
}
void QMapboxGLRendererBackend::bind()
{
assert(mbgl::BackendScope::exists());
setFramebufferBinding(m_fbo);
setViewport(0, 0, m_size);
}
mbgl::Size QMapboxGLRendererBackend::getFramebufferSize() const
@@ -19,8 +27,9 @@ mbgl::Size QMapboxGLRendererBackend::getFramebufferSize() const
return m_size;
}
void QMapboxGLRendererBackend::setFramebufferSize(const mbgl::Size &size)
void QMapboxGLRendererBackend::updateFramebuffer(quint32 fbo, const mbgl::Size &size)
{
m_fbo = fbo;
m_size = size;
}

View File

@@ -14,10 +14,10 @@ public:
// mbgl::RendererBackend implementation
void updateAssumedState() final;
void bind() final {}
void bind() final;
mbgl::Size getFramebufferSize() const final;
void setFramebufferSize(const mbgl::Size &);
void updateFramebuffer(quint32 fbo, const mbgl::Size &);
protected:
mbgl::gl::ProcAddress getExtensionFunctionPointer(const char*) final;
@@ -27,6 +27,7 @@ protected:
void deactivate() final {}
private:
quint32 m_fbo = 0;
mbgl::Size m_size = { 0, 0 };
Q_DISABLE_COPY(QMapboxGLRendererBackend)

View File

@@ -15,8 +15,8 @@ QMapboxGLTest::QMapboxGLTest() : size(512, 512), fbo((assert(widget.context()->i
this, SLOT(onMapChanged(QMapboxGL::MapChange)));
connect(&map, SIGNAL(needsRendering()),
this, SLOT(onNeedsRendering()));
map.resize(fbo.size(), fbo.size());
map.setFramebufferObject(fbo.handle());
map.resize(fbo.size());
map.setFramebufferObject(fbo.handle(), fbo.size());
map.setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
}