关于C++ Gui Programming with Qt4第20章Vowel Cube的bug
运行时出现如下错误:
Starting E:\Qt\OpenGL\QtOpenGL\VowelCube-build-desktop\debug\VowelCube.exe...
ASSERT: "d" in file ..\..\include/QtCore/../../src/corelib/tools/qscopedpointer.h, line 112
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
QWidget::repaint: Recursive repaint detected
ASSERT: "d" in file ..\..\include/QtCore/../../src/corelib/tools/qscopedpointer.h, line 112
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
E:\Qt\OpenGL\QtOpenGL\VowelCube-build-desktop\debug\VowelCube.exe exited with code 3
不知道到底出了什么问题,恳请各位高人指点迷津,在下感激不尽!
#ifndef VOWELCUBE_H
#define VOWELCUBE_H
#include <QtCore>
#include <QtGui>
#include <QtOpenGL>
class VowelCube : public QGLWidget
{
Q_OBJECT
public:
VowelCube(QWidget *parent = 0);
~VowelCube();
protected:
void paintEvent(QPaintEvent *e);
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void wheelEvent(QWheelEvent *e);
private:
void createGradient();
void createGLObject();
void drawBackground(QPainter *painter);
void drawCube();
void drawLegend(QPainter *painter);
GLuint glObject;
QRadialGradient gradient;
GLfloat xrot, yrot, zrot;
GLfloat scaling;
QPoint lastPos;
};
#endif // VOWELCUBE_H
#include <cmath>
#include "vowelcube.h"
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif
VowelCube::VowelCube(QWidget *parent)
: QGLWidget(parent)
{
setFormat(QGLFormat(QGL::SampleBuffers));
xrot = -38.0;
yrot = -58.0;
zrot = 0.0;
scaling = 1.0;
createGradient();
createGLObject();
}
VowelCube::~VowelCube()
{
makeCurrent();
glDeleteLists(glObject, 1);
}
void VowelCube::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
drawBackground(&painter);
drawCube();
drawLegend(&painter);
}
void VowelCube::mousePressEvent(QMouseEvent *e)
{
lastPos = e->pos();
}
void VowelCube::mouseMoveEvent(QMouseEvent *e)
{
GLfloat dx = GLfloat(e->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(e->y() - lastPos.y()) / height();
if (e->buttons() & Qt::LeftButton) {
xrot += 180 * dy;
yrot += 180 * dx;
update();
} else if (e->buttons() & Qt::RightButton) {
xrot += 180 * dy;
zrot += 180 * dx;
update();
}
lastPos = e->pos();
}
void VowelCube::wheelEvent(QWheelEvent *e)
{
double numDegrees = -e->delta() / 8.0;
double numSteps = numDegrees / 15.0;
scaling *= std::pow(1.125, numSteps);
update();
}
void VowelCube::createGradient()
{
gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
gradient.setCenter(0.45, 0.50);
gradient.setFocalPoint(0.40, 0.45);
gradient.setColorAt(0.0, QColor(105, 146, 182));
gradient.setColorAt(0.4, QColor(81, 113, 150));
gradient.setColorAt(0.8, QColor(16, 56, 121));
}
void VowelCube::createGLObject()
{
static const GLfloat vertex_list[8][3] = {{-1.0, -1.0, 1.0},
{1.0, -1.0, 1.0},
{1.0, 1.0, 1.0},
{-1.0, 1.0, 1.0},
{-1.0, -1.0, -1.0},
{1.0, -1.0, -1.0},
{1.0, 1.0, -1.0},
{-1.0, 1.0, -1.0}};
static const int vertex_index_list1[6] = {6, 7, 5, 4, 1, 0};
static const int vertex_index_list2[10] = {2, 6, 5, 1, 2, 3, 7, 4, 0, 3};
makeCurrent();
glShadeModel(GL_FLAT);
glObject = glGenLists(1);
glNewList(glObject, GL_COMPILE); {
qglColor(QColor(255, 239, 191));
glLineWidth(1.0);
glBegin(GL_LINES); {
for (int i = 0; i < 6; i++)
glVertex3fv(vertex_list[vertex_index_list1[i]]);
} glEnd();
glBegin(GL_LINE_LOOP); {
for (int i = 0; i < 10; i++)
glVertex3fv(vertex_list[vertex_index_list2[i]]);
} glEnd();
} glEndList();
}
void VowelCube::drawBackground(QPainter *painter)
{
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
painter->drawRect(rect());
}
void VowelCube::drawCube()
{
glPushAttrib(GL_ALL_ATTRIB_BITS);
glMatrixMode(GL_PROJECTION);
glPushMatrix(); {
glLoadIdentity();
GLfloat x = 3.0 * GLfloat(width()) / height();
glOrtho(-x, x, -3.0, 3.0, 4.0, 15.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); {
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glScalef(scaling, scaling, scaling);
glRotatef(xrot, 1.0, 0.0, 0.0);
glRotatef(yrot, 0.0, 1.0, 0.0);
glRotatef(zrot, 0.0, 0.0, 1.0);
glEnable(GL_MULTISAMPLE);
glCallList(glObject);
setFont(QFont("Times", 24));
qglColor(QColor(255, 223, 127));
renderText(1.0, 1.0, 1.0, QChar('a'));
renderText(-1.0, 1.0, 1.0, QChar('e'));
renderText(1.0, 1.0, -1.0, QChar('o'));
renderText(-1.0, 1.0, -1.0, QChar(0x00F6));
renderText(1.0, -1.0, 1.0, QChar(0x0131));
renderText(-1.0, -1.0, 1.0, QChar('i'));
renderText(1.0, -1.0, -1.0, QChar('u'));
renderText(-1.0, -1.0, -1.0, QChar(0x00FC));
glMatrixMode(GL_MODELVIEW);
} glPopMatrix();
glMatrixMode(GL_PROJECTION);
} glPopMatrix();
glPopAttrib();
}
void VowelCube::drawLegend(QPainter *painter)
{
const int Margin = 11;
const int Padding = 6;
QTextDocument textDocument;
textDocument.setDefaultStyleSheet("* { color: #FFEFEF }");
textDocument.setHtml("<h4 align="center">Vowel Categories</h4>"
"<p align="center"><table width="100%">"
"<tr><td>Open:<td>a<td>e<td>o<td>ö"
"<tr><td>Close:<td>ı<td>i<td>u<td>ü"
"<tr><td>Front:<td>e<td>i<td>ö<td>ü"
"<tr><td>Back:<td>a<td>ı<td>o<td>u"
"<tr><td>Round:<td>o<td>ö<td>u<td>ü"
"<tr><td>Unround:<td>a<td>e<td>ı<td>i"
"</table>");
textDocument.setTextWidth(textDocument.size().width());
QRect rect(QPoint(0, 0), textDocument.size().toSize() + QSize(2 * Padding, 2 * Padding));
painter->translate(width() - rect.width() - Margin, height() - rect.height() - Margin);
painter->setPen(QColor(255, 239, 239));
painter->setBrush(QColor(255, 0, 0, 31));
painter->drawRect(rect);
painter->translate(Padding, Padding);
textDocument.drawContents(painter);
}
#include <QtGui/QApplication>
#include "vowelcube.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if (!QGLFormat::hasOpenGL()) {
QMessageBox::warning(0, "Fatal Error!", "This system has no OpenGL support!");
return -1;
}
VowelCube w;
w.setWindowTitle(QObject::tr("Vowel Cube"));
w.setMinimumSize(200, 200);
w.resize(500, 500);
w.show();
return a.exec();
}