From 9e3bab30ae6a1f87af82a2fdc9502fbaa98a3351 Mon Sep 17 00:00:00 2001 From: ExMix Date: Tue, 18 Nov 2014 10:59:23 +0300 Subject: [PATCH] [desktop] surface and OGL for desktop build with drape renderer --- drape_frontend/frontend_renderer.cpp | 2 +- qt/drape_surface.cpp | 130 +++++++++++++++++++++++++++ qt/drape_surface.hpp | 48 ++++++++++ qt/qtoglcontext.cpp | 49 ++++++++++ qt/qtoglcontext.hpp | 22 +++++ qt/qtoglcontextfactory.cpp | 31 +++++++ qt/qtoglcontextfactory.hpp | 21 +++++ 7 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 qt/drape_surface.cpp create mode 100644 qt/drape_surface.hpp create mode 100644 qt/qtoglcontext.cpp create mode 100644 qt/qtoglcontext.hpp create mode 100644 qt/qtoglcontextfactory.cpp create mode 100644 qt/qtoglcontextfactory.hpp diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index d16a72cbef..1fe377bb47 100644 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -198,7 +198,7 @@ void FrontendRenderer::RenderScene() GLFunctions::glEnable(gl_const::GLDepthTest); GLFunctions::glClearColor(0.93f, 0.93f, 0.86f, 1.f); - GLFunctions::glClearDepth(1.0); + GLFunctions::glClearDepthValue(1.0); GLFunctions::glDepthFunc(gl_const::GLLessOrEqual); GLFunctions::glDepthMask(true); diff --git a/qt/drape_surface.cpp b/qt/drape_surface.cpp new file mode 100644 index 0000000000..3a2287b3ad --- /dev/null +++ b/qt/drape_surface.cpp @@ -0,0 +1,130 @@ +#include "drape_surface.hpp" + +#include "../drape_frontend/viewport.hpp" + +#include "../base/stl_add.hpp" +#include "../base/logging.hpp" + +#include "../std/bind.hpp" +#include "../std/cmath.hpp" + +#include + +namespace qt +{ + +DrapeSurface::DrapeSurface() + : m_dragState(false) + , m_contextFactory(NULL) +{ + setSurfaceType(QSurface::OpenGLSurface); + + QObject::connect(this, SIGNAL(heightChanged(int)), this, SLOT(sizeChanged(int))); + QObject::connect(this, SIGNAL(widthChanged(int)), this, SLOT(sizeChanged(int))); +} + +DrapeSurface::~DrapeSurface() +{ + m_framework.PrepareToShutdown(); + m_contextFactory.Destroy(); +} + +void DrapeSurface::LoadState() +{ + if (!m_framework.LoadState()) + m_framework.ShowAll(); + else + m_framework.Invalidate(); +} + +void DrapeSurface::SaveState() +{ + m_framework.SaveState(); +} + +void DrapeSurface::exposeEvent(QExposeEvent *e) +{ + Q_UNUSED(e); + + if (isExposed()) + { + if (m_contextFactory.IsNull()) + { + dp::ThreadSafeFactory * factory = new dp::ThreadSafeFactory(new QtOGLContextFactory(this)); + m_contextFactory = dp::MasterPointer(factory); + CreateEngine(); + } + } +} + +void DrapeSurface::mousePressEvent(QMouseEvent * e) +{ + QWindow::mousePressEvent(e); + if (!isExposed()) + return; + + if (e->button() == Qt::LeftButton) + { + m2::PointF const p = GetDevicePosition(e->pos()); + DragEvent const event(p.x, p.y); + m_framework.StartDrag(event); + m_dragState = true; + } +} + +void DrapeSurface::mouseMoveEvent(QMouseEvent * e) +{ + QWindow::mouseMoveEvent(e); + if (!isExposed()) + return; + + if (m_dragState) + { + m2::PointF const p = GetDevicePosition(e->pos()); + DragEvent const event(p.x, p.y); + m_framework.DoDrag(event); + } +} + +void DrapeSurface::mouseReleaseEvent(QMouseEvent * e) +{ + QWindow::mouseReleaseEvent(e); + if (!isExposed()) + return; + + if (m_dragState) + { + m2::PointF const p = GetDevicePosition(e->pos()); + DragEvent const event(p.x, p.y); + m_framework.StopDrag(event); + m_dragState = false; + } +} + +void DrapeSurface::wheelEvent(QWheelEvent * e) +{ + if (!m_dragState) + { + m2::PointF const p = GetDevicePosition(e->pos()); + ScaleToPointEvent const event(p.x, p.y, exp(e->delta() / 360.0)); + m_framework.ScaleToPoint(event, false); + } +} + +void DrapeSurface::CreateEngine() +{ + m_framework.CreateDrapeEngine(m_contextFactory.GetRefPointer(), devicePixelRatio(), width(), height()); +} + +void DrapeSurface::sizeChanged(int) +{ + m_framework.OnSize(width(), height()); +} + +m2::PointF DrapeSurface::GetDevicePosition(QPoint const & p) +{ + qreal const ratio = devicePixelRatio(); + return m2::PointF(p.x() * ratio, p.y() * ratio); +} + +} diff --git a/qt/drape_surface.hpp b/qt/drape_surface.hpp new file mode 100644 index 0000000000..9df8236e2d --- /dev/null +++ b/qt/drape_surface.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "qtoglcontextfactory.hpp" + +#include "../map/framework.hpp" +#include "../drape_frontend/drape_engine.hpp" + +#include + +namespace qt +{ + +class DrapeSurface : public QWindow +{ + Q_OBJECT + +public: + DrapeSurface(); + ~DrapeSurface(); + + void LoadState(); + void SaveState(); + + Framework & GetFramework() { return m_framework; } + +protected: + void exposeEvent(QExposeEvent * e); + void mousePressEvent(QMouseEvent * e); + void mouseMoveEvent(QMouseEvent * e); + void mouseReleaseEvent(QMouseEvent * e); + void wheelEvent(QWheelEvent * e); + +private: + void CreateEngine(); + + Q_SLOT void sizeChanged(int); + +private: + m2::PointF GetDevicePosition(QPoint const & p); + + bool m_dragState; + +private: + Framework m_framework; + dp::MasterPointer m_contextFactory; +}; + +} // namespace qt diff --git a/qt/qtoglcontext.cpp b/qt/qtoglcontext.cpp new file mode 100644 index 0000000000..feee116dc1 --- /dev/null +++ b/qt/qtoglcontext.cpp @@ -0,0 +1,49 @@ +#include "qtoglcontext.hpp" + +#include "../base/assert.hpp" +#include "../base/logging.hpp" + +#include "../drape/glfunctions.hpp" + +QtOGLContext::QtOGLContext(QWindow * surface, QtOGLContext * contextToShareWith) +{ + m_isContextCreated = false; + m_surface = surface; + m_nativeContext = new QOpenGLContext(); + + if (contextToShareWith != NULL) + m_nativeContext->setShareContext(contextToShareWith->m_nativeContext); + + m_nativeContext->setFormat(m_surface->requestedFormat()); + ASSERT(m_surface->isExposed(), ()); + VERIFY(m_nativeContext->create(), ()); +} + +QtOGLContext::~QtOGLContext() +{ + delete m_nativeContext; +} + +void QtOGLContext::makeCurrent() +{ + ASSERT(m_nativeContext->isValid(), ()); + m_nativeContext->makeCurrent(m_surface); + +#ifdef DEBUG + LOG(LDEBUG, ("Current context : ", m_nativeContext)); + QList list = QOpenGLContextGroup::currentContextGroup()->shares(); + for (int i = 0; i < list.size(); ++i) + LOG(LDEBUG, ("Share context : ", list[i])); +#endif +} + +void QtOGLContext::present() +{ + m_nativeContext->makeCurrent(m_surface); + m_nativeContext->swapBuffers(m_surface); +} + +void QtOGLContext::setDefaultFramebuffer() +{ + GLFunctions::glBindFramebuffer(GL_FRAMEBUFFER, 0); +} diff --git a/qt/qtoglcontext.hpp b/qt/qtoglcontext.hpp new file mode 100644 index 0000000000..aec0a1339b --- /dev/null +++ b/qt/qtoglcontext.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "../drape/oglcontext.hpp" + +#include +#include + +class QtOGLContext: public dp::OGLContext +{ +public: + QtOGLContext(QWindow * surface, QtOGLContext * contextToShareWith); + ~QtOGLContext(); + + virtual void present(); + virtual void makeCurrent(); + virtual void setDefaultFramebuffer(); + +private: + QOpenGLContext * m_nativeContext; + QWindow * m_surface; + bool m_isContextCreated; +}; diff --git a/qt/qtoglcontextfactory.cpp b/qt/qtoglcontextfactory.cpp new file mode 100644 index 0000000000..33ad81691a --- /dev/null +++ b/qt/qtoglcontextfactory.cpp @@ -0,0 +1,31 @@ +#include "qtoglcontextfactory.hpp" + +#include "../base/assert.hpp" + +QtOGLContextFactory::QtOGLContextFactory(QWindow * surface) + : m_surface(surface) + , m_drawContext(NULL) + , m_uploadContext(NULL) +{} + +QtOGLContextFactory::~QtOGLContextFactory() +{ + delete m_drawContext; + delete m_uploadContext; +} + +dp::OGLContext * QtOGLContextFactory::getDrawContext() +{ + if (m_drawContext == NULL) + m_drawContext = new QtOGLContext(m_surface, m_uploadContext); + + return m_drawContext; +} + +dp::OGLContext * QtOGLContextFactory::getResourcesUploadContext() +{ + if (m_uploadContext == NULL) + m_uploadContext = new QtOGLContext(m_surface, m_drawContext); + + return m_uploadContext; +} diff --git a/qt/qtoglcontextfactory.hpp b/qt/qtoglcontextfactory.hpp new file mode 100644 index 0000000000..4b65f12fe3 --- /dev/null +++ b/qt/qtoglcontextfactory.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "../../drape/oglcontextfactory.hpp" +#include "qtoglcontext.hpp" + +#include + +class QtOGLContextFactory : public dp::OGLContextFactory +{ +public: + QtOGLContextFactory(QWindow * surface); + ~QtOGLContextFactory(); + + virtual dp::OGLContext * getDrawContext(); + virtual dp::OGLContext * getResourcesUploadContext(); + +private: + QWindow * m_surface; + QtOGLContext * m_drawContext; + QtOGLContext * m_uploadContext; +};