当前位置: 首页 > news >正文

嵌入式Linux(SOC带GPU树莓派)无窗口系统下搭建 OpenGL ES + Qt 开发环境,并绘制旋转金字塔

树莓派无窗口系统下搭建 OpenGL ES + Qt 开发环境,并绘制旋转金字塔

1. 安装 OpenGL ES 开发环境

运行以下命令安装所需的 OpenGL ES 开发工具和库:

sudo apt install cmake mesa-utils libegl1-mesa-dev libgles2-mesa-dev libdrm-dev libgbm-dev

2. 安装 Qt 开发环境

安装 Qt 的核心开发库:

sudo apt install -y qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qtdeclarative5-dev qml-module-qtquick2

3. 配置 Qt 使用 EGL 和 GBM(无窗口模式)

使用 EGLFS(EGL Fullscreen)插件

EGLFS 插件可以在没有窗口管理器的环境下直接使用 OpenGL 渲染。

  1. 确认系统支持 EGLFS

    ls /usr/lib/arm-linux-gnueabihf/qt5/plugins/platforms/libqeglfs.so
    

    如果存在 libqeglfs.so,表示系统支持 EGLFS。

  2. 设置环境变量启用 EGLFS

    export QT_QPA_PLATFORM=eglfs
    

    使用 GBM 后台支持:

    export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
    

    或者切换到 Framebuffer(可选):

    export QT_QPA_PLATFORM=linuxfb
    

4. 编写并运行 Qt 项目代码

创建项目目录和文件
mkdir qt-opengl-example
cd qt-opengl-example
  1. main.cpp

    #include <QApplication>
    #include <QMainWindow>
    #include "openglwidget.h"int main(int argc, char *argv[]) {QApplication app(argc, argv);QMainWindow window;OpenGLWidget *widget = new OpenGLWidget();window.setCentralWidget(widget);window.setWindowTitle("OpenGL ES Rotating Pyramid");window.resize(800, 600);window.show();return app.exec();
    }
    
  2. openglwidget.h

    #ifndef OPENGLWIDGET_H
    #define OPENGLWIDGET_H#include <QOpenGLWidget>
    #include <QOpenGLFunctions>
    #include <QTimer>class OpenGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
    {Q_OBJECTpublic:explicit OpenGLWidget(QWidget *parent = nullptr);~OpenGLWidget();protected:void initializeGL() override;void resizeGL(int w, int h) override;void paintGL() override;void timerEvent(QTimerEvent *event) override;private:float rotationAngle;
    };#endif // OPENGLWIDGET_H
  3. openglwidget.cpp

    #include "openglwidget.h"
    #include <QOpenGLShaderProgram>
    #include <QOpenGLBuffer>
    #include <QOpenGLVertexArrayObject>
    #include <QMatrix4x4>
    #include <QtMath>OpenGLWidget::OpenGLWidget(QWidget *parent) :QOpenGLWidget(parent), rotationAngle(0.0f)
    {setAutoFillBackground(false);  // 不自动填充背景,交给OpenGL渲染startTimer(10);// 启动定时器,每隔0.01秒触发
    }OpenGLWidget::~OpenGLWidget()
    {
    }void OpenGLWidget::initializeGL()
    {initializeOpenGLFunctions();glClearColor(0.0f, 0.0f, 0.0f, 1.0f);  // 设置清屏颜色glEnable(GL_DEPTH_TEST);  // 启用深度测试
    }void OpenGLWidget::resizeGL(int w, int h)
    {glViewport(0, 0, w, h);
    }void OpenGLWidget::paintGL()
    {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // 清除颜色和深度缓冲// 定义金字塔的顶点数据GLfloat vertices[] = {// 底面-0.5f, -0.5f, -0.5f,  // 顶点10.5f, -0.5f, -0.5f,  // 顶点20.5f, -0.5f,  0.5f,  // 顶点3-0.5f, -0.5f,  0.5f,  // 顶点4// 顶面0.0f,  0.5f,  0.0f   // 顶点5};// 定义金字塔的索引GLuint indices[] = {0, 1, 4,  // 底面与顶面连接的三角形1, 2, 4,  // 底面与顶面连接的三角形2, 3, 4,  // 底面与顶面连接的三角形3, 0, 4,  // 底面与顶面连接的三角形0, 1, 2,  // 底面三角形2, 3, 0   // 底面三角形};// 创建并绑定着色器程序QOpenGLShaderProgram program;program.addShaderFromSourceCode(QOpenGLShader::Vertex,"#version 300 es\n""in vec3 position;\n""uniform mat4 modelViewProjectionMatrix;\n""void main() {\n""   gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);\n""}");program.addShaderFromSourceCode(QOpenGLShader::Fragment,"#version 300 es\n""precision mediump float;\n""out vec4 fragColor;\n""void main() {\n""   fragColor = vec4(1.0, 0.5, 0.0, 1.0);  // 金字塔颜色:橙色\n""}");program.link();program.bind();// 创建顶点数组对象和顶点缓冲对象GLuint vao, vbo, ebo;glGenVertexArrays(1, &vao);glBindVertexArray(vao);glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);glGenBuffers(1, &ebo);glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);GLint posAttrib = program.attributeLocation("position");program.enableAttributeArray(posAttrib);glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);// 创建一个模型视图投影矩阵QMatrix4x4 projection;projection.perspective(45.0f, (float)width() / height(), 0.1f, 100.0f);projection.translate(0.0f, 0.0f, -3.0f);  // 将物体向远离观察者的方向移动QMatrix4x4 modelView;modelView.rotate(rotationAngle, 0.0f, 1.0f, 0.0f);  // 水平旋转金字塔QMatrix4x4 modelViewProjectionMatrix = projection * modelView;// 将 MVP 矩阵传递给着色器program.setUniformValue("modelViewProjectionMatrix", modelViewProjectionMatrix);// 绘制金字塔glDrawElements(GL_TRIANGLES, 18, GL_UNSIGNED_INT, nullptr);glBindVertexArray(0);
    }void OpenGLWidget::timerEvent(QTimerEvent *event)
    {rotationAngle += 1.0f;  // 增加旋转角度if (rotationAngle >= 360.0f)rotationAngle = 0.0f;update();  // 触发重绘
    }
  4. 创建项目文件并编译运行

    qmake -project
    echo "QT += core gui widgets opengl" >> qt-opengl-example.pro
    qmake
    make
    ./qt-opengl-example
    

