结果预览:

一.代码5个文件

  1. //glwidget.h
  2. #ifndef GLWIDGET_H
  3. #define GLWIDGET_H
  4. #include <QGLWidget>
  5.  
  6. class GLWidget:public QGLWidget
  7. {
  8. Q_OBJECT
  9. public:
  10. explicit GLWidget(QWidget *parent = );
  11.  
  12. int xRotation() const { return xRot; }
  13. int yRotation() const { return yRot; }
  14. int zRotation() const { return zRot; }
  15.  
  16. signals:
  17. void xRotationChanged( int angle);
  18. void yRotationChanged( int angle);
  19. void zRotationChanged( int angle);
  20. public slots:
  21. void setXRotation(int angle);
  22. void setYRotation(int angle);
  23. void setZRotation(int angle);
  24. protected:
  25. void initializeGL();
  26. void paintGL();
  27. void resizeGL(int w, int h);
  28. void mousePressEvent(QMouseEvent *event);
  29. void mouseMoveEvent(QMouseEvent *event);
  30.  
  31. private slots:
  32. void alwaysRotate();
  33. void drawTriangle();
  34.  
  35. private:
  36. void normalizeAngle(int &angle);
  37. int xRot;
  38. int yRot;
  39. int zRot;
  40. QColor faceColors[];
  41. QPoint lastPos;
  42. QColor qtGreen, qtPurple;
  43. };
  44.  
  45. #endif
  1. //glwidget.cpp
  2. #include <QtGui>
  3. #include <QtOpenGL>
  4. #include<math.h>
  5. #include"glwidget.h"
  6.  
  7. #ifndef GL_MULTISAMPLE
  8. #define GL_MULTISAMPLE 0x809D
  9. #endif
  10.  
  11. GLWidget::GLWidget(QWidget *parent):QGLWidget(parent)
  12. {
  13.  
  14. xRot = ;
  15. yRot = ;
  16. zRot = ;
  17.  
  18. faceColors[] = Qt::red;
  19. faceColors[] = Qt::green;
  20. faceColors[] = Qt::blue;
  21. faceColors[] = Qt::yellow;
  22.  
  23. qtGreen = QColor::fromCmykF(0.40, 0.0, 1.0, 0.0);
  24. qtPurple = QColor::fromCmykF(0.39, 0.39, 0.0, 0.0);
  25.  
  26. QTimer *timer = new QTimer(this);
  27. connect(timer , SIGNAL(timeout()), this,SLOT(alwaysRotate()));
  28. timer->start();
  29. }
  30. void GLWidget::initializeGL()
  31. {
  32. qglClearColor(qtPurple.dark());
  33. glShadeModel(GL_SMOOTH);
  34. glEnable(GL_DEPTH);
  35. glEnable(GL_DEPTH_TEST);
  36. glEnable(GL_MULTISAMPLE);
  37. glEnable(GL_CULL_FACE);
  38.  
  39. }
  40. void GLWidget::paintGL()
  41. {
  42. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  43. glPushMatrix();
  44. drawTriangle();
  45. glPopMatrix();
  46. }
  47.  
  48. void GLWidget::resizeGL(int w, int h)
  49. {
  50. int side = qMin(w,h);
  51. glViewport((width() - side) / , (height() - side)/, side, side);
  52.  
  53. glMatrixMode(GL_PROJECTION);
  54. glLoadIdentity();
  55. glFrustum( -1.2, 1.2, -1.2, 1.2,5.0, 60.0);
  56. glMatrixMode(GL_MODELVIEW);
  57. glLoadIdentity();
  58. glTranslatef(0.0, 0.0, -40.0);
  59.  
  60. }
  61.  
  62. void GLWidget::mousePressEvent(QMouseEvent *event)
  63. {
  64. lastPos = event->pos();
  65. }
  66. void GLWidget::mouseMoveEvent(QMouseEvent *event)
  67. {
  68. int dx = event->x() - lastPos.x();
  69. int dy = event->y() - lastPos.y();
  70.  
  71. if (event->buttons()&Qt::LeftButton)
  72. {
  73. setYRotation(yRot + *dy);
  74. } else if (event->buttons()&Qt::RightButton)
  75. {
  76. setZRotation(zRot + *dx);
  77. }
  78. lastPos = event->pos();
  79. }
  80.  
  81. void GLWidget::drawTriangle()
  82. {
  83. static const GLfloat P1[] = { 0.0, -1.0, +2.0 };
  84. static const GLfloat P2[] = { +1.73, -1.0, -1.0 };
  85. static const GLfloat P3[] = { -1.73, -1.0, -1.0 };
  86. static const GLfloat P4[] = { 0.0, +2.0, 0.0 };
  87.  
  88. static const GLfloat * const coords[][] = {
  89. { P1, P2, P3 }, { P1, P3, P4 }, { P1, P4, P2 }, { P2, P4, P3 }
  90. };
  91. glMatrixMode(GL_MODELVIEW);
  92. glLoadIdentity();
  93. glTranslated( 0.0 , 0.0, -10.0);
  94. glRotatef(xRot, 1.0, 0.0, 0.0);
  95. glRotatef(yRot, 0.0, 1.0, 0.0);
  96. glRotatef(zRot, 0.0, 0.0,1.0);
  97.  
  98. for (int i = ; i != ; ++i)
  99. {
  100. glBegin(GL_TRIANGLES);
  101. qglColor(faceColors[i]);
  102. for (int j = ; j<;++j)
  103. glVertex3f(coords[i][j][], coords[i][j][], coords[i][j][]);
  104. glEnd();
  105. }
  106.  
  107. }
  108.  
  109. void GLWidget::normalizeAngle(int &angle)
  110. {
  111. while (angle<)
  112. angle +=*;
  113. while (angle>*)
  114. angle -=*;
  115. }
  116.  
  117. void GLWidget::setXRotation(int angle)
  118. {
  119. normalizeAngle(angle);
  120. if ( angle!=xRot)
  121. {
  122. xRot = angle;
  123. emit xRotationChanged(angle);
  124. updateGL();
  125. }
  126. }
  127. void GLWidget::setYRotation(int angle)
  128. {
  129. normalizeAngle(angle);
  130. if ( angle != yRot ) {
  131. yRot = angle;
  132. emit yRotationChanged(angle);
  133. updateGL();
  134. }
  135. }
  136.  
  137. void GLWidget::setZRotation(int angle)
  138. {
  139. normalizeAngle(angle);
  140. if ( angle != zRot ) {
  141. zRot = angle;
  142. emit zRotationChanged(angle);
  143. updateGL();
  144. }
  145. }
  146.  
  147. void GLWidget::alwaysRotate()
  148. {
  149. zRot +=;
  150. if (zRot>*) zRot = ;
  151. emit zRotationChanged(zRot);
  152. updateGL();
  153. }
  1. //mainwindow.h
  2. #ifndef MAINWINDOW_H
  3. #define MAINWINDOW_H
  4.  
  5. #include <QMainWindow>
  6.  
  7. class QAction;
  8. class QLabel;
  9. class QMenu;
  10. class QSlider;
  11. class QScrollArea;
  12.  
  13. class GLWidget;
  14.  
  15. class MainWindow : public QMainWindow
  16. {
  17. Q_OBJECT
  18.  
  19. public:
  20. MainWindow(QWidget *parent = );
  21. ~MainWindow();
  22.  
  23. private slots:
  24. void renderIntoPixmap();
  25. void grabFrameBuffer();
  26. void clearPixmap();
  27. void about();
  28.  
  29. private:
  30.  
  31. void createMenus();
  32. void createActions();
  33.  
  34. QSlider *createSlider(const char *changedSignal, const char *setterSlot);
  35. void setPixmap(const QPixmap &pixmap);
  36. QSize getSize();
  37.  
  38. QWidget *centralWidget;
  39. QScrollArea *glWidgetArea;
  40. QScrollArea *pixmapLabelArea;
  41. GLWidget *glWidget;
  42. QLabel *pixmapLabel;
  43. QSlider *xSlider;
  44. QSlider *ySlider;
  45. QSlider *zSlider;
  46.  
  47. QMenu *fileMenu;
  48. QMenu *helpMenu;
  49. QAction *renderIntoPixmapAction;
  50. QAction *grabFrameBufferAction;
  51. QAction *clearPixmapAction;
  52. QAction *exitAction;
  53. QAction *aboutAction;
  54. QAction *aboutQtAction;
  55.  
  56. };
  57.  
  58. #endif // MAINWINDOW_H
  1. //mainwindow.cpp
  2. #include <QtOpenGL>
  3. #include <QAction>
  4. #include <QLabel>
  5. #include <QMenu>
  6. #include <QSlider>
  7. #include <QScrollArea>
  8. #include <QMenuBar>
  9. #include <QApplication>
  10.  
  11. #include "mainwindow.h"
  12. #include "glwidget.h"
  13. #include <time.h>
  14.  
  15. MainWindow::MainWindow(QWidget *parent)
  16. : QMainWindow(parent)
  17. {
  18. centralWidget = new QWidget;
  19. setCentralWidget(centralWidget);
  20.  
  21. glWidget = new GLWidget;
  22. pixmapLabel = new QLabel;
  23.  
  24. glWidgetArea = new QScrollArea;
  25. glWidgetArea->setWidget(glWidget);
  26. //glWidgetArea->viewport()->setBackgroundRole(QPalette::Dark);
  27. glWidgetArea->setWidgetResizable(true);
  28. glWidgetArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  29. glWidgetArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  30. glWidgetArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
  31. glWidgetArea->setMinimumSize(, );
  32.  
  33. pixmapLabelArea = new QScrollArea;
  34. pixmapLabelArea->setWidget(pixmapLabel);
  35. pixmapLabelArea->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
  36. pixmapLabelArea->setMinimumSize(, );
  37.  
  38. //在构造一个QSlider时将QGLWidget的信号和槽传给这个函数的形参,这样就可以在QMainWindow中
  39. //控制OpenGL的动作了,而让GLWidget类只完成绘图工作。
  40. xSlider = createSlider(SIGNAL(xRotationChanged(int)),
  41. SLOT(setXRotation(int)));
  42. ySlider = createSlider(SIGNAL(yRotationChanged(int)),
  43. SLOT(setYRotation(int)));
  44. zSlider = createSlider(SIGNAL(zRotationChanged(int)),
  45. SLOT(setZRotation(int)));
  46.  
  47. /*
  48. xSlider = new QSlider(Qt::Horizontal);
  49. ySlider = new QSlider(Qt::Horizontal);
  50. zSlider = new QSlider(Qt::Horizontal);
  51. */
  52.  
  53. QGridLayout *centralLayout = new QGridLayout;
  54. centralLayout->addWidget(glWidgetArea, , );
  55. centralLayout->addWidget(pixmapLabelArea, , );
  56. centralLayout->addWidget(xSlider, , , , );
  57. centralLayout->addWidget(ySlider, , , , );
  58. centralLayout->addWidget(zSlider, , , , );
  59. centralWidget->setLayout(centralLayout);
  60.  
  61. createActions();
  62. createMenus();
  63.  
  64. xSlider->setValue( * );
  65. ySlider->setValue( * );
  66. zSlider->setValue( * );
  67.  
  68. setWindowTitle(tr("Grabeer"));
  69. resize(, );
  70. }
  71.  
  72. void MainWindow::setPixmap(const QPixmap &pixmap)
  73. {
  74. //截图到磁盘
  75. time_t curTime = time(NULL);
  76. QString path1 = "E:\\",path2=".jpg";
  77. QString path = QString::number(curTime, )+path2;
  78.  
  79. pixmapLabel->setPixmap(pixmap);
  80. pixmap.save(path, , -);
  81. QSize size = pixmap.size();
  82. if (size - QSize(, ) == pixmapLabelArea->maximumViewportSize())
  83. size -= QSize(, );
  84. pixmapLabel->resize(size);
  85. }
  86.  
  87. QSize MainWindow::getSize()
  88. {
  89. bool ok;
  90. QString text = QInputDialog::getText(this, tr("Grabber"),
  91. tr("Enter Pixmap Size:"),
  92. QLineEdit::Normal,
  93. tr("%1 x %2").arg(glWidget->width())
  94. .arg(glWidget->height()),
  95. &ok);
  96. if (!ok)
  97. return QSize();
  98.  
  99. QRegExp regExp(tr("([0-9]+) *x *([0-9]+)"));
  100. if (regExp.exactMatch(text)) {
  101. int width = regExp.cap().toInt();
  102. int height = regExp.cap().toInt();
  103. if (width > && width < && height > && height < )
  104. return QSize(width, height);
  105. }
  106. return glWidget->size();
  107. }
  108.  
  109. void MainWindow::renderIntoPixmap()
  110. {
  111. QSize size = getSize();
  112. if (size.isValid()) {
  113. QPixmap pixmap = glWidget->renderPixmap(size.width(), size.height());
  114. setPixmap(pixmap);
  115. }
  116. }
  117.  
  118. void MainWindow::grabFrameBuffer()
  119. {
  120. //QGLWidget有一个返回其帧缓冲区的QImage图片的函数
  121. QImage image = glWidget->grabFrameBuffer();
  122. //QPixmap的fromImage函数把一个QImage转换成QPixmap
  123. setPixmap(QPixmap::fromImage(image));
  124. }
  125.  
  126. void MainWindow::clearPixmap()
  127. {
  128. setPixmap(QPixmap()); //给它传一个空的对象
  129. }
  130.  
  131. void MainWindow::about()
  132. {
  133. QMessageBox::about(this, tr("About Grabber"),
  134. tr("The <b>Grabber</b> example demonstrates two approaches for "
  135. "rendering OpenGL into a Qt pixmap."));
  136. }
  137.  
  138. QSlider *MainWindow::createSlider(const char *changedSignal,
  139. const char *setterSlot)
  140. {
  141. QSlider *slider = new QSlider(Qt::Horizontal);
  142. slider->setRange(, * );
  143. slider->setSingleStep();
  144. slider->setPageStep( * );
  145. slider->setTickInterval( * );
  146. slider->setTickPosition(QSlider::TicksRight);
  147.  
  148. //这种经典的用法一定要小心,报错:glWidget的槽函数在传进来的时候已经被强制转换成SLOT了,
  149. //所以setterSlot不用SLOT修饰;同样,changedSignal也不能再拿SIGNAL修饰
  150. connect(slider, SIGNAL(valueChanged(int)), glWidget, setterSlot);
  151. connect(glWidget, changedSignal, slider, SLOT(setValue(int)));
  152.  
  153. return slider;
  154. }
  155.  
  156. void MainWindow::createActions()
  157. {
  158. renderIntoPixmapAction = new QAction(tr("&Render into Pixmap..."), this);
  159. renderIntoPixmapAction->setShortcut(tr("Ctrl+R"));
  160. renderIntoPixmapAction->setToolTip(tr("yes, triggerd it"));
  161. connect(renderIntoPixmapAction, SIGNAL(triggered()),
  162. this, SLOT(renderIntoPixmap()));
  163.  
  164. grabFrameBufferAction = new QAction(tr("&Grab Frame Buffer"), this);
  165. grabFrameBufferAction->setShortcut(tr("Ctrl+G"));
  166. connect(grabFrameBufferAction, SIGNAL(triggered()),
  167. this, SLOT(grabFrameBuffer()));
  168.  
  169. clearPixmapAction = new QAction(tr("&Clear Pixmap"), this);
  170. clearPixmapAction->setShortcut(tr("Ctrl+L"));
  171. connect(clearPixmapAction, SIGNAL(triggered()), this, SLOT(clearPixmap()));
  172.  
  173. exitAction = new QAction(tr("E&xit"), this);
  174. exitAction->setShortcuts(QKeySequence::Quit);
  175. connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));
  176.  
  177. aboutAction = new QAction(tr("&About"), this);
  178. connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
  179.  
  180. aboutQtAction = new QAction(tr("About &Qt"), this);
  181. connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
  182. }
  183.  
  184. void MainWindow::createMenus()
  185. {
  186. fileMenu = menuBar()->addMenu(tr("&File"));
  187. fileMenu->addAction(renderIntoPixmapAction);
  188. fileMenu->addAction(grabFrameBufferAction);
  189. fileMenu->addAction(clearPixmapAction);
  190. fileMenu->addSeparator();
  191. fileMenu->addAction(exitAction);
  192.  
  193. helpMenu = menuBar()->addMenu(tr("&Help"));
  194. helpMenu->addAction(aboutAction);
  195. helpMenu->addAction(aboutQtAction);
  196. }
  197.  
  198. MainWindow::~MainWindow()
  199. {
  200. }
  1. //main.cpp
  2. #include <QApplication>
  3. #include <QDesktopWidget>
  4.  
  5. #include "mainwindow.h"
  6. #include "glwidget.h"
  7. int main(int argc, char *argv[])
  8. {
  9. QApplication app(argc, argv);
  10. MainWindow window;
  11. window.show();
  12. //GLWidget widegt;
  13. //widegt.show();
  14. return app.exec();
  15. }

