前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2.通过QOpenGLWidget绘制三角形

2.通过QOpenGLWidget绘制三角形

作者头像
诺谦
发布2020-09-27 10:13:57
1.9K0
发布2020-09-27 10:13:57
举报
文章被收录于专栏:Linux驱动Linux驱动

参考:1.opengl绘制三角形

1.QOpenGLWidget的早先版本

QGLWidget是遗留Qt OpenGL模块的一部分,和其他QGL类一样,应该在新的应用程序中避免使用。相反,从Qt 5.4开始,最好使用QOpenGLWidget和QOpenGL类。

如果开发XP平台,由于兼容性问题,Qt5.4(不含)之后的QtOpenglWidget 则不兼容,建议还是用QGLWidget.

2.QOpenGLWidget类是用于呈现OpenGL图形的部件

代码语言:txt
复制
    QOpenGLWidget提供显示集成到Qt应用程序中的OpenGL图形的功能。使用起来非常简单:让类继承它,并像其他QWidget一样使用子类,额外可以选择使用QPainer和标准的OpenGL渲染命令。
代码语言:txt
复制
    QOpenGLWidget提供了三个方便的虚拟函数,子类中重新实现这些函数来执行OpenGL绘制任务:
  • paintGL():渲染OpenGL场景。该函数里面主要绘制部件,比如在全屏视频上面显示滑动条
  • resizeGL ():当窗口尺寸发生变化时被调用,然后会调用paintGL()函数重新绘制一次(并且第一次显示时也会调用resizeGL() )。
  • initializeGL():用于初始化,设置OpenGL要呈现的画面,只在程序开始时运行一次,之后不会再运行。

其中在initializeGL()中初始化具体如下所示:

图片

然后在paintGL()中,每次当我们要绘制不同的物体时,便调用bind()来绑定对象、绘制完后,解绑对象,如果还要绘制下个物体,那么就取出对应的VAO,绑定它,绘制完物体后,再解绑。

3.三角形示例

图片

图片

4.头文件代码

代码语言:javascript
复制
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
 
#include <QMainWindow>
#include <QObject>
#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
class myGlWidget : public QOpenGLWidget , protected QOpenGLFunctions
{
Q_OBJECT
public:
 
myGlWidget(QWidget *parent = nullptr);
protected:
 
void paintGL() ;
void initializeGL() ;
void resizeEvent(QResizeEvent *e) ;
 
 
private:
QOpenGLShaderProgram *program;
 
QOpenGLVertexArrayObject vao;
QOpenGLBuffer vbo;
 
};
 
#endif // MYGLWIDGET_H

5.源文件代码

代码语言:javascript
复制
#include "myglwidget.h"
#include <QtDebug>


//GLSL3.0版本后,废弃了attribute关键字(以及varying关键字),属性变量统一用in/out作为前置关键字
#define GL_VERSION  "#version 330 core\n"

#define GLCHA(x)  #@x           //加单引号,将x变为字符
#define GLSTR(x)  #x            //加双引号,将x变为字符串
#define GET_GLSTR(x) GL_VERSION#x


const char *vsrc = GET_GLSTR(
    layout (location = 0) in vec3 aPos;
    void main(void)
    {
      gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
    }
);

const char *fsrc =GET_GLSTR(
            out vec4 FragColor;
            void main(void)
            {
              FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);
            }
);

//fsrc 等价于 -->   const char *fsrc ="#version 330 core\n"
//                      "out vec4 FragColor;\n"
//                      "void main()\n"
//                      "{\n"
//                      "   FragColor = vec4(1.0f, 1.0f, 0.0f, 1.0f);\n"
//                      "}\n\0";

myGlWidget::myGlWidget(QWidget *parent):QOpenGLWidget(parent)
{

}


void myGlWidget::paintGL()
{
   // 绘制
  // glViewport(0, 0, width(), height());

   glClear(GL_COLOR_BUFFER_BIT);

   // 渲染Shader
   program->bind(); //绑定激活Program对象
   vao.bind();      //绑定激活vao
   glDrawArrays(GL_TRIANGLES, 0, 3);    //绘制3个定点,样式为三角形
   vao.release();       //解绑
   program->release();  //解绑

}
void myGlWidget::initializeGL()
{

   // 为当前环境初始化OpenGL函数
   initializeOpenGLFunctions();

   glClearColor(1.0f, 1.0f, 1.0f, 1.0f);    //设置背景色为白色

   //1.创建顶点着色器
   QOpenGLShader *vshader = new QOpenGLShader(QOpenGLShader::Vertex, this);
   vshader->compileSourceCode(vsrc);

   //2.创建片元着色器 rgba(1.0f, 1.0f, 0.0f, 1.0f)表示黄色,而alpha值为1.0,表示完全不透明
   QOpenGLShader *fshader = new QOpenGLShader(QOpenGLShader::Fragment, this);
   fshader->compileSourceCode(fsrc);

   //3.创建着色器程序
   program = new QOpenGLShaderProgram;
   program->addShader(vshader);
   program->addShader(fshader);
   program->link();
   program->bind();//激活Program对象


   //4.初始化VBO,将顶点数据存储到buffer中,等待VAO激活后才能释放
   float vertices[] = {
   -0.5f, -0.5f, 0.0f,
   0.5f, -0.5f, 0.0f,
   0.0f, 0.5f, 0.0f
   };

   vbo.create();
   vbo.bind();              //绑定到当前的OpenGL上下文,
   vbo.allocate(vertices, 9*sizeof(GLfloat));
   vbo.setUsagePattern(QOpenGLBuffer::StreamDraw);  //设置为一次修改,多次使用


   //5.初始化VAO,设置顶点数据状态(顶点,法线,纹理坐标等)
   vao.create();
   vao.bind();

   GLint aPos = program->attributeLocation("aPos");        //获取aPos位置
   if(aPos==-1)  //未找到
   {
       return;
   }
   program->setAttributeBuffer(aPos, GL_FLOAT, 0,  3, 0);   //设置顶点属性
   program->enableAttributeArray(aPos); //使能顶点属性


   //6.解绑所有对象
   vao.release();
   vbo.release();
   program->release();


}
void myGlWidget::resizeEvent(QResizeEvent *e)
{


}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档