46.Qt 使用OpenGL绘制立方体
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>ö"
"<tr><td>Close:<td>ı<td>i<td>u<td>ü"
"<tr><td>Front:<td>e<td>i<td>ö<td>ü"
"<tr><td>Back:<td>a<td>ı<td>o<td>u"
"<tr><td>Round:<td>o<td>ö<td>u<td>ü"
"<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绘制立方体的更多相关文章
- QT OpenGL绘制三维图形(立方体、圆柱体、圆锥、球体、圆环等等)
本文使用QGLWidget来绘制各种三维基本图形,包括立方体.圆柱体.圆锥.球体.圆环等等,涉及包括基本绘制以及上色.纹理.旋转等操作. 使用的软件版本:QT5.12 + QT Creater4.8. ...
- OpenGl 绘制一个立方体
OpenGl 绘制一个立方体 为了绘制六个正方形,我们为每个正方形指定四个顶点,最终我们需要指定6*4=24个顶点.但是我们知道,一个立方体其实总共只有八个顶点,要指定24次,就意味着每个顶点其实重复 ...
- OpenGL绘制自由落体小球
OpenGL绘制自由落体小球 一. 程序运行的软硬件环境 本次设计在window10系统下进行,运用C++进行编写,在CodeBlocks环境下使用OpenGL进行设计. 所需环境配置分为2部分 ...
- OpenGL绘制简单场景,实现旋转缩放平移和灯光效果
本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ...
- Qt Quick + OpenGL + Bullet初次測试
Qt Quick + OpenGL + Bullet初次測试 眼下Qt的Quick模块已经表现得很出色,并且可以预留接口来渲染OpenGL场景.一般来说,已经可以满足大部分编程须要了.这次呢.尝试使用 ...
- [Modern OpenGL系列(三)]用OpenGL绘制一个三角形
本文已同步发表在CSDN:http://blog.csdn.net/wenxin2011/article/details/51347008 在上一篇文章中已经介绍了OpenGL窗口的创建.本文接着说如 ...
- opengl绘制正弦曲线
利用opengl绘制正弦曲线 ,见代码: #include <windows.h> //#include <GLUT/glut.h> #include <GL/glut. ...
- Qt之自绘制饼图
1.说明 最近在搞绘图方面的工作,说实话C++的第三方绘图库并不算多,总之我了解的有:qtcharts.ChartDirector.qwt.kdchart和QCustomPlot.这几个库各有利弊. ...
- Opengl绘制我们的小屋(二)第一人称漫游
这章我们先讲第一人称漫游的实现.在openTK里,我们用函数Matrix4.LookAt(caram.Eye,caram.Target,Vector3.UnitY)来放置摄像机,其中三个参数分别与摄像 ...
随机推荐
- SSIS SQL Server配置自动作业
目录: 一. 用SSMS配置作业,自助调度: 二.用SSMS调SSIS包: 一. 用SSMS配置作业,自助调度: 为验证数据,先创建一个表: CREATE TABLE test_table (id I ...
- 三维重建5:场景中语义分析/语义SLAM/DCNN-大尺度SLAM
前言: 在实时/非实时大规模三维场景重建中,引入了语义SLAM这个概念,参考三维重建:SLAM的尺度和方法论问题和三维重建:SLAM的粒度和工程化问题 .大规模三维场景重建的尺度增大,因此相对于整个重 ...
- .NET Core & EntityFrameworkCore
前言 .NET Core 相比于 .NET Fromework 有跨平台.轻量化且开源的优势. 在使用 EntityFrameworkCore 的时候也遇到了很多问题,至于网络上的教程嘛...大部分都 ...
- 【技术累积】【点】【java】【18】URLEncode
基础概念 由于以URL的形式传递信息给服务器时,不允许URL中出现一些特殊字符和空格的,所以需要对URL进行编码处理. 原理是: 将要转码的字符转变为16进制: 从右到左,每两位前面加% 哪些字符是需 ...
- (转)基于Metronic的Bootstrap开发框架经验总结(5)--Bootstrap文件上传插件File Input的使用
http://www.cnblogs.com/wuhuacong/p/4774396.html Bootstrap文件上传插件File Input是一个不错的文件上传控件,但是搜索使用到的案例不多,使 ...
- Dispatch Queues and Thread Safety
Dispatch Queues and Thread Safety It might seem odd to talk about thread safety in the context of di ...
- mac系统下安装、启动、停止mongodb
mongodb是非关系型数据库,mysquel是关系型数据库,前者没有数据表这个说法,后者有 一. 下载nodejs,安装,一直到 node -v显示版本号,表示安装成功. 二. 本文主要讲解,安装包 ...
- webpack学习(三)
前篇:webpack学习(二) jquery不需要在项目中自己下载,而是作为一个模块引入.jquery的存放路径是在 node_modules目录下.1.首先给项目安装jquery,npm insta ...
- 使用百度fis3构建前端多页应用
吾日三省吾身. 从一个完全不相干的行业转到IT,多多少少都会感到迷茫,不知道学习什么.从何学起?在几乎没有任何经验的背景下,坚持投递简历,最后终于进入了一个创业公司,开始做起了前端工作.工资勉强维持生 ...
- STL源码分析之第一级配置器
前言 上一节我们分析了空间配置器对new的配置, 而STL将空间配置器分为了两级, 第一级是直接调用malloc分配空间, 调用free释放空间, 第二级三就是建立一个内存池, 小于128字节的申请都 ...