Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

如何在Qt中使用OpenGL

From 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 03:14.
436 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×