现在的位置: 首页 > 综合 > 正文

C++ Gui Programming with Qt4第20章第二个示例代码VowelCube

2013年09月28日 ⁄ 综合 ⁄ 共 4869字 ⁄ 字号 评论关闭
#ifndef MYPANEL_H
#define MYPANEL_H

#include "QtGui"
#include <QGLWidget>
#include "ui_mypanel.h"

class MyPanel : public QGLWidget
{
	Q_OBJECT

public:
	MyPanel(QWidget *parent = 0);
	~MyPanel();
protected:
	virtual void mouseMoveEvent(QMouseEvent *event);
	virtual void mousePressEvent(QMouseEvent *event);
	virtual void wheelEvent(QWheelEvent *event);
	virtual void paintEvent(QPaintEvent* event);
private:
	Ui::MyPanel ui;

	void createGradient();
	void createGLObject();
	void drawBackground(QPainter * painter);
	void drawCube();
	void drawLegend(QPainter* painter);

	GLuint glObject;
	QRadialGradient gradient;
	GLfloat xrot;
	GLfloat yrot;
	GLfloat zrot;
	GLfloat scaling;
	QPoint lastPos;
};

#endif // MYPANEL_H

#include <cmath>
#include "mypanel.h"
#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif
MyPanel::MyPanel(QWidget *parent)
: QGLWidget(parent)
{
	//setFormat(QGLFormat(QGL::SampleBuffers));
	xrot = -38.0;
	yrot = -58.0;
	zrot = 0.0;
	scaling = 1.0;
	setAutoBufferSwap(false);
	setAutoFillBackground(false);
	createGradient();
	createGLObject();
}
MyPanel::~MyPanel()
{
	makeCurrent();
	glDeleteLists(glObject, 1);
}
void MyPanel::paintEvent(QPaintEvent *e)
{
	QPainter painter(this);    
	//painter.begin(this);
	drawBackground(&painter);
	painter.end();
	//painter.beginNativePainting();
	drawCube();
	//painter.endNativePainting();
	painter.begin(this);
	drawLegend(&painter);
	painter.end();
	swapBuffers();
}
void MyPanel::mousePressEvent(QMouseEvent *e)
{
	lastPos = e->pos();
}
void MyPanel::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 MyPanel::wheelEvent(QWheelEvent *e)
{
	double numDegrees = -e->delta() / 8.0;
	double numSteps = numDegrees / 15.0;
	scaling *= std::pow(1.125, numSteps);
	update();
}
void MyPanel::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 MyPanel::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 MyPanel::drawBackground(QPainter *painter)
{
	painter->setPen(Qt::NoPen);
	painter->setBrush(gradient);
	painter->drawRect(rect());
}
void MyPanel::drawCube()
{
	//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	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 MyPanel::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);
}

上面是C++ Gui Programming with Qt4第20章第二个示例代码,注意构造函数中的setFormat函数会导致程序崩溃,可能是书中用的Qt版本比较旧,我现在用的是Qt4.7.0,构造函数还需要添加两个函数



setAutoBufferSwap(
false
);
    
setAutoFillBackground(
false
);在调用drawCube之前需要禁用painter,否则会无法绘制立方体。



【上篇】
【下篇】

抱歉!评论已关闭.