main.cpp

#include <QApplication>
#include <iostream> #include "vowelcube.h" int main(int argc, char *argv[])
{
QApplication app(argc, argv); if (!QGLFormat::hasOpenGL()) {
std::cerr << "This system has no OpenGL support" << std::endl;
return ;
} VowelCube cube;
cube.setWindowTitle(QObject::tr("Vowel Cube"));
cube.setMinimumSize(, );
cube.resize(, );
cube.show(); return app.exec();
}

vowelcube.h

#ifndef VOWELCUBE_H
#define VOWELCUBE_H #include <QGLWidget>
#include <QRadialGradient> //使用OpenGL绘制立方体,使用QPainter绘制背景
//的渐变,接着使用renderText()绘制立方体角上的8个
//元音字母,最后使用QPainter和QTextDocument绘制图例。
//用户可以单击并拖动鼠标来旋转立方体,并且可以使用鼠标滚轮进行放大或缩小
class VowelCube : public QGLWidget
{
Q_OBJECT public:
VowelCube(QWidget *parent = );
~VowelCube(); protected:
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void wheelEvent(QWheelEvent *event); private:
void createGradient();
void createGLObject();
void drawBackground(QPainter *painter);
void drawCube();
void drawLegend(QPainter *painter); GLuint glObject;
QRadialGradient gradient;
GLfloat rotationX;
GLfloat rotationY;
GLfloat rotationZ;
GLfloat scaling;
QPoint lastPos;
}; #endif

vowelcube.cpp

 #include <QtGui>
