Skip to content

Commit

Permalink
add QOpenGLWidget for Qt<5.4 without opengl module
Browse files Browse the repository at this point in the history
TODO:
events, paintEngine
  • Loading branch information
wang-bin committed Jan 12, 2015
1 parent 9401ec9 commit 215b9c1
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 8 deletions.
178 changes: 178 additions & 0 deletions widgets/QOpenGLWidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2015 Wang Bin <[email protected]>
* This file is part of QtAV
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
#include "QtAVWidgets/QOpenGLWidget.h"
#include <QResizeEvent>
#include <QWindow>

namespace QtAV {

QOpenGLWidget::QOpenGLWidget(QWidget *parent, Qt::WindowFlags f)
: QWidget(parent, f)
, m_initialized(false)
, m_fakeHidden(false)
, m_context(0)
, m_paintDevice(0)
{
setAttribute(Qt::WA_NativeWindow); // ensure windowHandle() is not null
// WA_PaintOnScreen: QWidget::paintEngine: Should no longer be called. This flag is only supported on X11 and it disables double buffering
//setAttribute(Qt::WA_PaintOnScreen); // enforce native window, so windowHandle() is not null
setAttribute(Qt::WA_NoSystemBackground);
setAutoFillBackground(true); // for compatibility
// FIXME: why setSurfaceType crash?
//windowHandle()->setSurfaceType(QWindow::OpenGLSurface);
}

QOpenGLWidget::~QOpenGLWidget()
{
delete m_paintDevice;
}

void QOpenGLWidget::setFormat(const QSurfaceFormat &format)
{
m_requestedFormat = format;
}

QSurfaceFormat QOpenGLWidget::format() const
{
return m_requestedFormat;
}

bool QOpenGLWidget::isValid() const
{
return m_initialized && m_context->isValid();
}

void QOpenGLWidget::makeCurrent()
{
if (!m_initialized) {
qWarning("QOpenGLWidget: Cannot make uninitialized widget current");
return;
}
if (!windowHandle()) {
qWarning("QOpenGLWidget: No window handle");
return;
}
m_context->makeCurrent((QSurface*)windowHandle());
}

void QOpenGLWidget::doneCurrent()
{
if (!m_initialized)
return;
m_context->doneCurrent();
}

QOpenGLContext *QOpenGLWidget::context() const
{
return m_context;
}

void QOpenGLWidget::initializeGL()
{
}
void QOpenGLWidget::paintGL()
{
}

void QOpenGLWidget::resizeGL(int w, int h)
{
Q_UNUSED(w);
Q_UNUSED(h);
}

void QOpenGLWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
if (!m_initialized)
return;
if (updatesEnabled())
render();
}

void QOpenGLWidget::resizeEvent(QResizeEvent *e)
{
if (e->size().isEmpty()) {
m_fakeHidden = true;
return;
}
m_fakeHidden = false;
initialize();
if (!m_initialized)
return;
//recreateFbo();
resizeGL(width(), height());
invokeUserPaint();
//resolveSamples();
}

void QOpenGLWidget::initialize()
{
if (m_initialized)
return;

QWindow *win = windowHandle();
if (!win) {
qWarning("QOpenGLWidget: No window handle");
return;
}
m_context = new QOpenGLContext(this);
// TODO: shareContext()
m_context->setFormat(m_requestedFormat);
if (!m_context->create()) {
qWarning("QOpenGLWidget: Failed to create context");
return;
}
//m_context = QOpenGLContext::currentContext();
if (!m_context) {
qWarning("QOpenGLWidget: QOpenGLContext is null");
return;
}
if (!m_context->makeCurrent(win)) {
qWarning("QOpenGLWidget: Failed to make context current");
return;
}
m_paintDevice = new QOpenGLPaintDevice();
m_paintDevice->setSize(size() * devicePixelRatio());
m_paintDevice->setDevicePixelRatio(devicePixelRatio());
m_initialized = true;
initializeGL();
}

void QOpenGLWidget::render()
{
if (m_fakeHidden || !m_initialized)
return;
// QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined
if (!windowHandle() || !windowHandle()->isExposed())
return;
makeCurrent();
invokeUserPaint();
m_context->swapBuffers(windowHandle());
}

void QOpenGLWidget::invokeUserPaint()
{
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glViewport(0, 0, width()*devicePixelRatio(), height()*devicePixelRatio());
paintGL();
f->glFlush();
}
} //namespace QtAV
6 changes: 5 additions & 1 deletion widgets/QtAVWidgets/OpenGLWidgetRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
#define QTAV_OPENGLWIDGETRENDERER_H

#include <QtAVWidgets/global.h>
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#include <QtWidgets/QOpenGLWidget>
#else
#include <QtAVWidgets/QOpenGLWidget.h>
#endif //QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#include <QtAV/OpenGLRendererBase.h>

