qt 6.5.1 original

This commit is contained in:
kleuter
2023-10-29 23:33:08 +01:00
parent 71d22ab6b0
commit 85d238dfda
21202 changed files with 5499099 additions and 0 deletions

View File

@ -0,0 +1,39 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(contextinfo LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opengl/contextinfo")
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpenGL Widgets)
qt_standard_project_setup()
qt_add_executable(contextinfo
main.cpp
renderwindow.cpp renderwindow.h
widget.cpp widget.h
)
set_target_properties(contextinfo PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(contextinfo PRIVATE
Qt6::Core
Qt6::Gui
Qt6::OpenGL
Qt6::Widgets
)
install(TARGETS contextinfo
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -0,0 +1,14 @@
TEMPLATE = app
QT += widgets opengl
requires(qtConfig(filedialog))
SOURCES += main.cpp \
widget.cpp \
renderwindow.cpp
HEADERS += widget.h \
renderwindow.h
# install
target.path = $$[QT_INSTALL_EXAMPLES]/opengl/contextinfo
INSTALLS += target

View File

@ -0,0 +1,25 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include "widget.h"
int main(int argc, char **argv)
{
for (int i = 1; i < argc; ++i) {
if (!qstrcmp(argv[i], "-g"))
QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
else if (!qstrcmp(argv[i], "-s"))
QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
else if (!qstrcmp(argv[i], "-d"))
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
}
QApplication app(argc, argv);
Widget w;
w.resize(700, 800);
w.show();
return app.exec();
}

View File

@ -0,0 +1,191 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "renderwindow.h"
#include <QTimer>
#include <QMatrix4x4>
#include <QOpenGLContext>
#include <QtOpenGL/QOpenGLShaderProgram>
#include <QOpenGLFunctions>
RenderWindow::RenderWindow(const QSurfaceFormat &format)
: m_context(nullptr),
m_initialized(false),
m_forceGLSL110(false),
m_angle(0.0f)
{
setSurfaceType(QWindow::OpenGLSurface);
setFormat(format);
m_context = new QOpenGLContext(this);
m_context->setFormat(requestedFormat());
if (!m_context->create()) {
delete m_context;
m_context = nullptr;
}
}
void RenderWindow::exposeEvent(QExposeEvent *)
{
if (isExposed())
render();
}
// ES needs the precision qualifiers.
// On desktop GL QOpenGLShaderProgram inserts dummy defines for highp/mediump/lowp.
static const char *vertexShaderSource110 =
"attribute highp vec4 posAttr;\n"
"attribute lowp vec4 colAttr;\n"
"varying lowp vec4 col;\n"
"uniform highp mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource110 =
"varying lowp vec4 col;\n"
"void main() {\n"
" gl_FragColor = col;\n"
"}\n";
static const char *vertexShaderSource =
"#version 150\n"
"in vec4 posAttr;\n"
"in vec4 colAttr;\n"
"out vec4 col;\n"
"uniform mat4 matrix;\n"
"void main() {\n"
" col = colAttr;\n"
" gl_Position = matrix * posAttr;\n"
"}\n";
static const char *fragmentShaderSource =
"#version 150\n"
"in vec4 col;\n"
"out vec4 fragColor;\n"
"void main() {\n"
" fragColor = col;\n"
"}\n";
static GLfloat vertices[] = {
0.0f, 0.707f,
-0.5f, -0.5f,
0.5f, -0.5f
};
static GLfloat colors[] = {
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f
};
void RenderWindow::init()
{
m_program = new QOpenGLShaderProgram(this);
QSurfaceFormat format = m_context->format();
bool useNewStyleShader = format.profile() == QSurfaceFormat::CoreProfile;
// Try to handle 3.0 & 3.1 that do not have the core/compatibility profile concept 3.2+ has.
// This may still fail since version 150 (3.2) is specified in the sources but it's worth a try.
if (format.renderableType() == QSurfaceFormat::OpenGL && format.majorVersion() == 3 && format.minorVersion() <= 1)
useNewStyleShader = !format.testOption(QSurfaceFormat::DeprecatedFunctions);
if (m_forceGLSL110)
useNewStyleShader = false;
const char *vsrc = useNewStyleShader ? vertexShaderSource : vertexShaderSource110;
const char *fsrc = useNewStyleShader ? fragmentShaderSource : fragmentShaderSource110;
qDebug("Using version %s shader", useNewStyleShader ? "150" : "110");
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc)) {
emit error(m_program->log());
return;
}
if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc)) {
emit error(m_program->log());
return;
}
if (!m_program->link()) {
emit error(m_program->log());
return;
}
m_posAttr = m_program->attributeLocation("posAttr");
m_colAttr = m_program->attributeLocation("colAttr");
m_matrixUniform = m_program->uniformLocation("matrix");
m_vbo.create();
m_vbo.bind();
m_vbo.allocate(vertices, sizeof(vertices) + sizeof(colors));
m_vbo.write(sizeof(vertices), colors, sizeof(colors));
m_vbo.release();
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
if (m_vao.isCreated()) // have VAO support, use it
setupVertexAttribs();
}
void RenderWindow::setupVertexAttribs()
{
m_vbo.bind();
m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 2);
m_program->setAttributeBuffer(m_colAttr, GL_FLOAT, sizeof(vertices), 3);
m_program->enableAttributeArray(m_posAttr);
m_program->enableAttributeArray(m_colAttr);
m_vbo.release();
}
bool RenderWindow::event(QEvent *ev)
{
if (ev->type() == QEvent::UpdateRequest)
render();
return QWindow::event(ev);
}
void RenderWindow::render()
{
if (!m_context->makeCurrent(this)) {
emit error(tr("makeCurrent() failed"));
return;
}
QOpenGLFunctions *f = m_context->functions();
if (!m_initialized) {
m_initialized = true;
f->glEnable(GL_DEPTH_TEST);
f->glClearColor(0, 0, 0, 1);
init();
emit ready();
}
if (!m_vbo.isCreated()) // init() failed, don't bother with trying to render
return;
const qreal retinaScale = devicePixelRatio();
f->glViewport(0, 0, width() * retinaScale, height() * retinaScale);
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_program->bind();
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f / 3.0f, 0.1f, 100.0f);
matrix.translate(0.0f, 0.0f, -2.0f);
matrix.rotate(m_angle, 0.0f, 1.0f, 0.0f);
m_program->setUniformValue(m_matrixUniform, matrix);
if (m_vao.isCreated())
m_vao.bind();
else // no VAO support, set the vertex attribute arrays now
setupVertexAttribs();
f->glDrawArrays(GL_TRIANGLES, 0, 3);
m_vao.release();
m_program->release();
// swapInterval is 1 by default which means that swapBuffers() will (hopefully) block
// and wait for vsync.
m_context->swapBuffers(this);
m_angle += 1.0f;
requestUpdate();
}