二.介绍

1.GLWidget控件类的实现

a.继承QGLWidget类

b.实例虚构OpenGL函数

  1. protected:
  2. void initializeGL();
  3. void paintGL();
  4. void resizeGL(int w, int h);
  5. void mousePressEvent(QMouseEvent *event);
  6. void mouseMoveEvent(QMouseEvent *event);

c.根据相关的功能添加函数和变量

d.c++语法两个,其一

  1. int xRotation() const { return xRot; }
  2. int yRotation() const { return yRot; }
  3. int zRotation() const { return zRot; }
  4. //const修饰类的成员函数,则该成员函数不能修改类中任何非const成员函数。一般写在函数的最后来修饰.
  5. //常成员函数, 它不改变对象的成员变量.
  6. //也不能调用类中任何非const成员函数.

其二

  1. explicit GLWidget(QWidget *parent = );
  2. //声明为explicit的构造函数不能在隐式转换中使用。

2.mainwindow类的实现.

a.实现鼠标拖动和slider保持一致.

举个简单的例子:

  1. #include<QApplication>
  2. #include <QHBoxLayout>
  3. #include <QSlider>
  4. #include <QSpinBox>
  5. int main(int argc, char *argv[])
  6. {
  7. QApplication app(argc, argv);
  8.  
  9. QWidget *window = new QWidget;
  10. window->setWindowTitle("Enter a Number");
  11.  
  12. QSpinBox *spinbox = new QSpinBox;
  13. QSlider *slider = new QSlider(Qt::Horizontal);
  14. spinbox->setRange(, );
  15. slider->setRange(, );
  16.  
  17. QObject::connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
  18. QObject::connect(slider,SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
  19. spinbox->setValue();
  20.  
  21. QHBoxLayout *layout = new QHBoxLayout;
  22. layout->addWidget(spinbox);
  23. layout->addWidget(slider);
  24. window->setLayout(layout);
  25.  
  26. window->show();
  27. return app.exec();
  28. }

b.截图功能实现的工作原理..........

Qt中OpenGL的初步使用的更多相关文章

  1. Qt中OpenGL模块下将图片转化为纹理,并传入shader中

    QImage texture, buffer; buffer.load("C:/Users/wukesong/Pictures/flower.jpg"); texture = QG ...

  2. Qt 框架的图形性能高(OpenGL上的系统效率高),网络性能低,开发效率高,Quick是可以走硬件加速——Qt中分为好几套图形系统,差不多代表了2D描画的发展史。最经典的软描画系统

    -----图形性能部分-----Qt的widgets部分,运行时的图像渲染性能是一般的,因为大部分的界面内容都是Qt自绘,没有走硬件加速,也就是说很多图形内容都是CPU算出来的.但是widgets底层 ...

  3. Ubuntu中在QT中配置OpenGL

    之前搞实验室项目,博客有些天没有更新.现在学习需要,开始搞OpenGL+Ubuntu+QT. 搞了整整一天,由于是首次使用ubuntu,所以这ubuntu下配置qt和Opengl环境时走了很多的弯路, ...

  4. Qt Quick + OpenGL + Bullet初次測试

    Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...

  5. Windows平台下Qt中glut库的使用

    用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...

  6. Qt中的事件

    1. 引自---http://blog.sina.com.cn/s/blog_6e80f1390100pro4.html 信号和事件的区别就在与,事件比信号更加底层,而且如果一个信号对应多个槽的话,信 ...

  7. 在QT中使用Irrlicht引擎的方法与步骤

      Ø 相关库,插件安装部分 本篇文档介绍在Qt5.2.0下面使用lrrlicht引擎在Qt窗口中输出(开发环境:vs2012) 1. 首先安装好Qt5.2.0,下载地址: http://downlo ...

  8. QT中使用Glut库

    用Qt中的QGLWidget窗体类中是不包括glut工具库的,难怪在myGLWidget(在我的程序中是QGLWidget的派生类)中绘制实心球体是说“glutSolidSphere”: 找不到标识符 ...

  9. Qt 中一些常用类中文说明

    Qt 中一些常用类中文说明是本文讲述的内容,这篇文章主要是介绍Qt 当中经常使用的类,采取的是使用字母索引的方式,下面的类是被经常使用的. QDataStream 为QIODevice提供了一串的二进 ...

随机推荐

  1. MVC 全局异常过滤器HandleErrorAttribute

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  2. Oracle sql语言模糊查询--like后面的通配符

    关于like后面的条件,Oracle提供了四种匹配模式: 1,% :表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FR ...

  3. CentOS 7 启动VNC失败问题

    开机后发现VNC服务没有启启来,提示我们使用journalctl -xn查看错误信息,提示信息如下: Sep :: localhost.localdomain systemd[]: Unit vncs ...

  4. java命令行运行带外部jar

    假设:java 代码路径为com.jdw.test,其中调用了外部jar包 则需要将jar包解压后,放入com同级目录 然后再com目录启动命令行 java com.jdw.test.HelloWor ...

  5. c++大数模版

    http://blog.csdn.net/hackbuteer1/article/details/6595881 #include<iostream> #include<string ...

  6. 自动生成XML空节点格式的差异

    我们用C#开发了上位机配置软件,用C开发了嵌入式软件,然后他们之间的参数交互靠XML文件来沟通. C#中添加一个空的节点有以下几种情况. 不给节点的InnerText赋值: <root> ...

  7. UVA 12657 Boxes in a Line

    双向链表 注意:如果算法是最后处理翻转情况时,注意指令4翻转后1,2两个指令也要翻转处理: 指令3 中交换盒子要注意两个盒子相邻的情况 #include <iostream> #inclu ...

  8. c语言 列出系统进程

    #include <stdio.h> #include "stdafx.h" #include <Windows.h> #include <strin ...

  9. Linux进程间通信——信号集函数

    一.什么是信号 用过Windows的我们都知道,当我们无法正常结束一个程序时,可以用任务管理器强制结束这个进程,但这其实是怎么实现的呢?同样的功能在Linux上是通过生成信号和捕获信号来实现的,运行中 ...

  10. .net Mvc Controller 接收 Json/post方式 数组 字典 类型 复杂对象

    原文地址:http://www.cnblogs.com/fannyatg/archive/2012/04/16/2451611.html ------------------------------- ...