==================================[GLWidget.h]==================================
#ifndef GLWIDGET_H
#define GLWIDGET_H
#include <QtOpenGL/QGLWidget>
class GLWidget : public QGLWidget {
Q_OBJECT
public:
GLWidget(QWidget *parent = 0);
~GLWidget();
protected:
virtual void initializeGL();
virtual void resizeGL(int w, int h);
virtual void paintGL();
virtual void hideEvent(QHideEvent *event);
virtual void showEvent(QShowEvent *event);
virtual void timerEvent(QTimerEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
virtual void wheelEvent(QWheelEvent *event);
private:
int timerId;
QPoint lastPos;
GLfloat rotateX;
GLfloat rotateY;
GLfloat rotateZ;
GLfloat zoom;
void drawCube(GLfloat factorX = 1, GLfloat factorY = 1,
GLfloat factorZ = 1, GLfloat w = 1);
void drawCone(GLfloat radius = 1.0f, GLfloat height = 1,
GLuint steps = 18);
};
#endif // GLWIDGET_H
==================================[GLWidget.cpp]==================================
#include "GLWidget.h"
#include <qDebug>
#include <QTimerEvent>
#include <QMouseEvent>
#include <cmath>
GLWidget::GLWidget(QWidget *parent)
: QGLWidget(parent) {
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
rotateX = 0.0f;
rotateY = 0.0f;
rotateZ = 0.0f;
zoom = 1.0f;
}
GLWidget::~GLWidget() {
}
void GLWidget::hideEvent(QHideEvent *event) {
this->killTimer(this->timerId);
}
void GLWidget::showEvent(QShowEvent *event) {
this->timerId = this->startTimer(500);
}
void GLWidget::timerEvent(QTimerEvent *event) {
if (event->timerId() == this->timerId) {
} else {
QGLWidget::timerEvent(event);
}
}
void GLWidget::mousePressEvent(QMouseEvent *event) {
if (Qt::LeftButton == event->button()) {
lastPos = event->pos();
} else if (Qt::RightButton == event->button()) {
lastPos = event->pos();
}
}
void GLWidget::mouseMoveEvent(QMouseEvent *event) {
if (Qt::LeftButton & event->buttons()) {
GLfloat dx = event->pos().x() - lastPos.x();
GLfloat dy = event->pos().y() - lastPos.y();
rotateX += dy;
rotateY += dx;
updateGL();
//qDebug() << QString("RotateX:%1, RotateY:%2").arg(rotateX).arg(rotateY);
} else if (Qt::RightButton & event->buttons()) {
GLfloat dz = event->pos().y() - lastPos.y();
dz *= 0.01f;
zoom += dz;
updateGL();
}
lastPos = event->pos();
}
void GLWidget::mouseReleaseEvent(QMouseEvent *event) {
}
void GLWidget::wheelEvent(QWheelEvent *event) {
GLfloat degrees = event->delta();
zoom -= degrees * 0.0002f;
// 注意, 如果zoom为负值, eye就会被放置到z轴的负方向, 而从物体的背面看了.
if (zoom < 1.0f) {
zoom = 1.0f;
}
updateGL();
}
///////////////////////////////////////////////////////////////////////////////
// Opengl Code
///////////////////////////////////////////////////////////////////////////////
void GLWidget::initializeGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glFrontFace(GL_CCW);
//glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glShadeModel(GL_SMOOTH);
// Point size
// glPointSize(GLfloat size);
GLfloat sizes[2];
GLfloat step;
glGetFloatv(GL_LINE_WIDTH_RANGE, sizes);
glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &step);
}
void GLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(75, (GLdouble)w / h, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void GLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
//glTranslatef(0.0f, 0.0f, zoom);
gluLookAt(0.0f, 0.0f, zoom, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glRotatef(rotateX, 1, 0, 0);
glRotatef(rotateY, 0, 1, 0);
glRotatef(rotateZ, 0, 0, 1);
// Real draw code.
//glColor3f(1.0f, 0.0f, 0.0f);
//drawCube(1, 1, 1, 1);
glPolygonMode(GL_BACK, GL_LINE);
drawCone(1.0f, 1.50, 48);
}
void GLWidget::drawCube(GLfloat factorX, GLfloat factorY,
GLfloat factorZ, GLfloat w) {
GLfloat x = factorX * 0.5f;
GLfloat y = factorY * 0.5f;
GLfloat z = factorZ * 0.5f;
// x / w, y / w, z / w
// 前左下, 前右下, 前右上, 前左上: p0, p1, p2, p3
// 后左下, 后右下, 后右上, 后左上: p4, p5, p6, p7
GLfloat p0[4] = {-x, -y, z, w};
GLfloat p1[4] = {x, -y, z, w};
GLfloat p2[4] = {x, y, z, w};
GLfloat p3[4] = {-x, y, z, w};
GLfloat p4[4] = {-x, -y, -z, w};
GLfloat p5[4] = {x, -y, -z, w};
GLfloat p6[4] = {x, y, -z, w};
GLfloat p7[4] = {-x, y, -z, w};
// 开始绘制Cube的六个面: 逆时针
glBegin(GL_QUADS);
// 前面: p0, p1, p2, p3
glVertex4fv(p0);
glVertex4fv(p1);
glVertex4fv(p2);
glVertex4fv(p3);
// 右面: p1, p5, p6, p2
glVertex4fv(p1);
glVertex4fv(p5);
glVertex4fv(p6);
glVertex4fv(p2);
// 后面: p5, p4, p7, p6
glVertex4fv(p5);
glVertex4fv(p4);
glVertex4fv(p7);
glVertex4fv(p6);
// 左右: p4, p0, p3, p7
glVertex4fv(p4);
glVertex4fv(p0);
glVertex4fv(p3);
glVertex4fv(p7);
// 上面: p2, p6, p7, p3
glVertex4fv(p2);
glVertex4fv(p6);
glVertex4fv(p7);
glVertex4fv(p3);
// 下面: p0, p4, p5, p1
glVertex4fv(p0);
glVertex4fv(p4);
glVertex4fv(p5);
glVertex4fv(p1);
glEnd();
}
void GLWidget::drawCone(GLfloat radius, GLfloat height,
GLuint steps) {
const GLfloat GL_PI = 3.1415f;
GLfloat angles = 2 * GL_PI / steps;
GLfloat vertices[steps][3];
for (int i = 0; i < steps; ++i) {
vertices[i][0] = radius * cos(i * angles);
vertices[i][1] = radius * sin(i * angles);
vertices[i][2] = 0;
}
// top surface
glBegin(GL_TRIANGLE_FAN);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, height);
for (int i = 0; i < steps; ++i) {
glVertex3fv(vertices[i]);
if ((i & 1) == 0) {
glColor3f(1.0f, 0.0f, 0.0f);
} else {
glColor3f(0.0f, 0.0f, 1.0f);
}
}
glVertex3fv(vertices[0]);
glEnd();
// bottom surface
glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f, 0.0f, 0);
for (int i = steps - 1; i >= 0; --i) {
glVertex3fv(vertices[i]);
if ((i & 1) == 0) {
glColor3f(0.0f, 1.0f, 0.0f);
} else {
glColor3f(1.0f, 0.0f, 1.0f);
}
}
glVertex3fv(vertices[steps - 1]);
glEnd();
}