×
Namespaces

Variants
Actions

如何在Qt中使用OpenGL

From Nokia Developer Wiki
Jump to: navigation, search
Article Metadata

代码示例
源文件: Media:OpenGL.zip

文章
liuting 在 22 Feb 2012 创建
最后由 renlin 在 11 Jul 2012 编辑

Contents

介绍

OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口(Application programming interface)的规格,它用于生成二维、三维图像。这个接口由近三百五十个不同的函数调用组成,用来从简单的图元绘制复杂的三维景象。而另一种编程接口系统是仅用于Microsoft Windows上的Direct3D。OpenGL常用于CAD、虚拟实境、科学视觉化程式和电子游戏开发。QT通过OpenGL Module来使用OpenGL,接下来我们将展示如何通过QTOpenGL 来创建一个三维正方体

OpenGLQt.pro

为了使用OtOpenGL Module,我们必须设.pro文件

QT       += core gui\
opengl
TARGET = OpenGLQt
TEMPLATE = app
SOURCES += main.cpp\
openglqt.cpp
HEADERS += openglqt.h
FORMS += openglqt.ui

openglqt.h

#ifndef OPENGLQT_H
#define OPENGLQT_H
 
#include <QMainWindow>
#include <QtOpenGL>
namespace Ui {
class OpenGLQt;
}
 
class OpenGLQt : public QGLWidget
{
Q_OBJECT
 
public:
explicit OpenGLQt(QWidget *parent = 0);
~OpenGLQt();
 
private:
Ui::OpenGLQt *ui;
 
 
protected:
void initializeGL();
void resizeGL(int width, int height);
void paintGL();
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private:
void draw();
int faceAtPosition(const QPoint &pos);
GLfloat rotationX;
GLfloat rotationY;
GLfloat rotationZ;
QColor faceColors[4];
QPoint lastPos;
void Spin(int xAngle, int yAngle, int zAngle);
private slots:
void Rotate();
};

The OpenGLQt class inherits from QGLWidget. The initializeGL(), resizeGL(), and paintGL() functions are reimplemented from QGLWidget. OpenGLQT类继承于QGLWidget,我们需要重写 initializeGL(), resizeGL(), and paintGL()

openglqt.cpp

#include "ui_openglqt.h"
 
OpenGLQt::OpenGLQt(QWidget *parent) :
QGLWidget(parent),
ui(new Ui::OpenGLQt)
{
 
 
//QGLWidget::setFormat() to specify the OpenGL display context
setFormat(QGLFormat(QGL::DoubleBuffer | QGL::DepthBuffer));
rotationX = -21.0;
rotationY = -57.0;
rotationZ = 0.0;
 
// Note: Square faces are set with static color and are cannot be changed during runtime
// set the color of the faces of Tetrahedron
faceColors[0] = Qt::red;
faceColors[1] = Qt::green;
faceColors[2] = Qt::blue;
faceColors[3] = Qt::yellow;
 
initializeGL();
resizeGL(51,51);
paintGL();
 
 
//timer to spin the object
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(Rotate()));
timer->start(20);
 
 
}
 
