Qt OpenGL初探 - 画坐标轴

本文详细介绍了如何在Qt中使用OpenGL模块创建一个3D坐标轴,并展示了关键函数如`paintGL`和`gluCylinder`的使用方法,以及如何参考官方文档进行学习。
摘要由CSDN通过智能技术生成

引言

在这里插入图片描述
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函数点击即可看到其具体的参数:
      在这里插入图片描述
  • 22
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大米粥哥哥

感谢认可!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值