qmlfrontend/game_view.cpp
branchui-scaling
changeset 15288 c4fd2813b127
parent 14847 ef9630519491
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/qmlfrontend/game_view.cpp	Wed Jul 31 23:14:27 2019 +0200
@@ -0,0 +1,106 @@
+#include "game_view.h"
+
+#include <QtQuick/qquickwindow.h>
+#include <QCursor>
+#include <QTimer>
+#include <QtGui/QOpenGLContext>
+#include <QtGui/QOpenGLShaderProgram>
+
+GameView::GameView(QQuickItem* parent)
+    : QQuickItem(parent), m_delta(0), m_windowChanged(true) {
+  connect(this, &QQuickItem::windowChanged, this,
+          &GameView::handleWindowChanged);
+}
+
+void GameView::tick(quint32 delta) {
+  m_delta = delta;
+
+  if (window()) {
+    QTimer* timer = new QTimer(this);
+    connect(timer, &QTimer::timeout, window(), &QQuickWindow::update);
+    timer->start(100);
+
+    // window()->update();
+  }
+}
+
+EngineInstance* GameView::engineInstance() const { return m_engineInstance; }
+
+void GameView::handleWindowChanged(QQuickWindow* win) {
+  if (win) {
+    connect(win, &QQuickWindow::beforeSynchronizing, this, &GameView::sync,
+            Qt::DirectConnection);
+    connect(win, &QQuickWindow::sceneGraphInvalidated, this, &GameView::cleanup,
+            Qt::DirectConnection);
+
+    win->setClearBeforeRendering(false);
+
+    m_windowChanged = true;
+  }
+}
+
+void GameView::cleanup() { m_renderer.reset(); }
+
+void GameView::setEngineInstance(EngineInstance* engineInstance) {
+  if (m_engineInstance == engineInstance) return;
+
+  cleanup();
+  m_engineInstance = engineInstance;
+
+  emit engineInstanceChanged(m_engineInstance);
+}
+
+void GameView::sync() {
+  if (!m_renderer && m_engineInstance) {
+    m_engineInstance->setOpenGLContext(window()->openglContext());
+    m_renderer.reset(new GameViewRenderer());
+    m_renderer->setEngineInstance(m_engineInstance);
+    connect(window(), &QQuickWindow::beforeRendering, m_renderer.data(),
+            &GameViewRenderer::paint, Qt::DirectConnection);
+  }
+
+  if (m_windowChanged || (m_viewportSize != window()->size())) {
+    m_windowChanged = false;
+
+    if (m_engineInstance)
+      m_engineInstance->setOpenGLContext(window()->openglContext());
+
+    m_viewportSize = window()->size();
+    m_centerPoint = QPoint(m_viewportSize.width(), m_viewportSize.height()) / 2;
+  }
+
+  if (m_engineInstance) {
+    QPoint mousePos = mapFromGlobal(QCursor::pos()).toPoint();
+    m_engineInstance->moveCamera(mousePos - m_centerPoint);
+    QCursor::setPos(mapToGlobal(m_centerPoint).toPoint());
+  }
+
+  if (m_renderer) m_renderer->tick(m_delta);
+}
+
+GameViewRenderer::GameViewRenderer()
+    : QObject(), m_delta(0), m_engineInstance(nullptr) {}
+
+GameViewRenderer::~GameViewRenderer() {}
+
+void GameViewRenderer::tick(quint32 delta) { m_delta = delta; }
+
+void GameViewRenderer::setEngineInstance(EngineInstance* engineInstance) {
+  m_engineInstance = engineInstance;
+}
+
+void GameViewRenderer::paint() {
+  if (m_delta == 0) return;
+
+  if (m_engineInstance) {
+    m_engineInstance->advance(m_delta);
+    m_engineInstance->renderFrame();
+  }
+
+  // m_window->resetOpenGLState();
+}
+
+void GameViewRenderer::onViewportSizeChanged(QQuickWindow* window) {
+  if (m_engineInstance)
+    m_engineInstance->setOpenGLContext(window->openglContext());
+}