OpenGLQt::~OpenGLQt()
{
delete ui;
}
 
 
void OpenGLQt::initializeGL()
{
qglClearColor(Qt::black);
glShadeModel(GL_FLAT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
 
void OpenGLQt::resizeGL(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLfloat x = GLfloat(width) / height;
glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
glMatrixMode(GL_MODELVIEW);
}
 
 
void OpenGLQt::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
draw();
}
 
void OpenGLQt::draw()
{
 
//change the value if don't want to spin automatically and want to check the mouse event
// glRotatef(rotationX/16.0f, 1.0, 0.0, 0.0); to glRotatef(rotationX, 1.0, 0.0, 0.0);
// glRotatef(rotationY/16.0f, 0.0, 1.0, 0.0); to glRotatef(rotationY, 0.0, 1.0, 0.0);
//glRotatef(rotationZ/16.0f, 0.0, 0.0, 1.0); to glRotatef(rotationZ, 0.0, 0.0, 1.0);
 
 
// Draw Tetrahedron
static const GLfloat P1[3] = { 0.0, -1.0, +2.0 };
static const GLfloat P2[3] = { +1.73205081, -1.0, -1.0 };
static const GLfloat P3[3] = { -1.73205081, -1.0, -1.0 };
static const GLfloat P4[3] = { 0.0, +2.0, 0.0 };
static const GLfloat * const coords[4][3] = {
{ P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glRotatef(rotationX/16.0f, 1.0, 0.0, 0.0);
glRotatef(rotationY/16.0f, 0.0, 1.0, 0.0);
glRotatef(rotationZ/16.0f, 0.0, 0.0, 1.0);
for (int i = 0; i < 4; ++i) {
glLoadName(i);
glBegin(GL_TRIANGLES);
qglColor(faceColors[i]);
for (int j = 0; j < 3; ++j) {
glVertex3f(coords[i][j][0], coords[i][j][1],
coords[i][j][2]);
}
glEnd();
}
}
 
void OpenGLQt::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
}
 
void OpenGLQt::mouseMoveEvent(QMouseEvent *event)
{
GLfloat dx = GLfloat(event->x() - lastPos.x()) / width();
GLfloat dy = GLfloat(event->y() - lastPos.y()) / height();
if (event->buttons() & Qt::LeftButton) {
rotationX += 180 * dy;
rotationY += 180 * dx;
updateGL();
}
else if (event->buttons() & Qt::RightButton)
{
rotationX += 180 * dy;
rotationZ += 180 * dx;
updateGL();
 
 
}
lastPos = event->pos();
}
 
void OpenGLQt::mouseDoubleClickEvent(QMouseEvent *event)
{
int face = faceAtPosition(event->pos());
if (face != -1) {
QColor color = QColorDialog::getColor(faceColors[face], this);
if (color.isValid()) {
faceColors[face] = color;
updateGL();
}
}
}
 
int OpenGLQt::faceAtPosition(const QPoint &pos)
{
const int MaxSize = 512;
GLuint buffer[MaxSize];
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
glSelectBuffer(MaxSize, buffer);
glRenderMode(GL_SELECT);
glInitNames();
glPushName(0);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPickMatrix(GLdouble(pos.x()), GLdouble(viewport[3] - pos.y()),
5.0, 5.0, viewport);
GLfloat x = GLfloat(width()) / height();
glFrustum(-x, x, -1.0, 1.0, 4.0, 15.0);
draw();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
if (!glRenderMode(GL_RENDER))
return -1;
return buffer[3];
}
 
void OpenGLQt::Rotate()
{
//QMessageBox::about(this,"Hello","world");
this->Spin(+2 * 16, +2 * 16, -1 * 16);
}
void OpenGLQt::Spin(int xAngle, int yAngle, int zAngle)
{
rotationX += xAngle;
rotationY += yAngle;
rotationZ += zAngle;
updateGL();
}
  1. 在构造函数中调用setFormat 设置OPENGL的显示方式.
  2. 函数initializeGL()在paintGL()之前调用,且只调用一次,在这里可以设置OpenGL的显示内容,定义显示列表或者其他初始化操作。其中qglClearColor()是QGLWidget的函数,其他函数都是OpenGL标准函数。如果全部遵循OpenGL库,可以调用RGBA格式的glClearColor()函数和颜色索引函数glClearIndex()。
  3. PaintGL() 函数将在任何需要重绘的时候调用,真正是在draw 函数中执行绘图操作
  4. 在draw函数中我们绘制四面体
  5. Spin() 函数用于旋转四面体到特定的角度

main.cpp

#include <QtGui/QApplication>
#include "openglqt.h"
#include <QApplication>
#include <iostream>
#include <QtOpenGL>
using namespace std;
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
if (!QGLFormat::hasOpenGL()) {
cerr << "This system has no OpenGL support" << endl;
return 1;
}
OpenGLQt openglqt;
openglqt.setWindowTitle(QObject::tr("OpenGL Qt"));
openglqt.resize(300, 300);
openglqt.show();
return app.exec();
}

运行效果

OpenGL1.JPG

代码下载

File:OpenGL.zip

相关链接

This page was last modified on 11 July 2012, at 06:14.
393 page views in the last 30 days.
×