#include <QtOpenGL>
#include <cmath> #ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE 0x809D
#endif #include "vowelcube.h" VowelCube::VowelCube(QWidget *parent)
: QGLWidget(parent)
{
//调用setFormat()使OpenGL的显示描述表支持饭走样。
setFormat(QGLFormat(QGL::SampleBuffers)); //初始化私有变量
rotationX = -38.0;
rotationY = -58.0;
rotationZ = 0.0;
scaling = 1.0; //设置填充背景的QRadialGradient
createGradient();
//创建OpenGL立方体对象
createGLObject(); setAutoBufferSwap( false );
setAutoFillBackground( false );
} VowelCube::~VowelCube()
{
makeCurrent();
//删除构造函数创建的OpenGL立方体对象
glDeleteLists(glObject, );
} //绘制,在paintEvent()中创建一个QPainter,在进行纯OpenGL操作时
//保存和恢复其状态。
//QPainter的构造函数(或者QPainter::begin())自动调用glClear
//除非预先调用窗口部件的setAutoFillBackground(false)
//QPainter的析构函数(或者QPainter::end())自动调用QGLWidget::swapBuffers()
//切换可见缓存和离屏缓存,除非预先调用setAutoBufferSwap(false).
//当QPainter被激活,我们可以交叉使用纯OpenGL命令,只要在执行纯OpenGL命令之前保存OpenGL状态,之后恢复OpenGL状态
void VowelCube::paintEvent(QPaintEvent * /* event */)
{
QPainter painter( this );
//绘制背景
drawBackground( &painter );
//背景绘制结束
painter.end( );
//绘制立方体
drawCube();
//绘制开始
painter.begin(this);
//使用HTML文字设置QTextDocument对象
drawLegend(&painter);
painter.end( );
swapBuffers( );
} //鼠标按下事件
void VowelCube::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
} //鼠标移动事件
void VowelCube::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 += * dy;
rotationY += * dx;
update();
} else if (event->buttons() & Qt::RightButton) {
rotationX += * dy;
rotationZ += * dx;
update();
}
lastPos = event->pos();
} //鼠标滚动的事件,调用update
void VowelCube::wheelEvent(QWheelEvent *event)
{
double numDegrees = -event->delta() / 8.0;
double numSteps = numDegrees / 15.0;
scaling *= std::pow(1.125, numSteps);
update();
} //使用蓝色渐变色设置QRadialGradient
void VowelCube::createGradient()
{
//确保指定的中心和焦点坐标根据窗口部件大小进行调整
gradient.setCoordinateMode(QGradient::ObjectBoundingMode);
//位置用0和1之间的浮点数表示,0对应焦点坐标,1对应圆的边缘
gradient.setCenter(0.45, 0.50);
gradient.setFocalPoint(0.40, 0.45);
gradient.setColorAt(0.0, QColor(, , ));
gradient.setColorAt(0.4, QColor(, , ));
gradient.setColorAt(0.8, QColor(, , ));
} //创建OpenGL列表,该列表保存绘制的立方体的边。
void VowelCube::createGLObject()
{
makeCurrent(); glShadeModel(GL_FLAT); glObject = glGenLists();
glNewList(glObject, GL_COMPILE);
qglColor(QColor(, , ));
glLineWidth(1.0); glBegin(GL_LINES);
glVertex3f(+1.0, +1.0, -1.0);
glVertex3f(-1.0, +1.0, -1.0);
glVertex3f(+1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(+1.0, -1.0, +1.0);
glVertex3f(-1.0, -1.0, +1.0);
glEnd(); glBegin(GL_LINE_LOOP);
glVertex3f(+1.0, +1.0, +1.0);
glVertex3f(+1.0, +1.0, -1.0);
glVertex3f(+1.0, -1.0, -1.0);
glVertex3f(+1.0, -1.0, +1.0);
glVertex3f(+1.0, +1.0, +1.0);
glVertex3f(-1.0, +1.0, +1.0);
glVertex3f(-1.0, +1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, +1.0);
glVertex3f(-1.0, +1.0, +1.0);
glEnd(); glEndList();
} void VowelCube::drawBackground(QPainter *painter)
{
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
painter->drawRect(rect());
} //绘制立方体
void VowelCube::drawCube()
{
glPushAttrib(GL_ALL_ATTRIB_BITS); glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
GLfloat x = 3.0 * GLfloat(width()) / height();
glOrtho(-x, +x, -3.0, +3.0, 4.0, 15.0); glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(0.0, 0.0, -10.0);
glScalef(scaling, scaling, scaling); glRotatef(rotationX, 1.0, 0.0, 0.0);
glRotatef(rotationY, 0.0, 1.0, 0.0);
glRotatef(rotationZ, 0.0, 0.0, 1.0); //设置反走样
glEnable(GL_MULTISAMPLE); //绘制立方体
glCallList(glObject); //设置文字颜色和字体
setFont(QFont("Times", ));
qglColor(QColor(, , )); //绘制字符,renderText使文字不变形
renderText(+1.1, +1.1, +1.1, QChar('a'));
renderText(-1.1, +1.1, +1.1, QChar('e'));
renderText(+1.1, +1.1, -1.1, QChar('o'));
renderText(-1.1, +1.1, -1.1, QChar(0x00F6));
renderText(+1.1, -1.1, +1.1, QChar(0x0131));
renderText(-1.1, -1.1, +1.1, QChar('i'));
renderText(+1.1, -1.1, -1.1, QChar('u'));
renderText(-1.1, -1.1, -1.1, QChar(0x00FC)); glMatrixMode(GL_MODELVIEW);
glPopMatrix(); glMatrixMode(GL_PROJECTION);
glPopMatrix(); glPopAttrib();
} //使用HTML文字设置QTextDocument对象,在半透明的蓝色矩形上绘制它们
void VowelCube::drawLegend(QPainter *painter)
{
const int Margin = ;
const int Padding = ; QTextDocument textDocument;
textDocument.setDefaultStyleSheet("* { color: #FFEFEF }");
textDocument.setHtml("<h4 align=\"center\">Vowel Categories</h4>"
"<p align=\"center\"><table width=\"100%\">"
"<tr><td>Open:<td>a<td>e<td>o<td>&ouml;"
"<tr><td>Close:<td>ı<td>i<td>u<td>&uuml;"
"<tr><td>Front:<td>e<td>i<td>&ouml;<td>&uuml;"
"<tr><td>Back:<td>a<td>ı<td>o<td>u"
"<tr><td>Round:<td>o<td>&ouml;<td>u<td>&uuml;"
"<tr><td>Unround:<td>a<td>e<td>ı<td>i"
"</table>");
textDocument.setTextWidth(textDocument.size().width()); QRect rect(QPoint(, ), textDocument.size().toSize()
+ QSize( * Padding, * Padding));
painter->translate(width() - rect.width() - Margin,
height() - rect.height() - Margin);
painter->setPen(QColor(, , ));
painter->setBrush(QColor(, , , ));
painter->drawRect(rect); painter->translate(Padding, Padding);
textDocument.drawContents(painter);
}

46.Qt 使用OpenGL绘制立方体的更多相关文章

  1. QT OpenGL绘制三维图形(立方体、圆柱体、圆锥、球体、圆环等等)

    本文使用QGLWidget来绘制各种三维基本图形,包括立方体.圆柱体.圆锥.球体.圆环等等,涉及包括基本绘制以及上色.纹理.旋转等操作. 使用的软件版本:QT5.12 + QT Creater4.8. ...

  2. OpenGl 绘制一个立方体

    OpenGl 绘制一个立方体 为了绘制六个正方形,我们为每个正方形指定四个顶点,最终我们需要指定6*4=24个顶点.但是我们知道,一个立方体其实总共只有八个顶点,要指定24次,就意味着每个顶点其实重复 ...

  3. OpenGL绘制自由落体小球

    OpenGL绘制自由落体小球 一.    程序运行的软硬件环境 本次设计在window10系统下进行,运用C++进行编写,在CodeBlocks环境下使用OpenGL进行设计. 所需环境配置分为2部分 ...

  4. OpenGL绘制简单场景,实现旋转缩放平移和灯光效果

    本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ...

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

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

  6. [Modern OpenGL系列(三)]用OpenGL绘制一个三角形

    本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...

  7. opengl绘制正弦曲线

    利用opengl绘制正弦曲线 ,见代码: #include <windows.h> //#include <GLUT/glut.h> #include <GL/glut. ...

  8. Qt之自绘制饼图

    1.说明 最近在搞绘图方面的工作,说实话C++的第三方绘图库并不算多,总之我了解的有:qtcharts.ChartDirector.qwt.kdchart和QCustomPlot.这几个库各有利弊. ...

  9. Opengl绘制我们的小屋(二)第一人称漫游

    这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...

随机推荐

  1. SSIS SQL Server配置自动作业

    目录: 一. 用SSMS配置作业,自助调度: 二.用SSMS调SSIS包: 一. 用SSMS配置作业,自助调度: 为验证数据,先创建一个表: CREATE TABLE test_table (id I ...

  2. 三维重建5:场景中语义分析/语义SLAM/DCNN-大尺度SLAM

    前言: 在实时/非实时大规模三维场景重建中,引入了语义SLAM这个概念,参考三维重建:SLAM的尺度和方法论问题和三维重建:SLAM的粒度和工程化问题 .大规模三维场景重建的尺度增大,因此相对于整个重 ...

  3. .NET Core & EntityFrameworkCore

    前言 .NET Core 相比于 .NET Fromework 有跨平台.轻量化且开源的优势. 在使用 EntityFrameworkCore 的时候也遇到了很多问题,至于网络上的教程嘛...大部分都 ...

  4. 【技术累积】【点】【java】【18】URLEncode

    基础概念 由于以URL的形式传递信息给服务器时,不允许URL中出现一些特殊字符和空格的,所以需要对URL进行编码处理. 原理是: 将要转码的字符转变为16进制: 从右到左,每两位前面加% 哪些字符是需 ...

  5. (转)基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用

    http://www.cnblogs.com/wuhuacong/p/4774396.html Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使 ...

  6. Dispatch Queues and Thread Safety

    Dispatch Queues and Thread Safety It might seem odd to talk about thread safety in the context of di ...

  7. mac系统下安装、启动、停止mongodb

    mongodb是非关系型数据库,mysquel是关系型数据库,前者没有数据表这个说法,后者有 一. 下载nodejs,安装,一直到 node -v显示版本号,表示安装成功. 二. 本文主要讲解,安装包 ...

  8. webpack学习(三)

    前篇:webpack学习(二) jquery不需要在项目中自己下载,而是作为一个模块引入.jquery的存放路径是在 node_modules目录下.1.首先给项目安装jquery,npm insta ...

  9. 使用百度fis3构建前端多页应用

    吾日三省吾身. 从一个完全不相干的行业转到IT,多多少少都会感到迷茫,不知道学习什么.从何学起?在几乎没有任何经验的背景下,坚持投递简历,最后终于进入了一个创业公司,开始做起了前端工作.工资勉强维持生 ...

  10. STL源码分析之第一级配置器

    前言 上一节我们分析了空间配置器对new的配置, 而STL将空间配置器分为了两级, 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都 ...