Qt OpenGL初探 - 画坐标轴

Qt OpenGL初探 - 画坐标轴

  • 引言
  • 一、过程详解
    • 1.1 项目创建
    • 1.2 实现细节
  • 二、核心代码
  • 三、官方文档
    • 3.1 官网地址
    • 3.2 官方手册的使用

引言

在这里插入图片描述
Qt OpenGL模块可以很方便地将OpenGL应用在Qt程序中,本文使用其画了一个3D坐标轴(见上图),并详细讲解了具体的编码过程与官方手册的使用。

OpenGL是业界采用最广泛的二维和三维图形API。它独立于窗口系统和操作系统,并且网络透明。OpenGL使软件开发人员能够在CAD、内容创建、能源、娱乐、游戏开发、制造、医疗和虚拟现实等市场中创建高性能、视觉吸引力强的图形软件应用程序。但是OpenGL只处理3D渲染,对于GUI编程并不友好。OpenGL应用程序的用户界面必须使用另一个工具包创建,比如MFC或Qt

一、过程详解

1.1 项目创建

    1. 创建一个MainWindow项目,便于后续显示,在pro文件需添加以下内容:
      QT += opengl
      win32:LIBS += -lOpengl32 -lglu32
      unix:LIBS += -lglut -lGLU
    1. 创建QopenGLDemo 类,继承QOpenGLWidget
      class QopenGLDemo : public QOpenGLWidget
    1. 在MainWindow构造函数中添加如下代码,将创建的3D窗口添加到主窗口中,用于显示
      QopenGLDemo *m_gl = new QopenGLDemo(this);
      this->setCentralWidget(m_gl);
    1. 在QopenGLDemo.cpp中实现三个虚函数即可显示,initializeGLresizeGLpaintGL,后续有三个函数的完整代码

1.2 实现细节