5. 调试与优化

启用调试日志
export QT_LOGGING_RULES="qt.qpa.*=true"
权限问题

确保当前用户有权限访问 /dev/fb0/dev/dri/*

sudo chmod a+rw /dev/fb0
sudo chmod a+rw /dev/dri/*

完成后,你的金字塔应用程序将在树莓派的无窗口系统中运行并水平旋转!

相关文章:

嵌入式Linux(SOC带GPU树莓派)无窗口系统下搭建 OpenGL ES + Qt 开发环境,并绘制旋转金字塔

树莓派无窗口系统下搭建 OpenGL ES Qt 开发环境&#xff0c;并绘制旋转金字塔 1. 安装 OpenGL ES 开发环境 运行以下命令安装所需的 OpenGL ES 开发工具和库&#xff1a; sudo apt install cmake mesa-utils libegl1-mesa-dev libgles2-mesa-dev libdrm-dev libgbm-dev2. 安…...

webGL入门教程_06变换矩阵与绕轴旋转总结

变换矩阵与绕轴旋转总结 目录 1. 变换矩阵简介2. 平移矩阵3. 缩放矩阵4. 旋转矩阵 4.1 绕 Z 轴旋转4.2 绕 X 轴旋转4.3 绕 Y 轴旋转 5. 组合变换矩阵6. 结论 1. 变换矩阵简介 在计算机图形学中&#xff0c;变换矩阵用于在三维空间中对物体进行操作&#xff0c;包括&#xff…...

生成树详解(STP、RSTP、MSTP)

目录 1、STP 1.概述 2.基本概念 3.端口角色及其作用 4.报文结构 5.STP的端口状态 6.三种定时器 7.STP选举步骤 8.配置BPDU的比较原则 9.TCN BPDU 10.临时环路的问题 11.传统STP的不足 拓扑变更处理过程 2、RSTP 1.端口角色 2.端口状态 3.P/A&#xff08;Propo…...

【QNX+Android虚拟化方案】128 - QNX 侧触摸屏驱动解析

【QNX+Android虚拟化方案】128 - QNX 侧触摸屏驱动解析 一、QNX 侧触摸屏配置基于原生纯净代码,自学总结 纯技术分享,不会也不敢涉项目、不泄密、不传播代码文档!!! 本文禁止转载分享 !!! 汇总链接:《【QNX+Android虚拟化方案】00 - 系列文章链接汇总》 本文链接:《【…...

C#中的集合初始化器

C#中的集合初始化器是一种简洁的语法&#xff0c;允许在声明集合的同时初始化其元素。这种语法特别适用于初始化实现了IEnumerable接口并具有Add方法的集合类型&#xff0c;如List<T>、Dictionary<TKey, TValue>等。 集合初始化器的基本用法 集合初始化器的基本语…...

cartographer建图与定位应用

文章目录 前言一、安装cartographer1.安装环境2.源码编译2.1 下载2.2 编译 二、gazebo仿真2d建图0.准备仿真环境1.编写lua文件2.编写启动文件3.建图保存 三、cartographer定位 move_base导航3.1 编写启动文件3.2 启动launch 总结 前言 本文介绍cartographer在ubuntu18.04下的…...

专业解析 .bashrc 中 ROS 工作空间的加载顺序及其影响 ubuntu 机器人

专业解析 .bashrc 中 ROS 工作空间的加载顺序及其影响 在使用 ROS&#xff08;Robot Operating System&#xff09;进行开发时&#xff0c;通常会涉及多个 Catkin 工作空间&#xff08;Catkin Workspace&#xff09;。这些工作空间包含不同的 ROS 包和节点&#xff0c;可能相互…...

Apache Doris 现行版本 Docker-Compose 运行教程

特别注意&#xff01;Doris On Docker 部署方式仅限于开发环境或者功能测试环境&#xff0c;不建议生产环境部署&#xff01; 如有生产环境或性能测试集群部署诉求&#xff0c;请使用裸机/虚机部署或K8S Operator部署方案&#xff01; 原文阅读&#xff1a;Apache Doris 现行版…...

Flink四大基石之窗口(Window)使用详解

目录 一、引言 二、为什么需要 Window 三、Window 的控制属性 窗口的长度&#xff08;大小&#xff09; 窗口的间隔 四、Flink 窗口应用代码结构 是否分组 Keyed Window --键控窗 Non-Keyed Window 核心操作流程 五、Window 的生命周期 分配阶段 触发计算 六、Wi…...

NGINX配置https双向认证(自签一级证书)

一 生成自签证书 以下是生成自签证书(包括服务端和客户端的证书)的步骤&#xff0c;以下命令执行两次&#xff0c;分别生成客户端和服务端证书和私钥。具体执行可以先建两个目录client和server&#xff0c;分别进入到这两个目录下执行下面的命令。 生成私钥&#xff1a; 首先&…...

Flink双流Join

在离线 Hive 中&#xff0c;我们经常会使用 Join 进行多表关联。那么在实时中我们应该如何实现两条流的 Join 呢&#xff1f;Flink DataStream API 为我们提供了3个算子来实现双流 join&#xff0c;分别是&#xff1a; join coGroup intervalJoin 下面我们分别详细看一下这…...

【数据结构实战篇】用C语言实现你的私有队列

&#x1f3dd;️专栏&#xff1a;【数据结构实战篇】 &#x1f305;主页&#xff1a;f狐o狸x 在前面的文章中我们用C语言实现了栈的数据结构&#xff0c;本期内容我们将实现队列的数据结构 一、队列的概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端…...

基于web的海贼王动漫介绍 html+css静态网页设计6页+设计文档

&#x1f4c2;文章目录 一、&#x1f4d4;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站演示 五、⚙️网站代码 &#x1f9f1;HTML结构代码 &#x1f492;CSS样式代码 六、&#x1f527;完整源码下载 七、&#x1f4e3;更多 一、&#…...

2022 年 9 月青少年软编等考 C 语言三级真题解析

目录 T1. 课程冲突T2. 42 点思路分析T3. 最长下坡思路分析T4. 吃糖果思路分析T5. 放苹果思路分析T1. 课程冲突 此题为 2021 年 9 月三级第一题原题,见 2021 年 9 月青少年软编等考 C 语言三级真题解析中的 T1。 T2. 42 点 42 42 42 是: 组合数学上的第 5 5 5 个卡特兰数字…...

机器学习算法(六)---逻辑回归

常见的十大机器学习算法&#xff1a; 机器学习算法&#xff08;一&#xff09;—决策树 机器学习算法&#xff08;二&#xff09;—支持向量机SVM 机器学习算法&#xff08;三&#xff09;—K近邻 机器学习算法&#xff08;四&#xff09;—集成算法 机器学习算法&#xff08;五…...

计算机科学中的主要协议

1、主要应用层协议&#xff1a; HTTP、FTP、SMTP、POP、IMAP、DNS、TELNET和SSH等 应用层协议的主要功能是支持网络应用&#xff0c;定义了不同应用程序之间的通信规则。它们负责将用户操作转换为网络可以理解的数据格式&#xff0c;并通过传输层进行传输。应用层协议直接与用…...

下载maven 3.6.3并校验文件做md5或SHA512校验

一、下载Apache Maven 3.6.3 Apache Maven 3.6.3 官方下载链接&#xff1a; 二进制压缩包&#xff08;推荐&#xff09;: ZIP格式: https://archive.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.zipTAR.GZ格式: https://archive.apache.org/dist/…...

【Android】View工作原理

View 是Android在视觉上的呈现在界面上Android提供了一套GUI库&#xff0c;里面有很多控件&#xff0c;但是很多时候我们并不满足于系统提供的控件&#xff0c;因为这样就意味这应用界面的同类化比较严重。那么怎么才能做出与众不同的效果呢&#xff1f;答案是自定义View&#…...

TIE算法具体求解-为什么是泊松方程和傅里叶变换

二维泊松方程的通俗理解 二维泊松方程 是偏微分方程的一种形式&#xff0c;通常用于描述空间中某个标量场&#xff08;如位相场、电势场&#xff09;的分布规律。其一般形式为&#xff1a; ∇ 2 ϕ ( x , y ) f ( x , y ) \nabla^2 \phi(x, y) f(x, y) ∇2ϕ(x,y)f(x,y) 其…...

postman中获取随机数、唯一ID、时间日期(包括当前日期增减)截取指定位数的字符等

在Postman中&#xff0c;您可以使用内置的动态变量和编写脚本的方式来获取随机数、唯一ID、时间日期以及截取指定位数的字符。以下是具体的操作方法&#xff1a; 一、postman中获取随机数、唯一ID、时间日期&#xff08;包括当前日期增减&#xff09;截取指定位数的字符等 获取…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题&#xff1a;3564. 季节性销售分析 题目&#xff1a; 表&#xff1a;sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...