[qt] Add setFramebufferObject() for correct FBO binding restoration

This commit is contained in:
Konstantin Käfer
2017-03-22 10:36:48 +01:00
parent e488ca702e
commit d20327844c
6 changed files with 57 additions and 18 deletions

View File

@@ -399,5 +399,9 @@ void MapWindow::paintGL()
{
m_frameDraws++;
m_map->resize(size(), size() * pixelRatio());
#if QT_VERSION >= 0x050400
// When we're using QOpenGLWidget, we need to tell Mapbox GL about the framebuffer we're using.
m_map->setFramebufferObject(defaultFramebufferObject());
#endif
m_map->render();
}

View File

@@ -192,6 +192,7 @@ public:
void rotateBy(const QPointF &first, const QPointF &second);
void resize(const QSize &size, const QSize &framebufferSize);
void setFramebufferObject(quint32 fbo);
double metersPerPixelAtLatitude(double latitude, double zoom) const;
QMapbox::ProjectedMeters projectedMetersForCoordinate(const QMapbox::Coordinate &) const;

View File

@@ -13,6 +13,10 @@ set(MBGL_QT_TEST_LIBRARIES
PRIVATE Qt4::QtOpenGL
)
target_compile_options(qmapboxgl
PRIVATE -Wno-inconsistent-missing-override
)
target_link_libraries(qmapboxgl
PRIVATE mbgl-core
PRIVATE Qt4::QtCore

View File

@@ -5,10 +5,9 @@
#include "qt_geojson.hpp"
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/layer.hpp>
#include <mbgl/style/conversion/source.hpp>
@@ -31,6 +30,7 @@
#include <QOpenGLContext>
#else
#include <QCoreApplication>
#include <QGLContext>
#endif
#include <QDebug>
@@ -1083,6 +1083,14 @@ void QMapboxGL::resize(const QSize& size, const QSize& framebufferSize)
{ static_cast<uint32_t>(size.width()), static_cast<uint32_t>(size.height()) });
}
/*!
If Mapbox GL needs to rebind the default framebuffer, it will use the
ID supplied here.
*/
void QMapboxGL::setFramebufferObject(quint32 fbo) {
d_ptr->fbObject = fbo;
}
/*!
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.
@@ -1484,6 +1492,7 @@ void QMapboxGL::render()
#endif
d_ptr->dirty = false;
d_ptr->updateViewBinding();
d_ptr->mapObj->render(*d_ptr);
}
@@ -1554,11 +1563,20 @@ QMapboxGLPrivate::~QMapboxGLPrivate()
{
}
mbgl::Size QMapboxGLPrivate::framebufferSize() const {
return { static_cast<uint32_t>(fbSize.width()), static_cast<uint32_t>(fbSize.height()) };
}
void QMapboxGLPrivate::updateViewBinding() {
getContext().bindFramebuffer.setCurrentValue(fbObject);
assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue());
getContext().viewport.setCurrentValue({ 0, 0, framebufferSize() });
assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void QMapboxGLPrivate::bind() {
getContext().bindFramebuffer = 0;
getContext().viewport = {
0, 0, { static_cast<uint32_t>(fbSize.width()), static_cast<uint32_t>(fbSize.height()) }
};
getContext().bindFramebuffer = fbObject;
getContext().viewport = { 0, 0, framebufferSize() };
}
void QMapboxGLPrivate::invalidate()

View File

@@ -20,17 +20,18 @@ public:
explicit QMapboxGLPrivate(QMapboxGL *, const QMapboxGLSettings &, const QSize &size, qreal pixelRatio);
virtual ~QMapboxGLPrivate();
// mbgl::View implementation.
float getPixelRatio() const;
void bind() final;
std::array<uint16_t, 2> getSize() const;
std::array<uint16_t, 2> getFramebufferSize() const;
mbgl::Size framebufferSize() const;
void updateViewBinding();
// mbgl::View implementation.
void bind() final;
// mbgl::Backend implementation.
void invalidate() final;
void activate() final {}
void deactivate() final {}
void invalidate() final;
// mbgl::Backend (mbgl::MapObserver) implementation.
// mbgl::MapObserver implementation.
void onCameraWillChange(mbgl::MapObserver::CameraChangeMode) final;
void onCameraIsChanging() final;
void onCameraDidChange(mbgl::MapObserver::CameraChangeMode) final;
@@ -47,6 +48,7 @@ public:
mbgl::EdgeInsets margins;
QSize size { 0, 0 };
QSize fbSize { 0, 0 };
quint32 fbObject = 0;
QMapboxGL *q_ptr { nullptr };

View File

@@ -2,24 +2,28 @@
#include <mbgl/util/io.hpp>
#include <QApplication>
#include <QGLWidget>
#include <QMapbox>
#include <QMapboxGL>
// We're using QGLFramebufferObject, which is only available in Qt 5 and up.
#if QT_VERSION >= 0x050000
#include <QGLWidget>
#include <QGLFramebufferObject>
class QMapboxGLTest : public QObject, public ::testing::Test {
Q_OBJECT
public:
QMapboxGLTest() : map(nullptr, settings) {
QMapboxGLTest() : fbo((assert(widget.context()->isValid()), widget.makeCurrent(), QSize(512, 512))), map(nullptr, settings) {
connect(&map, SIGNAL(mapChanged(QMapboxGL::MapChange)),
this, SLOT(onMapChanged(QMapboxGL::MapChange)));
connect(&map, SIGNAL(needsRendering()),
this, SLOT(onNeedsRendering()));
widget.makeCurrent();
QMapbox::initializeGLExtensions();
map.resize(QSize(512, 512), QSize(512, 512));
map.resize(fbo.size(), fbo.size());
map.setFramebufferObject(fbo.handle());
map.setCoordinateZoom(QMapbox::Coordinate(60.170448, 24.942046), 14);
}
@@ -36,6 +40,7 @@ public:
private:
QGLWidget widget;
QGLFramebufferObject fbo;
protected:
QMapboxGLSettings settings;
@@ -51,6 +56,9 @@ private slots:
};
void onNeedsRendering() {
widget.makeCurrent();
fbo.bind();
glViewport(0, 0, fbo.width(), fbo.height());
map.render();
};
};
@@ -88,3 +96,5 @@ TEST_F(QMapboxGLTest, TEST_DISABLED_ON_CI(styleUrl)) {
}
#include "qmapboxgl.moc"
#endif