wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

文章目录

  • 前言
  • 一、使用 stb_image 库加载纹理图片
    • 1. 获取 stb_image.h 头文件
    • 2. 使用 stb_image.h 中的相关接口加载纹理图片
    • 3. 纹理图片——cordeBouee4.jpg
  • 二、渲染使用纹理贴图的旋转 3D 立方体
    • 1. egl_wayland_texture_cube.c
    • 2. Matrix.h 和 Matrix.c
    • 3. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
    • 4. 编译
    • 5. 运行
  • 三、不使用外部图片的纹理贴图的旋转3d 立方体
    • 1. egl_wayland_texture_cube3_0.c
    • 2. Matrix.h 和 Matrix.c
    • 3. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
    • 4. 编译
    • 5. 运行
  • 总结
  • 参考资料


前言

本文主要介绍如果使用 wayland(xdg_wm_base) + egl + opengles3.0 绘制一个使用纹理贴图的绕Y轴旋转的正方体,涉及纹理图片加载(stb_image.h)等相关知识
软硬件环境:
硬件:PC
软件:ubuntu22.04 egl1.4 opengles3.0 weston9.0


一、使用 stb_image 库加载纹理图片

stb_image 是一个非常轻量级的图像加载库,由 Sean Barrett 创建并维护。这个库以单个头文件的形式存在,可以直接包含到你的项目中,无需额外的编译和链接过程。
通过包含对应的头文件,可以使用 stb_image 来加载各种常见的图片格式,例如 JPEG、PNG 等

1. 获取 stb_image.h 头文件

可以在 stb_image 库github 仓库地址 找到该库的源代码和详细信息
对于本文只需要获取 stb_image.h 这个头文件即可,将stb_image.h 头文件放到自己的工程代码目录下,如下图所示
在这里插入图片描述

2. 使用 stb_image.h 中的相关接口加载纹理图片

在代码中添加 STB_IMAGE_IMPLEMENTATION 宏定义和 #include “stb_image.h”,然后使用 stbi_load() 函数接口加载 JPG图片,加载完成后就会得到图片的分辨率以及像素格式信息,在使用 glTexImage2D() 加载到纹理后,然后使用 stb_image_free() 释放相关的资源,如下代码所示

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

GLuint createTexture(void)
{
   
	GLuint textureId;
	int width, height, nrChannels;

	/* Generate a texture object. */
	glGenTextures(1, &textureId);

	unsigned char* data = stbi_load("./cordeBouee4.jpg", &width, &height, &nrChannels, 0);
	if (data) {
   
		printf("width = %d, height = %d, nrChannels = %d\n", width, height, nrChannels);
		GLenum format;
		if (nrChannels == 1)
			format = GL_RED;
		else if (nrChannels == 3)
			format = GL_RGB;
		else if (nrChannels == 4)
			format = GL_RGBA;

		/* Activate a texture. */
		glActiveTexture(GL_TEXTURE0);
		/* Bind the texture object. */
		glBindTexture(GL_TEXTURE_2D, textureId);
		/* Load the texture. */
		glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
		/* Set the filtering mode. */
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

		stbi_image_free(data);
	} else {
   
		printf("stbi_load picture failed\n");
	}

	return textureId;
}

3. 纹理图片——cordeBouee4.jpg

如下图片就是本文使用的纹理图片——cordeBouee4.jpg
cordeBouee4.jpg

二、渲染使用纹理贴图的旋转 3D 立方体

使用 opengles3.0 渲染一个使用纹理贴图的旋转3D立方体,代码如 egl_wayland_texture_cube.c 所示

1. egl_wayland_texture_cube.c

#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"
#include "Matrix.h"


#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

#define WIDTH 800
#define HEIGHT 600

struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct xdg_wm_base *wm_base = NULL;
struct wl_registry *registry = NULL;

//opengles global var

GLuint projectionLocation;
GLuint modelLocation;
GLuint viewLocation;
GLuint simpleCubeProgram;
GLuint samplerLocation;
GLuint textureId;


float projectionMatrix[16];
float modelMatrix[16];
float viewMatrix[16];
float angleX = 30.0f;
float angleY = 0.0f;
float angleZ = 0.0f;


struct window {
   