View File

@ -0,0 +1,48 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef RENDERWINDOW_H
#define RENDERWINDOW_H
#include <QWindow>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>
QT_FORWARD_DECLARE_CLASS(QOpenGLContext)
QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
class RenderWindow : public QWindow
{
Q_OBJECT
public:
RenderWindow(const QSurfaceFormat &format);
QOpenGLContext *context() { return m_context; }
void exposeEvent(QExposeEvent *) override;
void setForceGLSL110(bool enable) { m_forceGLSL110 = enable; }
signals:
void ready();
void error(const QString &msg);
protected:
bool event(QEvent *ev) override;
private slots:
void render();
private:
void init();
void setupVertexAttribs();
QOpenGLContext *m_context;
bool m_initialized;
bool m_forceGLSL110;
QOpenGLShaderProgram *m_program;
int m_posAttr, m_colAttr, m_matrixUniform;
QOpenGLVertexArrayObject m_vao;
QOpenGLBuffer m_vbo;
float m_angle;
};
#endif // RENDERWINDOW_H

View File

@ -0,0 +1,360 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "widget.h"
#include "renderwindow.h"
#include <QVBoxLayout>
#include <QComboBox>
#include <QGroupBox>
#include <QRadioButton>
#include <QCheckBox>
#include <QHBoxLayout>
#include <QLabel>
#include <QList>
#include <QByteArray>
#include <QPushButton>
#include <QTextEdit>
#include <QSplitter>
#include <QGuiApplication>
#include <QSurfaceFormat>
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QDebug>
#include <QTextStream>
struct Version {
const char *str;
int major;
int minor;
};
static struct Version versions[] = {
{ "1.0", 1, 0 },
{ "1.1", 1, 1 },
{ "1.2", 1, 2 },
{ "1.3", 1, 3 },
{ "1.4", 1, 4 },
{ "1.5", 1, 5 },
{ "2.0", 2, 0 },
{ "2.1", 2, 1 },
{ "3.0", 3, 0 },
{ "3.1", 3, 1 },
{ "3.2", 3, 2 },
{ "3.3", 3, 3 },
{ "4.0", 4, 0 },
{ "4.1", 4, 1 },
{ "4.2", 4, 2 },
{ "4.3", 4, 3 },
{ "4.4", 4, 4 },
{ "4.5", 4, 5 }
};
struct Profile {
const char *str;
QSurfaceFormat::OpenGLContextProfile profile;
};
static struct Profile profiles[] = {
{ "none", QSurfaceFormat::NoProfile },
{ "core", QSurfaceFormat::CoreProfile },
{ "compatibility", QSurfaceFormat::CompatibilityProfile }
};
struct Option {
const char *str;
QSurfaceFormat::FormatOption option;
};
static struct Option options[] = {
{ "deprecated functions (not forward compatible)", QSurfaceFormat::DeprecatedFunctions },
{ "debug context", QSurfaceFormat::DebugContext },
{ "stereo buffers", QSurfaceFormat::StereoBuffers },
// This is not a QSurfaceFormat option but is helpful to determine if the driver
// allows compiling old-style shaders with core profile.
{ "force version 110 shaders", QSurfaceFormat::FormatOption(0) }
};
struct Renderable {
const char *str;
QSurfaceFormat::RenderableType renderable;
};
static struct Renderable renderables[] = {
{ "default", QSurfaceFormat::DefaultRenderableType },
#ifndef Q_OS_ANDROID
{ "OpenGL", QSurfaceFormat::OpenGL },
#endif
{ "OpenGL ES", QSurfaceFormat::OpenGLES }
};
void Widget::addVersions(QLayout *layout)
{
QHBoxLayout *hbox = new QHBoxLayout;
hbox->setSpacing(20);
QLabel *label = new QLabel(tr("Context &version: "));
hbox->addWidget(label);
m_version = new QComboBox;
m_version->setMinimumWidth(60);
label->setBuddy(m_version);
hbox->addWidget(m_version);
for (size_t i = 0; i < sizeof(versions) / sizeof(Version); ++i) {
m_version->addItem(QString::fromLatin1(versions[i].str));
if (versions[i].major == 2 && versions[i].minor == 0)
m_version->setCurrentIndex(m_version->count() - 1);
}
QPushButton *btn = new QPushButton(tr("Create context"));
connect(btn, &QPushButton::clicked, this, &Widget::start);
btn->setMinimumSize(120, 40);
hbox->addWidget(btn);
layout->addItem(hbox);
}
void Widget::addProfiles(QLayout *layout)
{
QGroupBox *groupBox = new QGroupBox(tr("Profile"));
QVBoxLayout *vbox = new QVBoxLayout;
for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
vbox->addWidget(new QRadioButton(QString::fromLatin1(profiles[i].str)));
static_cast<QRadioButton *>(vbox->itemAt(0)->widget())->setChecked(true);
groupBox->setLayout(vbox);
layout->addWidget(groupBox);
m_profiles = vbox;
}
void Widget::addOptions(QLayout *layout)
{
QGroupBox *groupBox = new QGroupBox(tr("Options"));
QVBoxLayout *vbox = new QVBoxLayout;
for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
vbox->addWidget(new QCheckBox(QString::fromLatin1(options[i].str)));
groupBox->setLayout(vbox);
layout->addWidget(groupBox);
m_options = vbox;
}
void Widget::addRenderableTypes(QLayout *layout)
{
QGroupBox *groupBox = new QGroupBox(tr("Renderable type"));
QVBoxLayout *vbox = new QVBoxLayout;
for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
vbox->addWidget(new QRadioButton(QString::fromLatin1(renderables[i].str)));
static_cast<QRadioButton *>(vbox->itemAt(0)->widget())->setChecked(true);
groupBox->setLayout(vbox);
layout->addWidget(groupBox);
m_renderables = vbox;
}
void Widget::addRenderWindow()
{
m_renderWindowLayout->addWidget(m_renderWindowContainer);
}
static QWidget *widgetWithLayout(QLayout *layout)
{
QWidget *w = new QWidget;
w->setLayout(layout);
return w;
}
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
QVBoxLayout *layout = new QVBoxLayout;
QSplitter *vsplit = new QSplitter(Qt::Vertical);
layout->addWidget(vsplit);
QSplitter *hsplit = new QSplitter;
QVBoxLayout *settingsLayout = new QVBoxLayout;
addVersions(settingsLayout);
addProfiles(settingsLayout);
addOptions(settingsLayout);
addRenderableTypes(settingsLayout);
hsplit->addWidget(widgetWithLayout(settingsLayout));
QVBoxLayout *outputLayout = new QVBoxLayout;
m_output = new QTextEdit;
m_output->setReadOnly(true);
outputLayout->addWidget(m_output);
m_extensions = new QTextEdit;
m_extensions->setReadOnly(true);
outputLayout->addWidget(m_extensions);
hsplit->addWidget(widgetWithLayout(outputLayout));
hsplit->setStretchFactor(0, 4);
hsplit->setStretchFactor(1, 6);
vsplit->addWidget(hsplit);
m_renderWindowLayout = new QVBoxLayout;
vsplit->addWidget(widgetWithLayout(m_renderWindowLayout));
vsplit->setStretchFactor(1, 5);
m_renderWindowContainer = new QWidget;
addRenderWindow();
QString description;
QTextStream str(&description);
str << "Qt " << QT_VERSION_STR << ' ' << QGuiApplication::platformName();
const char *openGlVariables[] =
{"QT_ANGLE_PLATFORM", "QT_OPENGL", "QT_OPENGL_BUGLIST", "QT_OPENGL_DLL"};
const size_t variableCount = sizeof(openGlVariables) / sizeof(openGlVariables[0]);
for (size_t v = 0; v < variableCount; ++v) {
if (qEnvironmentVariableIsSet(openGlVariables[v]))
str << ' ' << openGlVariables[v] << '=' << qgetenv(openGlVariables[v]);
}
if (QCoreApplication::testAttribute(Qt::AA_UseOpenGLES))
str << " Qt::AA_UseOpenGLES";
if (QCoreApplication::testAttribute(Qt::AA_UseSoftwareOpenGL))
str << " Qt::AA_UseSoftwareOpenGL";
if (QCoreApplication::testAttribute(Qt::AA_UseDesktopOpenGL))
str << " Qt::AA_UseDesktopOpenGL";
layout->addWidget(new QLabel(description));
setLayout(layout);
}
void Widget::start()
{
QSurfaceFormat fmt;
int idx = m_version->currentIndex();
if (idx < 0)
return;
fmt.setVersion(versions[idx].major, versions[idx].minor);
for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
if (static_cast<QRadioButton *>(m_profiles->itemAt(int(i))->widget())->isChecked()) {
fmt.setProfile(profiles[i].profile);
break;
}
bool forceGLSL110 = false;
for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
if (static_cast<QCheckBox *>(m_options->itemAt(int(i))->widget())->isChecked()) {
if (options[i].option)
fmt.setOption(options[i].option);
else if (i == 3)
forceGLSL110 = true;
}
for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
if (static_cast<QRadioButton *>(m_renderables->itemAt(int(i))->widget())->isChecked()) {
fmt.setRenderableType(renderables[i].renderable);
break;
}
// The example rendering will need a depth buffer.
fmt.setDepthBufferSize(16);
m_output->clear();
m_extensions->clear();
qDebug() << "Requesting surface format" << fmt;
m_renderWindowLayout->removeWidget(m_renderWindowContainer);
delete m_renderWindowContainer;
RenderWindow *renderWindow = new RenderWindow(fmt);
if (!renderWindow->context()) {
m_output->append(tr("Failed to create context"));
delete renderWindow;
m_renderWindowContainer = new QWidget;
addRenderWindow();
return;
}
m_surface = renderWindow;
renderWindow->setForceGLSL110(forceGLSL110);
connect(renderWindow, &RenderWindow::ready, this, &Widget::renderWindowReady);
connect(renderWindow, &RenderWindow::error, this, &Widget::renderWindowError);
m_renderWindowContainer = QWidget::createWindowContainer(renderWindow);
addRenderWindow();
}
void Widget::printFormat(const QSurfaceFormat &format)
{
m_output->append(tr("OpenGL version: %1.%2").arg(format.majorVersion()).arg(format.minorVersion()));
for (size_t i = 0; i < sizeof(profiles) / sizeof(Profile); ++i)
if (profiles[i].profile == format.profile()) {
m_output->append(tr("Profile: %1").arg(QString::fromLatin1(profiles[i].str)));
break;
}
QString opts;
for (size_t i = 0; i < sizeof(options) / sizeof(Option); ++i)
if (format.testOption(options[i].option))
opts += QString::fromLatin1(options[i].str) + QLatin1Char(' ');
m_output->append(tr("Options: %1").arg(opts));
for (size_t i = 0; i < sizeof(renderables) / sizeof(Renderable); ++i)
if (renderables[i].renderable == format.renderableType()) {
m_output->append(tr("Renderable type: %1").arg(QString::fromLatin1(renderables[i].str)));
break;
}
m_output->append(tr("Depth buffer size: %1").arg(QString::number(format.depthBufferSize())));
m_output->append(tr("Stencil buffer size: %1").arg(QString::number(format.stencilBufferSize())));
m_output->append(tr("Samples: %1").arg(QString::number(format.samples())));
m_output->append(tr("Red buffer size: %1").arg(QString::number(format.redBufferSize())));
m_output->append(tr("Green buffer size: %1").arg(QString::number(format.greenBufferSize())));
m_output->append(tr("Blue buffer size: %1").arg(QString::number(format.blueBufferSize())));
m_output->append(tr("Alpha buffer size: %1").arg(QString::number(format.alphaBufferSize())));
m_output->append(tr("Swap interval: %1").arg(QString::number(format.swapInterval())));
}
void Widget::renderWindowReady()
{
QOpenGLContext *context = QOpenGLContext::currentContext();
Q_ASSERT(context);
QString vendor, renderer, version, glslVersion;
const GLubyte *p;
QOpenGLFunctions *f = context->functions();
if ((p = f->glGetString(GL_VENDOR)))
vendor = QString::fromLatin1(reinterpret_cast<const char *>(p));
if ((p = f->glGetString(GL_RENDERER)))
renderer = QString::fromLatin1(reinterpret_cast<const char *>(p));
if ((p = f->glGetString(GL_VERSION)))
version = QString::fromLatin1(reinterpret_cast<const char *>(p));
if ((p = f->glGetString(GL_SHADING_LANGUAGE_VERSION)))
glslVersion = QString::fromLatin1(reinterpret_cast<const char *>(p));
m_output->append(tr("*** Context information ***"));
m_output->append(tr("Vendor: %1").arg(vendor));
m_output->append(tr("Renderer: %1").arg(renderer));
m_output->append(tr("OpenGL version: %1").arg(version));
m_output->append(tr("GLSL version: %1").arg(glslVersion));
m_output->append(tr("\n*** QSurfaceFormat from context ***"));
printFormat(context->format());
m_output->append(tr("\n*** QSurfaceFormat from window surface ***"));
printFormat(m_surface->format());
m_output->append(tr("\n*** Qt build information ***"));
const char *gltype[] = { "Desktop", "GLES 2", "GLES 1" };
m_output->append(tr("Qt OpenGL configuration: %1")
.arg(QString::fromLatin1(gltype[QOpenGLContext::openGLModuleType()])));
#if defined(Q_OS_WIN)
using namespace QNativeInterface;
m_output->append(tr("Qt OpenGL library handle: %1")
.arg(QString::number(qintptr(QWGLContext::openGLModuleHandle()), 16)));
#endif
QList<QByteArray> extensionList = context->extensions().values();
std::sort(extensionList.begin(), extensionList.end());
m_extensions->append(tr("Found %1 extensions:").arg(extensionList.count()));
for (const QByteArray &ext : std::as_const(extensionList))
m_extensions->append(QString::fromLatin1(ext));
m_output->moveCursor(QTextCursor::Start);
m_extensions->moveCursor(QTextCursor::Start);
}
void Widget::renderWindowError(const QString &msg)
{
m_output->append(tr("An error has occurred:\n%1").arg(msg));
}

View File

@ -0,0 +1,46 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QTextEdit)
QT_FORWARD_DECLARE_CLASS(QVBoxLayout)
QT_FORWARD_DECLARE_CLASS(QSurfaceFormat)
QT_FORWARD_DECLARE_CLASS(QSurface)
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
private slots:
void start();
void renderWindowReady();
void renderWindowError(const QString &msg);
private:
void addVersions(QLayout *layout);
void addProfiles(QLayout *layout);
void addOptions(QLayout *layout);
void addRenderableTypes(QLayout *layout);
void addRenderWindow();
void printFormat(const QSurfaceFormat &format);
QComboBox *m_version;
QLayout *m_profiles;
QLayout *m_options;
QLayout *m_renderables;
QTextEdit *m_output;
QTextEdit *m_extensions;
QVBoxLayout *m_renderWindowLayout;
QWidget *m_renderWindowContainer;
QSurface *m_surface;
};
#endif // WIDGET_H