核心为paintGL函数的实现

    1. 先画三条直线
      在这里插入图片描述
    // 初始化
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
    glLoadIdentity();  // 重置
    glTranslatef(0, 0, -30);    // 调整绘图坐标
    // 坐标轴
    float axis_length = 10;
    glLineWidth(5);
    glBegin(GL_LINE_STRIP);
    glColor3f(1, 0, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(axis_length, 0, 0);
    glEnd();
    glFlush();

    glBegin(GL_LINE_STRIP);
    glColor3f(0, 1, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(0, axis_length, 0);
    glEnd();
    glFlush();

    glBegin(GL_LINE_STRIP);
    glColor3f(0, 0, 1);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 0, axis_length);
    glEnd();
    glFlush();

glTranslatef(0, 0, -30);一定要有,根据投影矩阵:绘制的图形的Z轴坐标 >=0的话屏幕就不会显示。上图由于角度问题,并没有显示z轴…

    1. 调整角度,让其显示z轴
      在这里插入图片描述
	glTranslatef(0, 0, -30);    // 调整绘图坐标
    glRotatef(45.0, 0, -1, 0);  // 绕y轴旋转45度
    glRotatef(45.0, 1, 0, -1);  // 绕向量(1,0,-1) 旋转45度

增加两行旋转代码,感觉有那么点立体的意思了

    1. 画坐标轴的箭头
      在这里插入图片描述
    // 坐标轴箭头  参考官方文档: https://registry.khronos.org/OpenGL-Refpages/gl4/
    GLUquadricObj *objCylinder = gluNewQuadric();
    glPushMatrix();
    glColor3f(0, 0, 1);
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

    glPushMatrix();
    glColor3f(1, 0, 0);
    glRotatef(90, 0, 1, 0);      // 沿着y轴转90度 使得x轴对着原z轴方向
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

    glPushMatrix();
    glColor3f(0, 1, 0);
    glRotatef(-90, 1, 0, 0.0);   // 沿着x轴转90度 使得y轴对着原z轴方向
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

由于gluCylinder这个函数只能在原点处冲着z轴正向画圆柱(锥),想要在x轴和y轴上画,需要先将这两个轴旋转到z轴位置,并且进行平移。其中glPushMatrix即保存现场,直接glPopMatrix就会使得原点回到旋转和平移之前的位置。

    1. 最后增加一个原点
    // 画原点 - 白色
    glPointSize(10.0f);
    glBegin(GL_POINTS);
    glColor3f(1, 1, 1);
    glVertex3f(0, 0, 0);
    glEnd();
    glFlush();

二、核心代码

void QopenGLDemo::initializeGL(){
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  // rgba
    glShadeModel(GL_SMOOTH);               // 平滑着色  GL_FLAT 单调着色
}
void QopenGLDemo::resizeGL(int w, int h){
    glViewport(0, 0, w, h);           //重置当前的视口
    // glMatrixMode() 用以指定当前要操作的矩阵  GL_MODELVIEW(模型视图,默认值),GL_PROJECTION(投影),GL_TEXTURE(纹理),GL_COLOR(颜色)
    glMatrixMode(GL_PROJECTION);      //选择投影矩阵
    glLoadIdentity();                 //重置投影矩阵 为 单位矩阵

    gluPerspective(60.0, double(w) / h, 0.1, 1000.0);  //建立透视投影

    glMatrixMode(GL_MODELVIEW);       //选择模型矩阵
    glLoadIdentity();                 //重置模型矩阵 为 单位矩阵

}
void QopenGLDemo::paintGL(){
    // 初始化
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存
    glLoadIdentity();  // 重置

    glTranslatef(0, 0, -30);    // 调整绘图坐标
    glRotatef(45.0, 0, -1, 0);  // 绕y轴旋转45度
    glRotatef(45.0, 1, 0, -1);  // 绕向量(1,0,-1) 旋转45度

    // 坐标轴
    float axis_length = 10;
    glLineWidth(5);
    glBegin(GL_LINE_STRIP);
    glColor3f(1, 0, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(axis_length, 0, 0);
    glEnd();
    glFlush();

    glBegin(GL_LINE_STRIP);
    glColor3f(0, 1, 0);
    glVertex3f(0, 0, 0);
    glVertex3f(0, axis_length, 0);
    glEnd();
    glFlush();

    glBegin(GL_LINE_STRIP);
    glColor3f(0, 0, 1);
    glVertex3f(0, 0, 0);
    glVertex3f(0, 0, axis_length);
    glEnd();
    glFlush();

    // 坐标轴箭头  参考官方文档: https://registry.khronos.org/OpenGL-Refpages/gl4/
    GLUquadricObj *objCylinder = gluNewQuadric();
    glPushMatrix();
    glColor3f(0, 0, 1);
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

    glPushMatrix();
    glColor3f(1, 0, 0);
    glRotatef(90, 0, 1, 0);      // 沿着y轴转90度 使得x轴对着原z轴方向
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

    glPushMatrix();
    glColor3f(0, 1, 0);
    glRotatef(-90, 1, 0, 0.0);   // 沿着x轴转90度 使得y轴对着原z轴方向
    glTranslatef(0, 0, axis_length);
    gluCylinder(objCylinder, 0.3, 0.0, 0.3, 100, 1);  // gluCylinder绘制一个沿z轴定向的圆柱体
    glPopMatrix();

    // 画原点 - 白色
    glPointSize(10.0f);
    glBegin(GL_POINTS);
    glColor3f(1, 1, 1);
    glVertex3f(0, 0, 0);
    glEnd();
    glFlush();
}

三、官方文档

3.1 官网地址

官网:https://www.opengl.org/
官方手册(进官网点 Documentation),如下图:

在这里插入图片描述

3.2 官方手册的使用

官方手册好像是没有搜索功能的…
OpenGL 4 Reference Pages中的gluCylinder函数为例:https://registry.khronos.org/OpenGL-Refpages/gl4/

    1. 进入OpenGL 4 Reference Pages手册地址,glu开头的函数点击下图箭头处链接:
      在这里插入图片描述
    1. 继续点击下图箭头处链接,跳转到glu开头的函数:
      在这里插入图片描述
    1. 下滑找到gluCylinder函数点击即可看到其具体的参数:
      在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/316711.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

优化的实时换脸项目——DeepFaceLive

DeepFaceLive是一款基于人工智能技术的换脸工具,可以实现实时面部捕捉和换脸效果。它利用深度学习和计算机视觉算法,能够以惊人的准确度和速度将脸部特征无缝地映射到任何人的脸上。DeepFaceLive的特点是可以实时换脸,让用户通过网络摄像头应…

JVM基础(12)——G1调优

作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 学习必须往深处挖&…

BitMap源码解析

文章目录 前言数据结构添加与删除操作 JDK中BitSet源码解析重要成员属性初始化添加数据清除数据获取数据size和length方法集合操作:与、或、异或优缺点 前言 为什么称为bitmap? bitmap不仅仅存储介质以及数据结构不同于hashmap,存储的key和v…

没啥特长又想搞钱的进:2024副业小项目推荐

利用副业赚钱,绝对不是找个项目就做那么简单。实际上,网上很多副业项目都是看着高大上,做起来还不如送外卖、打零工实在。思路决定出路,你需要的不是具体的副业项目,你需要的是副业思维。 思维一;经验的二次利用比如你…

【iOS】数据持久化(四)之FMDB基本使用

正如我们前面所看到的,原生SQLite API在使用时还是比较麻烦的,于是,开源社区就出现了一系列将SQLite API进行封装的库,其中FMDB的被大多数人所使用 FMDB和SQLite相比较,SQLite比较原始,操作比较复杂&#…

Unity摇杆+键鼠控制位移、旋转

1、位移 首先我们找到两张图片,一个大圆一个小圆,像这样: 结构是这样的: 然后,新建一个场景,用胶囊去做玩家,摄像机在胶囊下,并且在场景中放两个cube作为参照物 像这样搭好后&#…

【电源专题】案例:在EN脚加个电阻就能解决电源下电输出振荡?

案例背景:在某产品上使用一颗升压芯片发现下电输出波形振荡,但此产品并不是第一个使用此升压芯片的。早先此升压芯片使用在其他产品上没有报过这个异常。 分析方法:使用DEMO板,查看标准DEMO板无异常。将异常板卡上的参数与全部换到DEMO板上发现同样存在异常。 推测原因:…

学习就要从简单的开始嘛,开始学一个个人博客吧

做一个个人博客第一步该怎么做? 好多零基础的同学们不知道怎么迈出第一步。 那么,就找一个现成的模板学一学呗,毕竟我们是高贵的Ctrl c v 工程师。 但是这样也有个问题,那就是,那些模板都,太!…

基于ssm的校园预点餐系统(有报告)。Javaee项目。ssm项目。

演示视频: 基于ssm的校园预点餐系统(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Spring Sp…

【Databend】行列转化:一行变多行和简单分列

文章目录 数据准备和需求生成序列和分隔函数根据分隔符变多行JSON 数据简单分列总结 数据准备和需求 行列转化在实际工作中很常见,其中最常见的有一行变多行,有下面一份数据: drop table if exists fact_suject_data; create table if not …

Linux常用命令之tar解压缩文件、uname -a查看系统信息

tar:解压缩 *.Z-------------------compress程序压缩的文件*.gz------------------gzip程序压缩的文件*.bz2-----------------bzip2程序压缩的文件*.tar------------------tar程序打包的数据,并没有压缩*.tar.gz---------------tar程序打包的文件,其中经过gzip的压…

蓝牙音视频远程控制协议(AVRCP) AV/C command格式介绍

零.声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:蓝牙综合介绍 ,主要介绍蓝牙的一些概念,产生背景,发展轨迹,市面蓝牙介绍,以及蓝牙开发板介绍。 第二篇:Trans…

关于lombok插件的使用

在 idea 中有个非常好用的插件 lombok,可以用来在实体类中自动生成 get 、set以及构造方法,下面我们来学习如何使用它: 首先打开settings,按照以下方法: 到 marketplace 中搜索 lombok,我这里已经安装好了…

探索短链接:让网络分享更便捷

短链接是一种将长网址缩短为简洁形式的编码,它在互联网领域具有广泛的应用。本文将从多个方面介绍短链接的原理、类型、优势及应用场景,帮助您深入了解这一重要的网络技术。 短链接 | 一个覆盖广泛主题工具的高效在线平台(amd794.com) https://amd794.…

JavaScript数组全攻略

🧑‍🎓 个人主页:《爱蹦跶的大A阿》 🔥当前正在更新专栏:《VUE》 、《JavaScript保姆级教程》、《krpano》 ​ ​ 目录 ✨ 前言 数组的定义 创建数组 1. 数组字面量 2. Array构造函数 3. Array.of() 4. Arra…

Web后端开发

一、Maven 1.1 简介 1.2 作用 1.3 流程 通过各种插件实现项目的标准化构建。 1.4 安装 1.5 配置环境 1.5.1 当前工程环境 1.5.2 全局环境 1.6 创建 Maven项目 1.7 导入项目 1.8 依赖管理 1.8.1 依赖配置 1.8.2 依赖传递 pom.xml——右键——Diagrams——show dependen…

Maya参考图的导入和层的应用

参考视频:08.参考图的导入和层的应用_哔哩哔哩_bilibili 前视图/右视图模式下导入图形 创建图层 锁定后可以避免图片位置的移动 前视图和右视图要根据参照物对齐 与模型保持一定距离,同时把该参照图添加到图层中 模型可以添加到图层2中

window-nginx注册服务(nginx-1.24.0.zip)

window-nginx注册服务(nginx-1.24.0.zip) 1、下载当前windows版nginx的稳定版本。 https://nginx.org/en/download.html 2、解压到指定目录中,这里解压到D盘根目录,D:\nginx-1.24.0 3、管理员打开命令行,可先进行相关操作,看一下n…

NLP论文阅读记录 - 2023 | EXABSUM:一种新的文本摘要方法,用于生成提取和抽象摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作三.本文方法四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4.6 细粒度分析 五 总结思考 前言 EXABSUM: a new text summarization approach for generating ex…

生产数据不备份,用时两行泪

背景:项目使用pg一主一从,因慢sql导致查询慢,所以想从原本的4核加到16核,联系好运维后,打算先从从库开始操作,机器上的pgsql都正常关闭,然后停止,关机,扩容一切都很顺利&…