From 2f3c6acb8d3023ca523306cef896e82029ff063c Mon Sep 17 00:00:00 2001
From: Oliver Bock <oliver.bock@aei.mpg.de>
Date: Fri, 6 Oct 2017 14:26:12 +0200
Subject: [PATCH] WIP: QGLWidget -> QOpenGLWidget migration (resolve known
 renderText() issues)

---
 src/pulsaranimationwidget.cpp | 107 +++++++++++++++++++++-------------
 src/pulsaranimationwidget.h   |   8 ++-
 2 files changed, 73 insertions(+), 42 deletions(-)

diff --git a/src/pulsaranimationwidget.cpp b/src/pulsaranimationwidget.cpp
index d775c65..f102df1 100644
--- a/src/pulsaranimationwidget.cpp
+++ b/src/pulsaranimationwidget.cpp
@@ -21,32 +21,13 @@
 #include "pulsaranimationwidget.h"
 #include "lib/antenna_lib.h"
 
+#include <QPainter>
+
 const double PulsarAnimationWidget::deg2rad = PI/180.0;
 
 PulsarAnimationWidget::PulsarAnimationWidget(QWidget *parent) :
-    QGLWidget(QGLFormat(QGL::AlphaChannel | QGL::SampleBuffers), parent)
+    QOpenGLWidget(parent)
 {
-    QString msgThis = tr("3D animation");
-    if(!format().directRendering()) {
-        QString msg = tr("Sorry, no direct rendering support for %1...");
-        qWarning() << msg.arg(msgThis);
-    }
-    if(!format().doubleBuffer()) {
-        QString msg = tr("Sorry, no double buffering support for %1...");
-        qWarning() << msg.arg(msgThis);
-    }
-    if(!format().rgba()) {
-        QString msg = tr("Sorry, no RGBA support for %1...");
-        qWarning() << msg.arg(msgThis);
-    }
-    if(!format().alpha()) {
-        QString msg = tr("Sorry, no alpha channel support for %1...");
-        qWarning() << msg.arg(msgThis);
-    }
-    if(!format().sampleBuffers()) {
-        QString msg = tr("Sorry, no multisampling support for %1...");
-        qWarning() << msg.arg(msgThis);
-    }
 
     // initialize quadric pointers
     m_quadricVirgoh = NULL;
@@ -162,11 +143,9 @@ void PulsarAnimationWidget::initializeGL()
     GLint maxTextureSize;
     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
 
-    // prepare and check beam texture
+    // prepare and bind beam texture
     QImage beamTexture(":/textures/resources/World-Map-7.jpg");
-
-    // bind textures
-    m_beamTexture = bindTexture(beamTexture, GL_TEXTURE_2D, GL_RGBA);
+    m_beamTexture = new QOpenGLTexture(beamTexture.mirrored());
 
     // use mipmapped textures
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -250,7 +229,7 @@ void PulsarAnimationWidget::paintGL()
 
             // create texture coordinates and enable texturing
             gluQuadricTexture(m_quadricEarth, GL_TRUE);
-            glBindTexture(GL_TEXTURE_2D, m_beamTexture);
+            m_beamTexture->bind();
             glEnable(GL_TEXTURE_2D);
 
             glCullFace(GL_FRONT);
@@ -452,10 +431,10 @@ void PulsarAnimationWidget::paintGL()
             font.setBold(true);
             font.setFamily("Arial");
             font.setStyleStrategy((QFont::StyleStrategy) (QFont::OpenGLCompatible | QFont::PreferQuality));
-            renderText(10, 40, -100, tr("B. Allen and O. Bock"), font);
-            renderText(10, 25, -100, tr("MPI for Gravitational Physics"));
-            renderText(10, 10, -100, QString("Copyright %1 2017").arg(QChar(0x00A9)));
-	    
+            renderText(0, 0, -100, tr("B. Allen and O. Bock"), font);
+//            renderText(10, 25, -100, tr("MPI for Gravitational Physics"));
+//            renderText(10, 10, -100, QString("Copyright %1 2017").arg(QChar(0x00A9)));
+
             // restore original state
             glMatrixMode(GL_PROJECTION);
         }
@@ -470,7 +449,7 @@ void PulsarAnimationWidget::mousePressEvent(QMouseEvent *event)
     Q_UNUSED(event);
 
     m_cameraInteraction = true;
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::mouseMoveEvent(QMouseEvent *event)
@@ -512,7 +491,7 @@ void PulsarAnimationWidget::mouseReleaseEvent(QMouseEvent *event)
     m_mouseLastY = 0;
     m_cameraInteraction = false;
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::showEvent(QShowEvent *event)
@@ -529,7 +508,7 @@ void PulsarAnimationWidget::updateCameraPosition(const double angleH, const doub
     m_cameraPosY = sin(angleV * deg2rad) * zoom;
     m_cameraPosZ = cos(angleH * deg2rad) * cos(angleV * deg2rad) * zoom;
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::setSourceInclination(const double degrees)
@@ -545,7 +524,7 @@ void PulsarAnimationWidget::setSourceInclination(const double degrees)
     m_sourceInclination = degrees;
     updatePulseProfile();
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::setLHOAngle(const double degrees)
@@ -553,7 +532,7 @@ void PulsarAnimationWidget::setLHOAngle(const double degrees)
     m_LHOAngle = degrees;
     updatePulseProfile();
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::setLLOAngle(const double degrees)
@@ -561,7 +540,7 @@ void PulsarAnimationWidget::setLLOAngle(const double degrees)
     m_LLOAngle = degrees;
     updatePulseProfile();
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::setVirgoAngle(const int degrees)
@@ -569,7 +548,7 @@ void PulsarAnimationWidget::setVirgoAngle(const int degrees)
     m_VirgoAngle = degrees;
     updatePulseProfile();
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::setSourceIota(const int degrees)
@@ -577,7 +556,7 @@ void PulsarAnimationWidget::setSourceIota(const int degrees)
     m_sourceIota = degrees;
     updatePulseProfile();
 
-    updateGL();
+    update();
 }
 
 void PulsarAnimationWidget::getCameraPosition(double& cameraAngleH, double& cameraAngleV, double& cameraZoom)
