我需要在现有的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构造函数。我得到了一些有趣的行为。
新的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 )
答案 0 :(得分:0)
在我调用setFormat()之后,在我的GLWidget构造函数中调用makeCurrent()就可以了。使用Qt 5.2,设置格式实际上并没有给我我请求的格式(即,请求OpenGL 2.1实际设置OpenGL 3.0,而请求3.0实际设置3.3)。虽然我的系统支持OpenGL 3.3,但除非使用的版本是3.0或更低,否则我不会得到三角形。但设置版本有效。
对带有QGLFormat对象的备用构造函数的调用也可以工作(最高版本3.0 ......再次请求3.0给我3.3,请求2.1给我3.0)。
使用Qt 4.8,相同的代码可以工作,并且可以请求最高版本3.3,而我要求的版本是我得到的版本。
一个工作示例:
testGL.cpp:
#include <QApplication>
#include <QDialog>
#include <QGLFormat>
#include <QVBoxLayout>
#include <QDebug>
#include "GLWidget.h"
class GLDialog : public QDialog
{
public:
GLDialog()
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(new GLWidget(this));//format,this));
}
};
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 <QGLFormat>
#include <QGLFunctions>
#include <QGLShader>
#include <QGLShaderProgram>
#include <QVector>
#include <QVector3D>
class GLWidget : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
GLWidget(QWidget * = 0, const QGLWidget * = 0, Qt::WindowFlags = 0);
protected:
virtual void initializeGL();
virtual void paintGL();
virtual void resizeGL(int, int);
private:
QVector<QVector3D> _triangle;
QColor _backgroundColour;
};
#endif
GLWidget.cpp:
#include <QtOpenGL>
#include <QGLContext>
#include <QGLFormat>
#include <QDebug>
#include <string>
#include <cstring>
#include "GLWidget.h"
GLWidget::GLWidget(QWidget *parent, const QGLWidget *shareWidget, Qt::WindowFlags f)
: QGLWidget(parent, shareWidget, f)
{
QGLFormat newFormat(format());
newFormat.setVersion(2,1);
setFormat(newFormat);
makeCurrent();
resizeGL(width(), height());
}
void GLWidget::initializeGL()
{
_backgroundColour = Qt::black;
_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