文章目录
- 前言
- 一、ubuntu 上相关环境准备
-
- 1. ubuntu 上安装 weston
- 2. 确定ubuntu 上安装的opengles 版本
- 3. 确定安装的 weston 是否支持 wl_shell 接口
- 二、窗口管理器接口 wl_shell 介绍
- 二、代码实例
-
- 1.egl_wayland_demo.c
- 2. 编译和运行
- 2.1 编译
- 2.2 运行
- 总结
- 参考资料
前言
本文主要介绍如何在 linux 下使用 egl + opengles2.0 相关接口渲染一个三角形的 wayland client 最简程序实例
软硬件环境:
硬件:PC
软件:ubuntu18.04, egl1.4 , opengles2.0, weston3.0
一、ubuntu 上相关环境准备
1. ubuntu 上安装 weston
ubuntu上确保已安装weston 程序,如果没有安装,可以使用 sudo apt install weston 命令来安装, 如下图所示
2. 确定ubuntu 上安装的opengles 版本
可以使用 glxinfo | grep “OpenGL ES” 命令来确定 ubuntu 上的 opengles 版本, 如下图所示, 可以看到我的 ubuntu18.04 上 安装的是 opengles2.0
如果提示没有安装 glxinfo 程序,可以使用 sudo apt-get install mesa-utils libgles2-mesa-dev 命令来安装,如下图所示
3. 确定安装的 weston 是否支持 wl_shell 接口
- 先运行 weston ,如下图所示,代表weston 运行成功(weston 版本为3.0.0)
- 运行 weston-info 命令,查看 weston 是否支持 wl_shell
如下图所示,可以看到当前 ubuntu 上安装的 weston 是支持 wl_shell 接口的
二、窗口管理器接口 wl_shell 介绍
- wl_shell 是Wayland协议早期版本中定义的一种窗口管理器接口
- wl_shell 提供了一组固定的窗口管理功能,比如创建新窗口、设置窗口标题和边框、调整窗口大小和位置等;
- wl_shell 的设计相对较简单,适用于基本的窗口管理需求;
- 由于wl_shell 功能有限,不符合所有窗口管理器的需求,因此在后续的Wayland协议中被 xdg_wm_base 取代,从2023.5.19 Ubuntu 22.04.2 LTS开始,wl_shell 就被废弃了;
二、代码实例
1.egl_wayland_demo.c
egl_wayland_demo.c 代码如下,其实质就是一个wayland client(weston 是一个wayland server)
#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WIDTH 640
#define HEIGHT 480
struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct wl_shell *shell = NULL;
struct wl_registry *registry = NULL;
struct window {
struct wl_surface *surface;
struct wl_shell_surface *shell_surface;
struct wl_egl_window *egl_window;
};
// Index to bind the attributes to vertex shaders
const unsigned int VertexArray = 0;
/*for registry listener*/
static void registry_add_object(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
{
if (!strcmp(interface, "wl_compositor")) {
compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
} else if(!strcmp(interface, "wl_shell")) {
shell = wl_registry_bind(registry, name, &wl_shell_interface, 1);
}
}
void registry_remove_object(void *data, struct wl_registry *registry, uint32_t name)
{
}
static struct wl_registry_listener registry_listener = {
registry_add_object, registry_remove_object};
/*for shell surface listener*/
static void shell_surface_ping (void *data, struct wl_shell_surface *shell_surface, uint32_t serial)
{
wl_shell_surface_pong (shell_surface, serial);
}
static void shell_surface_configure (void *data, struct wl_shell_surface *shell_surface, uint32_t edges,