@@ -596,6 +575,56 @@ void PulsarAnimationWidget::resetCameraPosition(const double angleH, const doubl
     updateCameraPosition(m_mouseAngleH, m_mouseAngleV, m_cameraZoom);
 }
 
+void PulsarAnimationWidget::renderText(double x, double y, double z, const QString &text, const QFont & font) {
+    // Identify x and y locations to render text within widget
+    int height = this->height();
+    GLdouble textPosX = 0, textPosY = 0, textPosZ = 0;
+//    project(x, y, 0f, &textPosX, &textPosY, &textPosZ);
+    textPosY = height - textPosY; // y is inverted
+
+    // Retrieve last OpenGL color to use as a font color
+    GLdouble glColor[4];
+    glGetDoublev(GL_CURRENT_COLOR, glColor);
+    QColor fontColor = QColor(glColor[0], glColor[1], glColor[2], glColor[3]);
+
+    // save OpenGL state
+    glPushAttrib(GL_ACCUM_BUFFER_BIT);
+    glPushAttrib(GL_COLOR_BUFFER_BIT);
+    glPushAttrib(GL_CURRENT_BIT);
+    glPushAttrib(GL_DEPTH_BUFFER_BIT);
+    glPushAttrib(GL_ENABLE_BIT);
+    glPushAttrib(GL_EVAL_BIT);
+    glPushAttrib(GL_FOG_BIT);
+    glPushAttrib(GL_HINT_BIT);
+    glPushAttrib(GL_FOG_BIT);
+    glPushAttrib(GL_LIGHTING_BIT);
+    glPushAttrib(GL_LINE_BIT);
+    glPushAttrib(GL_LIST_BIT);
+    glPushAttrib(GL_MULTISAMPLE_BIT);
+    glPushAttrib(GL_PIXEL_MODE_BIT);
+    glPushAttrib(GL_POINT_BIT);
+    glPushAttrib(GL_POLYGON_BIT);
+    glPushAttrib(GL_POLYGON_STIPPLE_BIT);
+    glPushAttrib(GL_SCISSOR_BIT);
+    glPushAttrib(GL_STENCIL_BUFFER_BIT);
+    glPushAttrib(GL_TEXTURE_BIT);
+    glPushAttrib(GL_TRANSFORM_BIT);
+    glPushAttrib(GL_VIEWPORT_BIT);
+    glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS);
+
+    // Render text
+    QPainter painter(this);
+    painter.setPen(fontColor);
+    painter.setFont(font);
+    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+    painter.drawText(textPosX, textPosY, text);
+    painter.end();
+
+    // save OpenGL state
+    glPopAttrib();
+    glPopClientAttrib();
+}
+
 void PulsarAnimationWidget::updatePulseProfile()
 {
     struct InputStruct in;
diff --git a/src/pulsaranimationwidget.h b/src/pulsaranimationwidget.h
index a73db47..ccb080f 100644
--- a/src/pulsaranimationwidget.h
+++ b/src/pulsaranimationwidget.h
@@ -23,7 +23,8 @@
 
 #include <cmath>
 
-#include <QGLWidget>
+#include <QOpenGLWidget>
+#include <QOpenGLTexture>
 #include <QTimer>
 #include <QMouseEvent>
 #include <QDebug>
@@ -39,7 +40,7 @@
 
 #define PI 3.14159265
 
-class PulsarAnimationWidget : public QGLWidget
+class PulsarAnimationWidget : public QOpenGLWidget
 {
     Q_OBJECT
 
@@ -54,6 +55,7 @@ public:
     void setSourceInclination(const double length);
     void getCameraPosition(double& cameraAngleH, double& cameraAngleV, double& cameraZoom);
     void resetCameraPosition(const double angleH, const double angleV, const double zoom);
+    void renderText(double x, double y, double z, const QString &text, const QFont & font = QFont());
 
 signals:
     void pulseProfileUpdated(const PlotData& data);
@@ -83,7 +85,7 @@ private:
     GLUquadricObj *m_quadricLHOv;
     GLUquadricObj *m_quadricLHOh;
 
-    GLuint m_beamTexture;
+    QOpenGLTexture *m_beamTexture;
 
     double m_earthRadius;
     double m_LHOAngle;
-- 
GitLab