namespace QtAV {

// do not define QOpenGLWidget here with ifdef to avoid moc error
class OpenGLWidgetRendererPrivate;
class Q_AVWIDGETS_EXPORT OpenGLWidgetRenderer : public QOpenGLWidget, public OpenGLRendererBase
{
Expand Down
72 changes: 72 additions & 0 deletions widgets/QtAVWidgets/QOpenGLWidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/******************************************************************************
QtAV: Media play library based on Qt and FFmpeg
Copyright (C) 2015 Wang Bin <[email protected]>
* This file is part of QtAV
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/

#ifndef QTAV_QOPENGLWIDGET_H
#define QTAV_QOPENGLWIDGET_H

#include <QtAVWidgets/global.h>
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#error "Qt5 is required!"
#endif
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLPaintDevice>
#include <QtGui/QSurfaceFormat>
#include <QtWidgets/QWidget>

namespace QtAV {

/*!
* \brief The QOpenGLWidget class
* A widget for rendering OpenGL graphics without QtOpenGL module
*/
class Q_AVWIDGETS_EXPORT QOpenGLWidget : public QWidget
{
Q_OBJECT
Q_DISABLE_COPY(QOpenGLWidget)
public:
explicit QOpenGLWidget(QWidget* parent = 0, Qt::WindowFlags f = 0);
virtual ~QOpenGLWidget();
void setFormat(const QSurfaceFormat &format);
QSurfaceFormat format() const;
bool isValid() const;
void makeCurrent();
void doneCurrent();
QOpenGLContext *context() const;
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
void paintEvent(QPaintEvent *e) Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *e) Q_DECL_OVERRIDE;
private:
void initialize();
void render();
void invokeUserPaint();

bool m_initialized;
bool m_fakeHidden;
QOpenGLContext *m_context;
QOpenGLPaintDevice *m_paintDevice;
QSurfaceFormat m_requestedFormat;
};
} //namespace QtAV

#endif //QTAV_QOPENGLWIDGET_H
6 changes: 3 additions & 3 deletions widgets/global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#if QTAV_HAVE(GL1)
#include "QtAVWidgets/GLWidgetRenderer.h"
#endif //QTAV_HAVE(GL1)
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#include "QtAVWidgets/OpenGLWidgetRenderer.h"
#endif
#include "QtAV/private/factory.h"
Expand Down Expand Up @@ -96,7 +96,7 @@ void RegisterVideoRendererGLWidget2_Man()
FACTORY_REGISTER_ID_MAN(VideoRenderer, GLWidget2, "QGLWidegt2")
}
#endif //QTAV_HAVE(GL)
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
#if AUTO_REGISTER
FACTORY_REGISTER_ID_AUTO(VideoRenderer, OpenGLWidget, "OpenGLWidget")
#else
Expand All @@ -119,7 +119,7 @@ void registerRenderers()
const std::vector<VideoRendererId> ids(VideoRendererFactory::registeredIds());
if (std::find(ids.begin(), ids.end(), VideoRendererId_Widget) != ids.end())
return;
#if QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)
#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
RegisterVideoRendererOpenGLWidget_Man();
#endif
#if QTAV_HAVE(GL)
Expand Down
10 changes: 6 additions & 4 deletions widgets/libQtAVWidgets.pro
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,22 @@ SDK_HEADERS *= \
QtAVWidgets/QtAVWidgets.h \
QtAVWidgets/global.h \
QtAVWidgets/version.h \
QtAVWidgets/OpenGLWidgetRenderer.h \
QtAVWidgets/GraphicsItemRenderer.h \
QtAVWidgets/WidgetRenderer.h

HEADERS *= $$QTAVSRC/output/video/VideoOutputEventFilter.h
SOURCES *= \
global.cpp \
$$QTAVSRC/output/video/VideoOutputEventFilter.cpp \
$$QTAVSRC/output/video/OpenGLWidgetRenderer.cpp \
$$QTAVSRC/output/video/GraphicsItemRenderer.cpp \
$$QTAVSRC/output/video/WidgetRenderer.cpp

!config_opengl {
SDK_HEADERS *= QtAVWidgets/QOpenGLWidget.h
SOURCES *= QOpenGLWidget.cpp
}
config_gl {
DEFINES *= QTAV_HAVE_GL=1
SOURCES += $$QTAVSRC/output/video/GLWidgetRenderer2.cpp
Expand All @@ -79,10 +85,6 @@ config_gl {
#SDK_HEADERS += QtAVWidgets/GLWidgetRenderer.h
}
}
config_opengl {
SDK_HEADERS *= QtAVWidgets/OpenGLWidgetRenderer.h
SOURCES *= $$QTAVSRC/output/video/OpenGLWidgetRenderer.cpp
}
config_gdiplus {
DEFINES *= QTAV_HAVE_GDIPLUS=1
SOURCES += $$QTAVSRC/output/video/GDIRenderer.cpp
Expand Down

0 comments on commit 215b9c1

Please sign in to comment.