【发布时间】:2014-05-03 01:00:12
【问题描述】:
我需要向现有的 Qt 应用程序添加一些 3D 图形。我使用的是 Qt 5.2,但我使用的是旧的 QGL* 类,至少目前是这样。首先,我只想画一个三角形。
我的工作正常,但后来我尝试通过调用 QGLWidget::setFormat 显式设置 OpenGL 版本,突然我的三角形不再绘制。我注释掉了我实际设置版本的行,它没有任何区别:使用 QGLWidget::format 返回的值调用 QGLWidget::setFormat 突然使绘图不发生。发生了什么?
testGL.cpp:
#include <QApplication>
#include <QDialog>
#include <QVBoxLayout>
#include "GLWidget.h"
class GLDialog : public QDialog
{
public:
GLDialog()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(new GLWidget);
}
};
int main(int argc, char **argv)
{
QApplication app(argc, argv);
GLDialog dlg;
dlg.resize(200,200);
dlg.show();
return app.exec();
}
GLWidget.h:
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QColor>
#include <QGLWidget>
#include <QVector>
#include <QVector3D>
class GLWidget : public QGLWidget
{
Q_OBJECT
public:
GLWidget(QWidget * = 0, const QGLWidget * = 0, Qt::WindowFlags = 0);
protected:
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int, int);
//virtual void mousePressEvent(QMouseEvent *);
//virtual void mouseMoveEvent(QMouseEvent *);
private:
QVector<QVector3D> _triangle;
QColor _backgroundColour;
QColor _triangleColour;
};
#endif
GLWidget.cpp:
#include <QtOpenGL>
#include <QGLContext>
#include <QGLFormat>
#include <QGLShader>
#include <QGLShaderProgram>
#include <QDebug>
#include "GLWidget.h"
GLWidget::GLWidget(QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f)
: QGLWidget(parent, shareWidget, f)
{
QGLFormat newFormat(format());
//newFormat.setVersion(3,3);
/* Comment out the following line and a triangle appears */
setFormat(newFormat);
}
void GLWidget::initializeGL()
{
_backgroundColour = Qt::black;
_triangleColour = Qt::white;
_triangle.push_back(QVector3D(-0.75, 0.75, 0));
_triangle.push_back(QVector3D(-0.75, -0.75, 0));
_triangle.push_back(QVector3D(0.75, -0.75, 0));
}
void GLWidget::paintGL()
{
qglClearColor(_backgroundColour);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, _triangle.constData());
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void GLWidget::resizeGL(int width, int height)
{
int side = qMin(width, height);
int hoffset = (int)((width - side) / 2.0 + 0.5);
int voffset = (int)((height - side) / 2.0 + 0.5);
glViewport(hoffset, voffset, side, side);
}
testGL.pro:
######################################################################
# Automatically generated by qmake (3.0) Fri Apr 18 16:09:15 2014
######################################################################
TEMPLATE = app
TARGET = testGL
INCLUDEPATH += .
CONFIG += qt warn_on debug
QT += opengl
# Input
HEADERS += GLWidget.h
SOURCES += GLWidget.cpp testGL.cpp
我是 OpenGL 的初学者,所以请原谅我的代码中的愚蠢。请注意,我没有明确设置着色器。那将是我的下一步。
更新:
我关注this advice 并使用了带有 QGLFormat 对象的备用 QGLWidget 构造函数。我得到了一些有趣的行为。
- 如果我只创建一个 QGLFormat,但不设置它的版本,我会得到一个三角形。请求的版本是 2.0,但检查我的 GLWidget 构造函数中的版本发现它是 3.0。
- 如果我显式调用 QGLFormat::setVersion(3,0),我会得到 3.3 版,但不会得到三角形。
- 如果我显式调用 QGLFormat::setVersion(2,0),我会得到一个三角形,并且设置的版本是 3.0。
新的 GLDialog 代码:
class GLDialog : public QDialog
{
public:
GLDialog()
{
QVBoxLayout *layout = new QVBoxLayout(this);
QGLFormat format;
/* Comment this line out or change to 2,0 to get a triangle */
format.setVersion(3,0);
layout->addWidget(new GLWidget(format,this));
}
};
在 GLWidget 构造函数中输出此格式字符串:
QGLFormat(options QFlags(0x1|0x2|0x4|0x8|0x20|0x80|0x400) , plane 0 , depthBufferSize 24 , accumBufferSize -1 , stencilBufferSize 8 , redBufferSize 8 , greenBufferSize 8 , blueBufferSize 8 , alphaBufferSize 8 , samples -1 , swapInterval -1 , majorVersion 3 , minorVersion 3 , profile 1 )
如果我注释掉指示的行:
QGLFormat(options QFlags(0x1|0x2|0x4|0x8|0x20|0x80|0x400) , plane 0 , depthBufferSize 24 , accumBufferSize -1 , stencilBufferSize 8 , redBufferSize 8 , greenBufferSize 8 , blueBufferSize 8 , alphaBufferSize 8 , samples -1 , swapInterval -1 , majorVersion 3 , minorVersion 0 , profile 0 )
如果我将请求的版本更改为 2.0:
QGLFormat(options QFlags(0x1|0x2|0x4|0x8|0x20|0x80|0x400) , plane 0 , depthBufferSize 24 , accumBufferSize -1 , stencilBufferSize 8 , redBufferSize 8 , greenBufferSize 8 , blueBufferSize 8 , alphaBufferSize 8 , samples -1 , swapInterval -1 , majorVersion 3 , minorVersion 0 , profile 0 )
【问题讨论】:
-
您使用的 Qt 版本是什么,什么平台?请注意,
setFormat已过时。不要使用它。直接处理上下文。 -
Arch Linux 上的 Qt 5.2。 QGLContext 似乎不允许我设置 OpenGL 版本...除非您的意思是调用 QGLWidget::context()->setFormat(...)。当我这样做时,背景甚至都没有被清除。