summaryrefslogtreecommitdiffstats
path: root/examples/opengl/qopenglwidget/glwidget.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'examples/opengl/qopenglwidget/glwidget.cpp')
-rw-r--r--examples/opengl/qopenglwidget/glwidget.cpp51
1 files changed, 39 insertions, 12 deletions
diff --git a/examples/opengl/qopenglwidget/glwidget.cpp b/examples/opengl/qopenglwidget/glwidget.cpp
index a480fe5726f..da098319e42 100644
--- a/examples/opengl/qopenglwidget/glwidget.cpp
+++ b/examples/opengl/qopenglwidget/glwidget.cpp
@@ -66,9 +66,8 @@ const int bubbleNum = 8;
#define GL_SRGB8_ALPHA8 0x8C43
#endif
-GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background)
- : m_mainWindow(mw),
- m_hasButton(button),
+GLWidget::GLWidget(MainWindow *maybeMainWindow, const QColor &background)
+ : m_mainWindow(maybeMainWindow),
m_background(background)
{
setMinimumSize(300, 250);
@@ -78,20 +77,41 @@ GLWidget::GLWidget(MainWindow *mw, bool button, const QColor &background)
GLWidget::~GLWidget()
{
+ reset();
+}
+
+void GLWidget::reset()
+{
qDeleteAll(m_bubbles);
+ // Leave everything in a state suitable for a subsequent call to
+ // initialize(). This matters when coming from the context's
+ // aboutToBeDestroyed signal, would not matter when invoked from the
+ // destructor.
+ m_bubbles.clear();
// And now release all OpenGL resources.
makeCurrent();
delete m_texture;
+ m_texture = nullptr;
delete m_program1;
+ m_program1 = nullptr;
delete m_program2;
+ m_program2 = nullptr;
delete m_vshader1;
+ m_vshader1 = nullptr;
delete m_fshader1;
+ m_fshader1 = nullptr;
delete m_vshader2;
+ m_vshader2 = nullptr;
delete m_fshader2;
+ m_fshader2 = nullptr;
m_vbo1.destroy();
m_vbo2.destroy();
doneCurrent();
+
+ // We are done with the current QOpenGLContext, forget it. If there is a
+ // subsequent initialize(), that will then connect to the new context.
+ QObject::disconnect(m_contextWatchConnection);
}
void GLWidget::setScaling(int scale)
@@ -334,6 +354,13 @@ void GLWidget::initializeGL()
m_vbo1.release();
createBubbles(bubbleNum - m_bubbles.count());
+
+ // A well-behaved QOpenGLWidget releases OpenGL resources not only upon
+ // destruction, but also when the associated OpenGL context disappears. If
+ // the widget continues to exist, the context's destruction will be
+ // followed by a call to initialize(). This is not strictly mandatory in
+ // widgets that never change their parents.
+ m_contextWatchConnection = QObject::connect(context(), &QOpenGLContext::aboutToBeDestroyed, context(), [this] { reset(); });
}
void GLWidget::paintGL()
@@ -403,7 +430,7 @@ void GLWidget::paintGL()
// When requested, follow the ideal way to animate: Rely on
// blocking swap and just schedule updates continuously.
- if (!m_mainWindow->timerEnabled())
+ if (!m_mainWindow || !m_mainWindow->timerEnabled())
update();
}
@@ -545,16 +572,16 @@ void GLWidget::setTransparent(bool transparent)
void GLWidget::resizeGL(int, int)
{
- if (m_hasButton) {
+ if (m_mainWindow) {
if (!m_btn) {
- m_btn = new QPushButton("A widget on top.\nPress for more widgets.", this);
- connect(m_btn, &QPushButton::clicked, this, &GLWidget::handleButtonPress);
+ m_btn = new QPushButton("\nAdd widget\n", this);
+ connect(m_btn, &QPushButton::clicked, this, [this] { m_mainWindow->addNew(); });
}
m_btn->move(20, 80);
+ if (!m_btn2) {
+ m_btn2 = new QPushButton("\nI prefer tabbed widgets\n", this);
+ connect(m_btn2, &QPushButton::clicked, this, [this] { m_mainWindow->showNewWindow(); });
+ }
+ m_btn2->move(20, 160);
}
}
-
-void GLWidget::handleButtonPress()
-{
- m_mainWindow->addNew();
-}