	struct wl_surface *surface;
    struct xdg_surface *xdg_surface;
	struct xdg_toplevel *xdg_toplevel;
	struct wl_egl_window *egl_window;
};

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

/*for xdg_wm_base listener*/
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) 
{
   
    if (!strcmp(interface, "wl_compositor")) {
   
        compositor = wl_registry_bind(registry, name, &wl_compositor_interface, 1);
    } else if (strcmp(interface, "xdg_wm_base") == 0) {
   
        wm_base = wl_registry_bind(registry, name,
            &xdg_wm_base_interface, 1);
        xdg_wm_base_add_listener(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);

	//window->wait_for_configure = false;
}

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()
{
   	
	if ((display = wl_display_connect(NULL)) == NULL)
	{
   
		printf("Failed to connect to Wayland display!\n");
		return false;
	}

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

	wl_registry_add_listener(registry, &registry_listener, NULL);
	wl_display_dispatch(display);

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

	return true;
}

bool initializeWindow(struct window *window)
{
   
	initWaylandConnection();
	window->surface = wl_compositor_create_surface (compositor);
	window->xdg_surface = xdg_wm_base_get_xdg_surface(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_texture");
    }

	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);
    xdg_wm_base_destroy(wm_base);
    wl_compositor_destroy(compositor);
    wl_registry_destroy(registry);
    wl_display_disconnect(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;
}


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

void releaseEGLState(EGLDisplay eglDisplay)
{
   
	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);

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


//"    gl_Position = projection * modelView * vec4(vertexPosition, 1.0);\n"
static const char  glVertexShader[] 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/455417.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Nacos 集群搭建

1 . 集群结构图 : 其中包括3个nacos结点&#xff0c;然后一个负载均衡器代理3个Nacos。这里负载均衡器可以使用nginx ; 我们计划的集群结构 : 三个nacos结点的地址 : 节点ipportnacos1192.168.150.18845nacos2192.168.150.18846nacos3192.168.150.18847 2 . 搭建集群 搭…

LeetCode 2864. 最大二进制奇数

文章目录 LeetCode 2864. 最大二进制奇数思路1AC CODE思路2AC CODE LeetCode 2864. 最大二进制奇数 题目链接&#xff1a;https://leetcode.cn/problems/maximum-odd-binary-number/description/ 思路1 由于二进制基数的最后一位必须是1&#xff0c;而其他位越大越好&#xf…

激活函数Mish

paper&#xff1a;Mish: A Self Regularized Non-Monotonic Activation Function official implementation&#xff1a;https://github.com/digantamisra98/Mish 背景 在早期文献中&#xff0c;Sigmoid和TanH激活函数被广泛使用&#xff0c;随后在深度神经网络中失效。相比于…

【小沐学C#】C#文件读写方式汇总

文章目录 1、简介2、相关类介绍3、代码示例3.1 FileStream&#xff08;流文件&#xff09;3.2 StreamReader / StreamWriter &#xff08;文本文件&#xff09;3.2.1 StreamReader3.2.2 StreamWriter 3.3 BinaryReader / BinaryWriter &#xff08;二进制文件&#xff09;3.3.1…

2024.03.13作业

要求&#xff1a;设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #include <iostream> #includ…

初学MyBatis小结

0 简介 MyBatis官网介绍 MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO&#xff08;P…

C语言分析基础排序算法——归并排序

目录 归并排序 递归版本 非递归版本 非递归版本的问题 归并排序小优化 归并排序 归并排序&#xff0c;分为分治以及合并&#xff0c;分治部分可以使用递归或者非递归完成&#xff0c;归并排序的基本思路是&#xff1a;将已有序的子序列合并&#xff0c;得到完全有序的序列…

qiankun:vite/webpack项目配置

相关博文&#xff1a; https://juejin.cn/post/7216536069285429285?searchId202403091501088BACFF113F980BA3B5F3 https://www.bilibili.com/video/BV12T411q7dq/?spm_id_from333.337.search-card.all.click qiankun结构&#xff1a; 主应用base&#xff1a;vue3historyv…

基于SpringCache实现数据缓存

SpringCache SpringCache是一个框架实现了基本注解的缓存功能,只需要简单的添加一个EnableCaching 注解就能实现缓存功能 SpringCache框架只是提供了一层抽象,底层可以切换CacheManager接口的不同实现类即使用不同的缓存技术,默认的实现是ConcurrentMapCacheManagerConcurren…

中间件 | Kafka - [常见问题]

INDEX 1 为什么快2 消息丢失2.1 消息丢失位置2.2 如何避免消息丢失 3 顺序消费 1 为什么快 kafka使用的是基于文件的顺序存储 代价是只能通过offset标记消费情况并总 partition 数越高&#xff0c;性能越下降&#xff0c;可降低一个数量级 每个 partition 的消息会保存在一个独…

C++day3——类中的成员函数

思维导图&#xff1a; 2、设计一个Per类&#xff0c;类中包含私有成员&#xff1a;姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员&#xff1a;成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #in…

力扣串题:验证回文串2

bool judge(char *s,int m,int n){while(m<n){if(s[m]!s[n]){return false;}m,n--;}return true; } bool validPalindrome(char * s){for(int i0,jstrlen(s)-1;i<j;i,j--){if(s[i]!s[j]){return (judge(s,i1,j)||judge(s,i,j-1));}}return true; }这个题直接背大佬代码吧…

彩虹外链网盘界面UI美化版超级简洁好看

彩虹外链网盘界面UI美化版 彩虹外链网盘&#xff0c;是一款PHP网盘与外链分享程序&#xff0c;支持所有格式文件的上传&#xff0c;可以生成文件外链、图片外链、音乐视频外链&#xff0c;生成外链同时自动生成相应的UBB代码和HTML代码&#xff0c;还可支持文本、图片、音乐、…

Albumentations——广泛应用于工业界、学术界、AI竞赛和开源项目中的CV数据增强工具

Albumentations: fast and flexible image augmentationsDiscover Albumentations: an open-source library offering efficient and customizable image augmentations to boost machine learning and computer vision model performance.https://albumentations.ai/

HM v.16.22 顺序读源码day1---encmain.cpp

文章目录 encmain.cpp引入的库执行主体1. 读取输入的配置文件2. 编码启动和过程计时 实现细节1. cTAppEncTop.parseCfg( argc, argv )&#xff1b;2. df::program_options_lite::ParseFailure;3. EnvVar::printEnvVar();4. EnvVar::printEnvVarInUse();5. printMacroSettings()…

plt保存PDF矢量文件中嵌入可编辑字体(可illustrator编辑)

背景&#xff1a; 用默认 plt.savefig() 保存图片&#xff0c;图中文字是以瞄点保存&#xff0c;而不是以文字格式。在编辑矢量图中&#xff0c;无法调整文字大小和字体。 方法&#xff1a; import matplotlib.pyplot as plt import numpy as np# ------输出的图片为illustr…

RabbitMQ备份交换机与优先级队列

1. 备份交换机 备份交换机可以理解为 RabbitMQ 中交换机的“备胎”&#xff0c;当我们为某一个交换机声明一个对应的备份交换机时&#xff0c;就是为它创建一个备胎&#xff0c;当交换机接收到一条不可路由消息时&#xff0c;将会把这条消息转发到备份交换机中&#xff0c;由备…

数据仓库的基本概念、基本特征、体系结构

个人看书学习心得及日常复习思考记录&#xff0c;个人随笔。 数据仓库的基本概念、基本特征 数据仓库的定义&#xff1a;数据仓库是一个面向主题的、集成的、不可更新的、随时间不断变化的数据集合&#xff0c;用以更好地支持企业或组织的决策分析处理。 数据仓库中数据的4个…

26-Java访问者模式 ( Visitor Pattern )

Java访问者模式 摘要实现范例 访问者模式&#xff08;Visitor Pattern&#xff09;使用了一个访问者类&#xff0c;它改变了元素类的执行算法&#xff0c;通过这种方式&#xff0c;元素的执行算法可以随着访问者改变而改变访问者模式中&#xff0c;元素对象已接受访问者对象&a…

Unity2019.2.x 导出apk 安装到安卓Android12+及以上的系统版本 安装出现-108 安装包似乎无效的解决办法

Unity2019.2.x 导出apk 安装到安卓Android12及以上的系统版本 安装出现-108 安装包似乎无效的解决办法 导出AndroidStudio工程后 需要设置 build.gradle文件 // GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAINbuildscript {repositor…
最新文章