wayland(xdg_wm_base) + egl + opengles 最简实例(一)

这篇具有很好参考价值的文章主要介绍了wayland(xdg_wm_base) + egl + opengles 最简实例(一)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

`本文主要介绍如何在linux 下,基于xdg_wm_base 接口的 wayland client 中 使用 egl + opengles 渲染一个最基本的三角形
软硬件环境:
硬件:PC
软件:
ubuntu22.04
EGL1.4
openGL ES3.1
weston9.0


一、ubuntu 下相关环境准备

1. 获取 xdg_wm_base 依赖的相关文件

之前的文章 weston 源码下载及编译 介绍了如何在ubuntu 22.04 下面编译 weston9.0 ,在编译结束后,在build 目录下会生成 xdg-shell-protocol.cxdg-shell-client-protocol.h 这两个文件,如下图所示
eglwayland client,EGL/OpenGL ES,weston/wayland,opengles,egl,wayland
xdg-shell-protocol.cxdg-shell-client-protocol.h 这两个文件就是使用 xdg_wm_base 时所依赖的,这里就直接从weston9.0的目录下获取了,当然也可以使用wayland 相关的命令(wayland-scanner)去操作对应的.xml 文件来生成它们。

(wayland-scanner)是一个用于生成Wayland协议代码的工具。它是Wayland项目的一部分,用于根据XML描述文件生成C语言代码,以便在应用程序中使用Wayland协议。
Wayland-Scanner工具的用途是将Wayland协议的XML描述文件转换为可供应用程序使用的C语言代码。这些代码包括客户端和服务器端的接口定义、消息处理函数、数据结构等。通过使用Wayland-Scanner,开发人员可以根据自定义的Wayland协议描述文件生成所需的代码,从而实现与Wayland服务器的通信

2. 查看 ubuntu 上安装的opengles 版本

使用 glxinfo | grep “OpenGL ES” 可以查看 ubuntu 上所安装的opengles 的版本,如下图所示,代表当前 ubuntu (ubuntu22.04)上安装的是opengles版本是 opengles3.1
eglwayland client,EGL/OpenGL ES,weston/wayland,opengles,egl,wayland

3. 查看 weston 所支持的 窗口shell 接口种类

直接执行 weston-info(后面会被wayland-info 命令取代) 命令,如下图所示,可以看到,当前ubuntu(ubuntu22.04)上所支持的窗口 shell 接口种类,其中就有 xdg_wm_base, zxdg_shell_v6 等,但是没有 wl_shell , 所以从这可以看出,wl_shell 确实已经在ubuntu22.04 上废弃使用了。
eglwayland client,EGL/OpenGL ES,weston/wayland,opengles,egl,wayland

二、xdg_wm_base 介绍

  • xdg_wm_base是由XDG组织定义的Wayland协议接口之一,它提供了一种标准化的方法,使得窗口管理器和应用程序能够进行互动;
  • xdg_wm_base定义了与窗口管理器交互的基本功能,如创建新窗口、设置窗口标题、最大化和最小化窗口等;
  • 它鼓励窗口管理器使用更加灵活和自由的方式来处理窗口管理任务;
  • xdg_wm_base和 wl_shell 都是Wayland协议的一部分,用于定义窗口管理器(Window Manager)与应用程序之间的通信接口。它们之间的区别在于设计理念和功能,xdg_wm_base提供了更加灵活和标准化的窗口管理器接口,窗口管理器可以根据需要实现更多的功能;

三、egl_wayland_demo

1.egl_wayland_demo2_0.c

使用 opengles2.x 接口的 egl_wayland_demo2_0.c 代码如下

#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>
#include "xdg-shell-client-protocol.h"

#define WIDTH 640
#define HEIGHT 480

struct window {
   
    struct wl_display *display;
    struct wl_compositor *compositor;
    struct xdg_wm_base *wm_base;
    struct wl_registry *registry;
    struct wl_surface *surface;
    struct xdg_surface *xdg_surface;
    struct xdg_toplevel *xdg_toplevel;
    struct wl_egl_window *egl_window;
};

// Index to bind the attributes to vertex shaders
const unsigned int VertexArray = 0;

static void
xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
{
   
	xdg_wm_base_pong(shell, serial);
}

static const struct xdg_wm_base_listener wm_base_listener = {
   
	xdg_wm_base_ping,
};

/*for registry listener*/
static void registry_add_object(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 
{
   
	struct window *window = (struct window *)data;

    if (!strcmp(interface, "wl_compositor")) {
   
        window->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
    } else if (strcmp(interface, "xdg_wm_base") == 0) {
   
        window->wm_base = wl_registry_bind(registry, name,
            &xdg_wm_base_interface, 1);
        xdg_wm_base_add_listener(window->wm_base, &wm_base_listener, NULL);
    }
}

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};

static void
handle_surface_configure(void *data, struct xdg_surface *surface,
			 uint32_t serial)
{
   
	//struct window *window = data;

	xdg_surface_ack_configure(surface, serial);
}

static const struct xdg_surface_listener xdg_surface_listener = {
   
	handle_surface_configure
};

static void
handle_toplevel_configure(void *data, struct xdg_toplevel *toplevel,
			  int32_t width, int32_t height,
			  struct wl_array *states)
{
   
}

static void
handle_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
{
   
}

static const struct xdg_toplevel_listener xdg_toplevel_listener = {
   
	handle_toplevel_configure,
	handle_toplevel_close,
};

bool initWaylandConnection(struct window *window)
{
   	
	if ((window->display = wl_display_connect(NULL)) == NULL)
	{
   
		printf("Failed to connect to Wayland display!\n");
		return false;
	}

	if ((window->registry = wl_display_get_registry(window->display)) == NULL)
	{
   
		printf("Faield to get Wayland registry!\n");
		return false;
	}

	wl_registry_add_listener(window->registry, &registry_listener, window);
	wl_display_dispatch(window->display);

	if (!window->compositor)
	{
   
		printf("Could not bind Wayland protocols!\n");
		return false;
	}

	return true;
}

bool initializeWindow(struct window *window)
{
   
	initWaylandConnection(window);
	window->surface = wl_compositor_create_surface (window->compositor);
	window->xdg_surface = xdg_wm_base_get_xdg_surface(window->wm_base, window->surface);
    if (window->xdg_surface == NULL)
    {
   
        printf("Failed to get Wayland xdg surface\n");
        return false;
    } else {
   
        xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window);
        window->xdg_toplevel =
            xdg_surface_get_toplevel(window->xdg_surface);
        xdg_toplevel_add_listener(window->xdg_toplevel,
            &xdg_toplevel_listener, window);
        xdg_toplevel_set_title(window->xdg_toplevel, "egl_wayland_demo");
    }
	return true;
}

void releaseWaylandConnection(struct window *window)
{
   
    if(window->xdg_toplevel)
        xdg_toplevel_destroy(window->xdg_toplevel);
    if(window->xdg_surface)
	    xdg_surface_destroy(window->xdg_surface);
	wl_surface_destroy(window->surface);
    wl_egl_window_destroy(window->egl_window);
	xdg_wm_base_destroy(window->wm_base);
	wl_compositor_destroy(window->compositor);
	wl_registry_destroy(window->registry);
	wl_display_disconnect(window->display);
}

bool createEGLSurface(EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface *eglSurface, struct window *window)
{
   

	window->egl_window = wl_egl_window_create(window->surface, WIDTH, HEIGHT);
	if (window->egl_window == EGL_NO_SURFACE) {
    
		printf("Can't create egl window\n"); 
		return false;
	} else {
   
		printf("Created wl egl window\n");
	}

	*eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, window->egl_window, NULL);
	
	return true;
}

bool opengles_init(GLuint *shaderProgram)
{
   
	GLuint fragmentShader = 0;
	GLuint vertexShader = 0;
	char msg[1000];
	GLsizei len;


	const char* const fragmentShaderSource = 
		"precision mediump float;\n"
		"void main()\n"
		"{\n"
		"   gl_FragColor = vec4 (1.0,0.0,0.0,1.0);\n"
		"}\n";


	// Create a fragment shader object
	fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

	// Load the source code into it
	glShaderSource(fragmentShader, 1, (const char**)&fragmentShaderSource, NULL);
	
	// Compile the source code
	glCompileShader(fragmentShader);

	// Check that the shader compiled
	GLint isShaderCompiled;
	glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isShaderCompiled);
	if (!isShaderCompiled)
	{
   
		// If an error happened, first retrieve the length of the log message
		glGetShaderInfoLog(fragmentShader, sizeof msg, &len, msg);
		fprintf(stderr, "Error: compiling %s: %.*s\n", "fragment", len, msg);
		return false;
	}

	// Vertex shader code
	const char* const vertexShaderSource =		
		"attribute vec4 vPosition; \n"
		"void main()\n"
		"{\n"
		"   gl_Position = vPosition;\n"
		"}\n";

	// Create a vertex shader object
	vertexShader = glCreateShader(GL_VERTEX_SHADER);

	// Load the source code into the shader
	glShaderSource(vertexShader, 1, (const char**)&vertexShaderSource, NULL);

	// Compile the shader
	glCompileShader(vertexShader);

	// Check the shader has compiled
	glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isShaderCompiled);
	if (!isShaderCompiled)
	{
   
		// If an error happened, first retrieve the length of the log message
		glGetShaderInfoLog(vertexShader, sizeof msg, &len, msg);
		fprintf(stderr, "Error: compiling %s: %.*s\n", "vertex", len, msg);
		return false;
	}

	// Create the shader program
	*shaderProgram = glCreateProgram();

	// Attach the fragment and vertex shaders to it
	glAttachShader(*shaderProgram, fragmentShader);
	glAttachShader(*shaderProgram, vertexShader);

	// Bind the vertex attribute "myVertex" to location VertexArray (0)
	glBindAttribLocation(*shaderProgram, VertexArray, "vPosition");

	// Link the program
	glLinkProgram(*shaderProgram);

	// After linking the program, shaders are no longer necessary
	glDeleteShader(vertexShader);
	glDeleteShader(fragmentShader);

	// Check if linking succeeded in the same way we checked for compilation success
	GLint isLinked;
	glGetProgramiv(*shaderProgram, GL_LINK_STATUS, &isLinked);

	if (!isLinked)
	{
   
		// If an error happened, first retrieve the length of the log message
		glGetProgramInfoLog(*shaderProgram, sizeof msg, &len, msg);
		fprintf(stderr, "Error: compiling %s: %.*s\n", "linkprogram", len, msg);
		return false;
	}

	//	Use the Program
	glUseProgram(*shaderProgram);

	return true;
}
bool renderScene(EGLDisplay eglDisplay, EGLSurface eglSurface)
{
   
	GLfloat vVertices[] = {
   0.0f,0.5f,0.0f,			//vertex pointer
		-0.5f,-0.5f,0.0f,
		0.5f,-0.5f,0.0f};

	glViewport(0, 0, WIDTH, HEIGHT);			//set the view port
	glClearColor(0.00f, 0.70f, 0.67f, 1.0f);		//set rgba value for backgroud 
	glClear(GL_COLOR_BUFFER_BIT);


	glEnableVertexAttribArray(VertexArray);
	glVertexAttribPointer(VertexArray, 3, GL_FLOAT, GL_FALSE, 0, vVertices);
	glDrawArrays(GL_TRIANGLES, 0, 3);			//draw a triangle

	if (!eglSwapBuffers(eglDisplay, eglSurface))
	{
   
		return false;
	}

	return true;

}

void deInitializeGLState(GLuint shaderProgram)
{
   
	// Frees the OpenGL handles for the program
	glDeleteProgram(shaderProgram);
}

void releaseEGLState(EGLDisplay eglDisplay, EGLSurface eglSurface, EGLContext context)
{
   
	if (eglDisplay != NULL)
	{
   
		// To release the resources in the context, first the context has to be released from its binding with the current thread.
		eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

        // To release the context
        eglDestroyContext(eglDisplay, context);

        // To release eglSurface
        eglDestroySurface(eglDisplay, eglSurface);

		// Terminate the display, and any resources associated with it (including the EGLContext)
		eglTerminate(eglDisplay);
	}
}



int main()
{
   
	/* EGL variables*/
	EGLDisplay eglDisplay;
	EGLConfig eglConfig;
	EGLSurface eglSurface;
	EGLContext context;
	struct window window;

	//wayland client init
	if(!initializeWindow(&window))
	{
   
		printf("initializeWindow failed\n");
		return -1;
	}

	//egl init	
	eglDisplay = eglGetDisplay(window.display);
	if (eglDisplay == EGL_NO_DISPLAY)
	{
   
		printf("Failed to get an EGLDisplay\n");
		return -1;
	}

	EGLint eglMajorVersion = 0;
	EGLint eglMinorVersion = 0;
    if (!eglInitialize(eglDisplay, &eglMajorVersion, &eglMinorVersion))
    {
   
        printf("Failed to initialize the EGLDisplay\n");
        return -1;
    } else {
   
        printf(" EGL%d.%d\n", eglMajorVersion, eglMinorVersion);
        printf(" EGL_CLIENT_APIS: %s\n", eglQueryString(eglDisplay, EGL_CLIENT_APIS));
        printf(" EGL_VENDOR: %s\n", eglQueryString(eglDisplay,  EGL_VENDOR));
        printf(" EGL_VERSION: %s\n", eglQueryString(eglDisplay,  EGL_VERSION));
        printf(" EGL_EXTENSIONS: %s\n", eglQueryString(eglDisplay,  EGL_EXTENSIONS));
    }

    int result = EGL_FALSE;
    result = eglBindAPI(EGL_OPENGL_ES_API);
    if (result != EGL_TRUE) {
    
        printf("eglBindAPI failed\n");
        return -1; 
    }
 
	const EGLint configurationAttributes[] = {
    EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
	EGLint configsReturned;
	if (!eglChooseConfig(eglDisplay, configurationAttributes, &eglConfig, 1, &configsReturned) || (configsReturned != 1))
	{
   
		printf("Failed to choose a suitable config\n");
		return -1;
	}

	EGLint contextAttributes[] = {
    EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
	context = eglCreateContext(eglDisplay, eglConfig, NULL, contextAttributes);

	if(!createEGLSurface(eglDisplay, eglConfig, &eglSurface, &window))
	{
   
		printf("Failed to create EGLSurface\n");
		return -1;
	}

	eglMakeCurrent(eglDisplay, eglSurface, eglSurface, context);
 
    const GLubyte* version = glGetString(GL_VERSION);
    if (version != NULL) {
   
        printf("OpenGL ES version: %s\n", version);
    } else {
   
        printf("Failed to get OpenGL ES version\n");
    }

	// opengles init
	GLuint shaderProgram = 0;
	opengles_init(&shaderProgram);

	// render
    // Renders a triangle for 800 frames using the state setup in the previous function
    for(int i=0; i<800; i++)
    {
   
        wl_display_dispatch_pending(window.display);
        if (!renderScene(eglDisplay, eglSurface))
        {
   
            printf("render failed!\n");
            return -1;
        }
    }

	//clean up
	deInitializeGLState(shaderProgram);

	// Release the EGL State
    releaseEGLState(eglDisplay, eglSurface, context);

	// Release the Wayland connection
	releaseWaylandConnection(&window);

	return 0;
}

2.egl_wayland_demo3_0.c

使用 opengles3.x 接口的 egl_wayland_demo3_0.c 代码如下文章来源地址https://www.toymoban.com/news/detail-828330.html

#include <wayland-client.h>
#include <wayland-server.h>
#include <wayland-egl.h>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xdg-shell-client-protocol.h"

#define WIDTH 640
#define HEIGHT 480

struct window {
   
    struct wl_display *display;
    struct wl_compositor *compositor;
    struct xdg_wm_base *wm_base;
    struct wl_registry *registry;
    struct wl_surface *surface;
    struct xdg_surface *xdg_surface;
    struct xdg_toplevel *xdg_toplevel;
    struct wl_egl_window *egl_window;
};

// Index to bind the attributes to vertex shaders
const unsigned int VertexArray = 0;

static void
xdg_wm_base_ping(void *data, struct xdg_wm_base *shell, uint32_t serial)
{
   
	xdg_wm_base_pong(shell, serial);
}

static const struct xdg_wm_base_listener wm_base_listener = {
   
	xdg_wm_base_ping,
};

/*for registry listener*/
static void registry_add_object(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) 
{
   
	struct window *window = (struct window *)data;</

到了这里,关于wayland(xdg_wm_base) + egl + opengles 最简实例(一)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • wayland(xdg_wm_base) + egl + opengles 纹理贴图进阶实例(四)

    wayland(xdg_wm_base) + egl + opengles 纹理贴图进阶实例(四)

    本文主要介绍如何在一个wayland client 里面使用 egl + opengles 读取一个 pattern 图片数据进行纹理贴图,在阅读本篇文章之前,建议先读一下之前的文章 《wayland(xdg_wm_base) + egl + opengles 最简实例(一)》 软硬件环境 硬件:PC 软件:ubuntu22.04 weston9.0 opengles2.0/3.0 egl1.4 在ubuntu 下执行如下

    2024年02月20日
    浏览(7)
  • wayland(xdg_wm_base) + egl + opengles 使用FBO渲染到纹理实例(六)

    本文主要介绍 如何在 opengles 中使用FBO 实现渲染到纹理的功能 软硬件环境: 硬件:PC 软件:ubuntu22.04 opengles3.0 egl1.4 FBO(Framebuffer Object)是OpenGL的一个扩展,它允许我们将渲染结果直接绘制到一个纹理或者渲染缓冲对象中,而不是默认的帧缓冲。 使用FBO可以实现一些高级的渲

    2024年02月20日
    浏览(15)
  • wayland(xdg_wm_base) + egl + opengles——dma_buf 作为纹理数据源(五)

    wayland(xdg_wm_base) + egl + opengles——dma_buf 作为纹理数据源(五)

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 `本文主要描述如何在一个wayland client 中将一个 dma_buf import 作为一个 opengles texture 数据源 软硬件环境 硬件:aarch64 软件:linux5.10 opengles2.0/3.0 egl1.5 如下图所示,EGL 中 import dma_buf 作为 opengles texture ,主要

    2024年02月20日
    浏览(24)
  • EGL + GBM + OPENGLES 最简实例

    本文主要介绍如何在 linux 下实现一个 egl + gbm + opengles 的最简demo 实例 软硬件环境 硬件:PC 软件:ubuntu18.04 egl1.4 opengles2.0 libgbm libdrm GBM(全称是Generic Buffer Manager)是一个用于管理图形缓冲区的通用接口,主要用于在 Linux 系统上实现图形显示和渲染,是以动态库 libgbm 来进行呈

    2024年01月23日
    浏览(6)
  • qnx 上screen + egl + opengles 最简实例

    qnx 上screen + egl + opengles 最简实例

    本文主要介绍如何在QNX 系统上使用egl和opengles 控制GPU渲染一个三角形并显示到屏幕上,是一个最基础的screen + egl + opengles 使用实例 软件环境: qnx7.1 opengles2.0 egl1.4 linux 上有wayland/weston 窗口系统,而 screen 就是 qnx 上的窗口系统,qnx screen 相关的介绍可以查看 screen 官方文档, 而

    2024年01月22日
    浏览(30)
  • 记录解决运行Qt程序出现警告提示“Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland t”

    记录解决运行Qt程序出现警告提示“Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland t”

    运行Qt程序是出现警告提示“Warning: Ignoring XDG_SESSION_TYPE=wayland on Gnome. Use QT_QPA_PLATFORM=wayland to run on Wayland anyway.”,虽然并不影响程序的运行和显示,但是看着碍眼啊,于是上网搜索了一下解决办法,记录一下 这个警告提示是关于在 Gnome 桌面环境下运行 Qt 程序时的一种提示信

    2024年04月12日
    浏览(15)
  • 【Android OpenGL开发】OpenGL ES与EGL介绍

    【Android OpenGL开发】OpenGL ES与EGL介绍

    OpenGL(Open Graphics Library)是一个跨编程语言、跨平台的编程图形程序接口,主要用于图像的渲染。 Android提供了简化版的OpenGL接口,即OpenGL ES。 早先定义 OpenGL ES 是 OpenGL 的嵌入式设备版本,用于移动端平台(Android、iOS),但由于嵌入式设备要求的是高性能,所以一些其它纯

    2024年02月04日
    浏览(7)
  • wayland 之opengl es

       EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层,它主要由系统制造商实现。 使用 EGL 绘图的基本步骤 Display(EGLDisplay) 是对实际显示设备的抽象。 Surface(EGLSurface)是对用来存储图像的内存区域 FrameBuffer 的抽象,包括 Color Buffer, Sten

    2024年02月09日
    浏览(5)
  • OpenGL ES EGL eglCreateContext

    OpenGL ES EGL eglCreateContext

    目录 一. EGL 前言 二. EGL 绘制流程简介 三.eglCreateContext 函数简介 1.关于属性列表 attribList 2.关于返回值 四.eglCreateContext 函数使用 五.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 OpenGL ES 特效 零基础 Op

    2023年04月08日
    浏览(7)
  • OpenGL ES EGL eglMakeCurrent

    OpenGL ES EGL eglMakeCurrent

    目录 一. EGL 前言 二. EGL 绘制流程简介 三.eglMakeCurrent 函数简介 1.eglMakeCurrent 简介 2.eglMakeCurrent 实现 3.eglMakeCurrent 使用 四.关于多个 EGLContext 五.共享 EGLContext 六.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目

    2024年02月14日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包