Qt中OpenGL的初步使用
结果预览:
一.代码5个文件
- //glwidget.h
- #ifndef GLWIDGET_H
- #define GLWIDGET_H
- #include <QGLWidget>
- class GLWidget:public QGLWidget
- {
- Q_OBJECT
- public:
- explicit GLWidget(QWidget *parent = );
- int xRotation() const { return xRot; }
- int yRotation() const { return yRot; }
- int zRotation() const { return zRot; }
- signals:
- void xRotationChanged( int angle);
- void yRotationChanged( int angle);
- void zRotationChanged( int angle);
- public slots:
- void setXRotation(int angle);
- void setYRotation(int angle);
- void setZRotation(int angle);
- protected:
- void initializeGL();
- void paintGL();
- void resizeGL(int w, int h);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- private slots:
- void alwaysRotate();
- void drawTriangle();
- private:
- void normalizeAngle(int &angle);
- int xRot;
- int yRot;
- int zRot;
- QColor faceColors[];
- QPoint lastPos;
- QColor qtGreen, qtPurple;
- };
- #endif
- //glwidget.cpp
- #include <QtGui>
- #include <QtOpenGL>
- #include<math.h>
- #include"glwidget.h"
- #ifndef GL_MULTISAMPLE
- #define GL_MULTISAMPLE 0x809D
- #endif
- GLWidget::GLWidget(QWidget *parent):QGLWidget(parent)
- {
- xRot = ;
- yRot = ;
- zRot = ;
- faceColors[] = Qt::red;
- faceColors[] = Qt::green;
- faceColors[] = Qt::blue;
- faceColors[] = Qt::yellow;
- qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
- qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
- QTimer *timer = new QTimer(this);
- connect(timer , SIGNAL(timeout()), this,SLOT(alwaysRotate()));
- timer->start();
- }
- void GLWidget::initializeGL()
- {
- qglClearColor(qtPurple.dark());
- glShadeModel(GL_SMOOTH);
- glEnable(GL_DEPTH);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_MULTISAMPLE);
- glEnable(GL_CULL_FACE);
- }
- void GLWidget::paintGL()
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glPushMatrix();
- drawTriangle();
- glPopMatrix();
- }
- void GLWidget::resizeGL(int w, int h)
- {
- int side = qMin(w,h);
- glViewport((width() - side) / , (height() - side)/, side, side);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum( -1.2, 1.2, -1.2, 1.2,5.0, 60.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0, 0.0, -40.0);
- }
- void GLWidget::mousePressEvent(QMouseEvent *event)
- {
- lastPos = event->pos();
- }
- void GLWidget::mouseMoveEvent(QMouseEvent *event)
- {
- int dx = event->x() - lastPos.x();
- int dy = event->y() - lastPos.y();
- if (event->buttons()&Qt::LeftButton)
- {
- setYRotation(yRot + *dy);
- } else if (event->buttons()&Qt::RightButton)
- {
- setZRotation(zRot + *dx);
- }
- lastPos = event->pos();
- }
- void GLWidget::drawTriangle()
- {
- static const GLfloat P1[] = { 0.0, -1.0, +2.0 };
- static const GLfloat P2[] = { +1.73, -1.0, -1.0 };
- static const GLfloat P3[] = { -1.73, -1.0, -1.0 };
- static const GLfloat P4[] = { 0.0, +2.0, 0.0 };
- static const GLfloat * const coords[][] = {
- { P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
- };
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslated( 0.0 , 0.0, -10.0);
- glRotatef(xRot, 1.0, 0.0, 0.0);
- glRotatef(yRot, 0.0, 1.0, 0.0);
- glRotatef(zRot, 0.0, 0.0,1.0);
- for (int i = ; i != ; ++i)
- {
- glBegin(GL_TRIANGLES);
- qglColor(faceColors[i]);
- for (int j = ; j<;++j)
- glVertex3f(coords[i][j][], coords[i][j][], coords[i][j][]);
- glEnd();
- }
- }
- void GLWidget::normalizeAngle(int &angle)
- {
- while (angle<)
- angle +=*;
- while (angle>*)
- angle -=*;
- }
- void GLWidget::setXRotation(int angle)
- {
- normalizeAngle(angle);
- if ( angle!=xRot)
- {
- xRot = angle;
- emit xRotationChanged(angle);
- updateGL();
- }
- }
- void GLWidget::setYRotation(int angle)
- {
- normalizeAngle(angle);
- if ( angle != yRot ) {
- yRot = angle;
- emit yRotationChanged(angle);
- updateGL();
- }
- }
- void GLWidget::setZRotation(int angle)
- {
- normalizeAngle(angle);
- if ( angle != zRot ) {
- zRot = angle;
- emit zRotationChanged(angle);
- updateGL();
- }
- }
- void GLWidget::alwaysRotate()
- {
- zRot +=;
- if (zRot>*) zRot = ;
- emit zRotationChanged(zRot);
- updateGL();
- }
- //mainwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- class QAction;
- class QLabel;
- class QMenu;
- class QSlider;
- class QScrollArea;
- class GLWidget;
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- MainWindow(QWidget *parent = );
- ~MainWindow();
- private slots:
- void renderIntoPixmap();
- void grabFrameBuffer();
- void clearPixmap();
- void about();
- private:
- void createMenus();
- void createActions();
- QSlider *createSlider(const char *changedSignal, const char *setterSlot);
- void setPixmap(const QPixmap &pixmap);
- QSize getSize();
- QWidget *centralWidget;
- QScrollArea *glWidgetArea;
- QScrollArea *pixmapLabelArea;
- GLWidget *glWidget;
- QLabel *pixmapLabel;
- QSlider *xSlider;
- QSlider *ySlider;
- QSlider *zSlider;
- QMenu *fileMenu;
- QMenu *helpMenu;
- QAction *renderIntoPixmapAction;
- QAction *grabFrameBufferAction;
- QAction *clearPixmapAction;
- QAction *exitAction;
- QAction *aboutAction;
- QAction *aboutQtAction;
- };
- #endif // MAINWINDOW_H
- //mainwindow.cpp
- #include <QtOpenGL>
- #include <QAction>
- #include <QLabel>
- #include <QMenu>
- #include <QSlider>
- #include <QScrollArea>
- #include <QMenuBar>
- #include <QApplication>
- #include "mainwindow.h"
- #include "glwidget.h"
- #include <time.h>
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent)
- {
- centralWidget = new QWidget;
- setCentralWidget(centralWidget);
- glWidget = new GLWidget;
- pixmapLabel = new QLabel;
- glWidgetArea = new QScrollArea;
- glWidgetArea->setWidget(glWidget);
- //glWidgetArea->viewport()->setBackgroundRole(QPalette::Dark);
- glWidgetArea->setWidgetResizable(true);
- glWidgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- glWidgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- glWidgetArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
- glWidgetArea->setMinimumSize(, );
- pixmapLabelArea = new QScrollArea;
- pixmapLabelArea->setWidget(pixmapLabel);
- pixmapLabelArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
- pixmapLabelArea->setMinimumSize(, );
- //在构造一个QSlider时将QGLWidget的信号和槽传给这个函数的形参,这样就可以在QMainWindow中
- //控制OpenGL的动作了,而让GLWidget类只完成绘图工作。
- xSlider = createSlider(SIGNAL(xRotationChanged(int)),
- SLOT(setXRotation(int)));
- ySlider = createSlider(SIGNAL(yRotationChanged(int)),
- SLOT(setYRotation(int)));
- zSlider = createSlider(SIGNAL(zRotationChanged(int)),
- SLOT(setZRotation(int)));
- /*
- xSlider = new QSlider(Qt::Horizontal);
- ySlider = new QSlider(Qt::Horizontal);
- zSlider = new QSlider(Qt::Horizontal);
- */
- QGridLayout *centralLayout = new QGridLayout;
- centralLayout->addWidget(glWidgetArea, , );
- centralLayout->addWidget(pixmapLabelArea, , );
- centralLayout->addWidget(xSlider, , , , );
- centralLayout->addWidget(ySlider, , , , );
- centralLayout->addWidget(zSlider, , , , );
- centralWidget->setLayout(centralLayout);
- createActions();
- createMenus();
- xSlider->setValue( * );
- ySlider->setValue( * );
- zSlider->setValue( * );
- setWindowTitle(tr("Grabeer"));
- resize(, );
- }
- void MainWindow::setPixmap(const QPixmap &pixmap)
- {
- //截图到磁盘
- time_t curTime = time(NULL);
- QString path1 = "E:\\",path2=".jpg";
- QString path = QString::number(curTime, )+path2;
- pixmapLabel->setPixmap(pixmap);
- pixmap.save(path, , -);
- QSize size = pixmap.size();
- if (size - QSize(, ) == pixmapLabelArea->maximumViewportSize())
- size -= QSize(, );
- pixmapLabel->resize(size);
- }
- QSize MainWindow::getSize()
- {
- bool ok;
- QString text = QInputDialog::getText(this, tr("Grabber"),
- tr("Enter Pixmap Size:"),
- QLineEdit::Normal,
- tr("%1 x %2").arg(glWidget->width())
- .arg(glWidget->height()),
- &ok);
- if (!ok)
- return QSize();
- QRegExp regExp(tr("([0-9]+) *x *([0-9]+)"));
- if (regExp.exactMatch(text)) {
- int width = regExp.cap().toInt();
- int height = regExp.cap().toInt();
- if (width > && width < && height > && height < )
- return QSize(width, height);
- }
- return glWidget->size();
- }
- void MainWindow::renderIntoPixmap()
- {
- QSize size = getSize();
- if (size.isValid()) {
- QPixmap pixmap = glWidget->renderPixmap(size.width(), size.height());
- setPixmap(pixmap);
- }
- }
- void MainWindow::grabFrameBuffer()
- {
- //QGLWidget有一个返回其帧缓冲区的QImage图片的函数
- QImage image = glWidget->grabFrameBuffer();
- //QPixmap的fromImage函数把一个QImage转换成QPixmap
- setPixmap(QPixmap::fromImage(image));
- }
- void MainWindow::clearPixmap()
- {
- setPixmap(QPixmap()); //给它传一个空的对象
- }
- void MainWindow::about()
- {
- QMessageBox::about(this, tr("About Grabber"),
- tr("The <b>Grabber</b> example demonstrates two approaches for "
- "rendering OpenGL into a Qt pixmap."));
- }
- QSlider *MainWindow::createSlider(const char *changedSignal,
- const char *setterSlot)
- {
- QSlider *slider = new QSlider(Qt::Horizontal);
- slider->setRange(, * );
- slider->setSingleStep();
- slider->setPageStep( * );
- slider->setTickInterval( * );
- slider->setTickPosition(QSlider::TicksRight);
- //这种经典的用法一定要小心,报错:glWidget的槽函数在传进来的时候已经被强制转换成SLOT了,
- //所以setterSlot不用SLOT修饰;同样,changedSignal也不能再拿SIGNAL修饰
- connect(slider, SIGNAL(valueChanged(int)), glWidget, setterSlot);
- connect(glWidget, changedSignal, slider, SLOT(setValue(int)));
- return slider;
- }
- void MainWindow::createActions()
- {
- renderIntoPixmapAction = new QAction(tr("&Render into Pixmap..."), this);
- renderIntoPixmapAction->setShortcut(tr("Ctrl+R"));
- renderIntoPixmapAction->setToolTip(tr("yes, triggerd it"));
- connect(renderIntoPixmapAction, SIGNAL(triggered()),
- this, SLOT(renderIntoPixmap()));
- grabFrameBufferAction = new QAction(tr("&Grab Frame Buffer"), this);
- grabFrameBufferAction->setShortcut(tr("Ctrl+G"));
- connect(grabFrameBufferAction, SIGNAL(triggered()),
- this, SLOT(grabFrameBuffer()));
- clearPixmapAction = new QAction(tr("&Clear Pixmap"), this);
- clearPixmapAction->setShortcut(tr("Ctrl+L"));
- connect(clearPixmapAction, SIGNAL(triggered()), this, SLOT(clearPixmap()));
- exitAction = new QAction(tr("E&xit"), this);
- exitAction->setShortcuts(QKeySequence::Quit);
- connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
- aboutAction = new QAction(tr("&About"), this);
- connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
- aboutQtAction = new QAction(tr("About &Qt"), this);
- connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
- }
- void MainWindow::createMenus()
- {
- fileMenu = menuBar()->addMenu(tr("&File"));
- fileMenu->addAction(renderIntoPixmapAction);
- fileMenu->addAction(grabFrameBufferAction);
- fileMenu->addAction(clearPixmapAction);
- fileMenu->addSeparator();
- fileMenu->addAction(exitAction);
- helpMenu = menuBar()->addMenu(tr("&Help"));
- helpMenu->addAction(aboutAction);
- helpMenu->addAction(aboutQtAction);
- }
- MainWindow::~MainWindow()
- {
- }
- //main.cpp
- #include <QApplication>
- #include <QDesktopWidget>
- #include "mainwindow.h"
- #include "glwidget.h"
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
- MainWindow window;
- window.show();
- //GLWidget widegt;
- //widegt.show();
- return app.exec();
- }
二.介绍
1.GLWidget控件类的实现
a.继承QGLWidget类
b.实例虚构OpenGL函数
- protected:
- void initializeGL();
- void paintGL();
- void resizeGL(int w, int h);
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
c.根据相关的功能添加函数和变量
d.c++语法两个,其一
- int xRotation() const { return xRot; }
- int yRotation() const { return yRot; }
- int zRotation() const { return zRot; }
- //const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰.
- //常成员函数, 它不改变对象的成员变量.
- //也不能调用类中任何非const成员函数.
其二
- explicit GLWidget(QWidget *parent = );
- //声明为explicit的构造函数不能在隐式转换中使用。
2.mainwindow类的实现.
a.实现鼠标拖动和slider保持一致.
举个简单的例子:
- #include<QApplication>
- #include <QHBoxLayout>
- #include <QSlider>
- #include <QSpinBox>
- int main(int argc, char *argv[])
- {
- QApplication app(argc, argv);
- QWidget *window = new QWidget;
- window->setWindowTitle("Enter a Number");
- QSpinBox *spinbox = new QSpinBox;
- QSlider *slider = new QSlider(Qt::Horizontal);
- spinbox->setRange(, );
- slider->setRange(, );
- QObject::connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
- QObject::connect(slider,SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
- spinbox->setValue();
- QHBoxLayout *layout = new QHBoxLayout;
- layout->addWidget(spinbox);
- layout->addWidget(slider);
- window->setLayout(layout);
- window->show();
- return app.exec();
- }
b.截图功能实现的工作原理..........
Qt中OpenGL的初步使用的更多相关文章
- Qt中OpenGL模块下将图片转化为纹理,并传入shader中
QImage texture, buffer; buffer.load("C:/Users/wukesong/Pictures/flower.jpg"); texture = QG ...
- Qt 框架的图形性能高(OpenGL上的系统效率高),网络性能低,开发效率高,Quick是可以走硬件加速——Qt中分为好几套图形系统,差不多代表了2D描画的发展史。最经典的软描画系统
-----图形性能部分-----Qt的widgets部分,运行时的图像渲染性能是一般的,因为大部分的界面内容都是Qt自绘,没有走硬件加速,也就是说很多图形内容都是CPU算出来的.但是widgets底层 ...
- Ubuntu中在QT中配置OpenGL
之前搞实验室项目,博客有些天没有更新.现在学习需要,开始搞OpenGL+Ubuntu+QT. 搞了整整一天,由于是首次使用ubuntu,所以这ubuntu下配置qt和Opengl环境时走了很多的弯路, ...
- Qt Quick + OpenGL + Bullet初次測试
Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
- Windows平台下Qt中glut库的使用
用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...
- Qt中的事件
1. 引自---http://blog.sina.com.cn/s/blog_6e80f1390100pro4.html 信号和事件的区别就在与,事件比信号更加底层,而且如果一个信号对应多个槽的话,信 ...
- 在QT中使用Irrlicht引擎的方法与步骤
Ø 相关库,插件安装部分 本篇文档介绍在Qt5.2.0下面使用lrrlicht引擎在Qt窗口中输出(开发环境:vs2012) 1. 首先安装好Qt5.2.0,下载地址: http://downlo ...
- QT中使用Glut库
用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...
- Qt 中一些常用类中文说明
Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进 ...
随机推荐
- MVC 全局异常过滤器HandleErrorAttribute
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- Oracle sql语言模糊查询--like后面的通配符
关于like后面的条件,Oracle提供了四种匹配模式: 1,% :表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FR ...
- CentOS 7 启动VNC失败问题
开机后发现VNC服务没有启启来,提示我们使用journalctl -xn查看错误信息,提示信息如下: Sep :: localhost.localdomain systemd[]: Unit vncs ...
- java命令行运行带外部jar
假设:java 代码路径为com.jdw.test,其中调用了外部jar包 则需要将jar包解压后,放入com同级目录 然后再com目录启动命令行 java com.jdw.test.HelloWor ...
- c++大数模版
http://blog.csdn.net/hackbuteer1/article/details/6595881 #include<iostream> #include<string ...
- 自动生成XML空节点格式的差异
我们用C#开发了上位机配置软件,用C开发了嵌入式软件,然后他们之间的参数交互靠XML文件来沟通. C#中添加一个空的节点有以下几种情况. 不给节点的InnerText赋值: <root> ...
- UVA 12657 Boxes in a Line
双向链表 注意:如果算法是最后处理翻转情况时,注意指令4翻转后1,2两个指令也要翻转处理: 指令3 中交换盒子要注意两个盒子相邻的情况 #include <iostream> #inclu ...
- c语言 列出系统进程
#include <stdio.h> #include "stdafx.h" #include <Windows.h> #include <strin ...
- Linux进程间通信——信号集函数
一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...
- .net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象
原文地址:http://www.cnblogs.com/fannyatg/archive/2012/04/16/2451611.html ------------------------------- ...