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

embedded/2024/12/4 4:47:12/

树莓派无窗口系统下搭建 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/*

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


http://www.ppmy.cn/embedded/142801.html

相关文章

GaussDB(类似PostgreSQL)常用命令和注意事项

文章目录 前言GaussDB&#xff08;类似PostgreSQL&#xff09;常用命令和注意事项1. 连接到GaussDB数据库2. 查看当前数据库中的所有Schema3. 进入指定的Schema4. 查看Schema下的表、序列、视图5. 查看Schema下所有的表6. 查看表结构7. 开始事务8. 查询表字段注释9. 注意事项&a…

mysql之慢查询设置及日志分析

mysql之慢查询日志分析 1.临时开启慢查询日志2.永久开启慢查询日志 慢查询是指mysql提供的日志记录功能&#xff0c;用来记录执行时间超过设置阈值的sql语句&#xff0c;并将信息写入到日志文件中&#xff1b; 1.临时开启慢查询日志 注意&#xff1a; 1.以下命令需要连接进入到…

前端面试热门题(二)[html\css\js\node\vue)

Vue 性能优化的方法 Vue 性能优化的方法多种多样&#xff0c;以下是一些常用的策略&#xff1a; 使用v-show替换v-if&#xff1a;v-show是通过CSS控制元素的显示与隐藏&#xff0c;而v-if是通过操作DOM来控制元素的显示与隐藏&#xff0c;频繁操作DOM会导致性能下降。因此&am…

后端-mybatis的一对多

分类表和菜单表是一对多的关系&#xff0c;菜单表对分类表是一对一的关系&#xff0c;我们拿前者来写一对多。 在分类表中加上一行属性list集合 最好new一下 写查询方法 写查询的sql语句 写分类表中普通字段的映射 写菜单表的字段映射&#xff0c;是集合。使用collection标…

数据结构判断两棵树是否相等

算法思想 判断两棵二叉树是否相等&#xff0c;主要有以下几个步骤&#xff1a; 递归比较&#xff1a;如果两棵树的根节点的数据相等&#xff0c;则继续递归地比较左右子树。递归终止条件&#xff1a; 如果两棵树都为空&#xff0c;则认为它们相等。如果一棵树为空&#xff0c…

【NLP】第四章:门控循环单元GRU

四、门控循环单元GRU 建议看本篇时&#xff0c;一定一定要把前面的LSTM先看看&#xff1a;【NLP】第三章&#xff1a;长短期记忆网络LSTM-CSDN博客 ,当你对LSTM的各个方面的细节都清晰了&#xff0c;GRU就是闭眼就会的&#xff0c;就是秒懂的&#xff0c;而且以后你再听到什么…

.net core 创建linux服务,并实现服务的自我更新

目录 创建服务创建另一个服务&#xff0c;用于执行更新操作给你的用户配置一些systemctl命令权限 创建服务 /etc/systemd/system下新建服务配置文件&#xff1a;yourapp.service&#xff0c;内容如下&#xff1a; [Unit] Descriptionyourapp Afternetwork.target[Service] Ty…

架构03-事务处理

零、文章目录 架构03-事务处理 1、本地事务实现原子性和持久性 &#xff08;1&#xff09;事务类型 **本地事务&#xff1a;**单个服务、单个数据源**全局事务&#xff1a;**单个服务、多个数据源**共享事务&#xff1a;**多个服务、单个数据源**分布式事务&#xff1a;**多…