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 600struct wl_display *display = NULL;
struct wl_compositor *compositor = NULL;
struct xdg_wm_base *wm_base = NULL;
struct wl_registry *registry = NULL;//opengles global varGLuint 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 programglDeleteProgram(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.rhkb.cn/news/280134.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

浅谈大模型“幻觉”问题

大模型的幻觉大概来源于算法对于数据处理的混乱&#xff0c;它不像人类一样可以by the book&#xff0c;它没有一个权威的对照数据源。 什么是大模型幻觉 大模型的幻觉&#xff08;Hallucination&#xff09;是指当人工智能模型生成的内容与提供的源内容不符或没有意义的现象。…

【JavaScript】JavaScript 程序流程控制 ② ( 循环流程控制 | 循环要素 - 循环体 / 循环终止条件 | for 循环语法结构 )

文章目录 一、JavaScript 程序流程控制 - 循环流程控制1、循环流程控制2、循环要素 - 循环体 / 循环终止条件3、for 循环语法结构 - 循环控制变量 / 循环终止条件 / 操作表达式4、for 循环 完整代码示例 一、JavaScript 程序流程控制 - 循环流程控制 1、循环流程控制 在 程序开…

C# 连接neo4j数据库,包括非默认的neo4j默认库

官方文档没找见&#xff0c;自己在源码里面找到的 private string _dbHost "bolt://localhost:7687"; private string _dbUser "neo4j"; private string _dbPassword "******"; private IDriver? _driver;public CQLOperation(string _data…

CTF-reverse-每日练题-xxxorrr

题目链接 https://adworld.xctf.org.cn/challenges/list 题目详情 xxxorrr ​ 解题报告 下载得到的文件使用ida64分析&#xff0c;如果报错就换ida32&#xff0c;得到分析结果&#xff0c;有main函数就先看main main函数分析 v6 main函数中&#xff0c;v6的值是__readfsqwor…

Haproxy 负载均衡集群

一. Haproxy &#xff1a; 1. Haproxy 介绍&#xff1a; HAProxy 是法国开发者威利塔罗 (Willy Tarreau) 在2000年使用C语言开发的一个开源软件&#xff0c;是一款具备高并发(一万以上)、高性能的TCP和HTTP负载均衡器&#xff0c;支持基于cookie的持久性&#xff0c;自动故障…

河南大学大数据平台技术实验报告二

大数据平台技术课程实验报告 实验二&#xff1a;HDFS操作实践 姓名&#xff1a;杨馥瑞 学号&#xff1a;2212080042 专业&#xff1a;数据科学与大数据技术 年级&#xff1a;2022级 主讲教师&#xff1a;林英豪 实验时间&#xff1a;2024年3月15日3点 至 2024年3月15日4点40 …

【矩阵】54. 螺旋矩阵【中等】

螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 解题思路 1、模拟顺时针螺旋顺序遍历矩阵…

完美解决 RabbitMQ可视化界面Overview不显示折线图和队列不显示Messages

问题场景&#xff1a; 今天使用docker部署了一个RabbitMQ&#xff0c;浏览器打开15672可视化页面发送消息后不显示Overview中的折线图&#xff0c;还有队列中的Messages&#xff0c;因为我要看队列中的消息数量。 解决方案&#xff1a; 进入容器内部 docker exec -it 容器id…

视频素材库app推荐的地方在哪里找?

视频素材库app推荐的地方在哪里&#xff1f;这是很多短视频创作者都会遇到的问题。别着急&#xff0c;今天我就来给大家介绍几个视频素材库app推荐的网站&#xff0c;让你的视频创作更加轻松有趣&#xff01; 蛙学网&#xff1a;视频素材库app推荐的首选当然是蛙学网啦&#xf…

CommonJs规范

文章目录 1. CommonJS 模块的导出2. CommonJS 模块的导入2.1使用 require 函数导入文件模块&#xff08;用户自定义&#xff09;2.2使用 require 函数导入核心模块&#xff08;Node.js 内置的模块&#xff09;2.3文件夹作为模块2.4模块的原理 在node中&#xff0c;默认支持的模…

GPT-4引领AI新纪元,Claude3、Gemini、Sora能否跟上步伐?

【最新增加Claude3、Gemini、Sora、GPTs讲解及AI领域中的集中大模型的最新技术】 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚…

C语言——自定义类型——结构体(从零到一的跨越)

目录 前言 1.什么是结构体 2.结构体类型的声明 2.1结构体的声明 2.2结构体的创建和初始化 2.3结构成员访问操作符 2.3.1结构体成员直接访问 2.3.2结构体成员的间接访问 2.4结构体变量的重命名 2.5结构体的特殊声明 2.6结构的自引用 3.结构体内存对齐 3.1对齐规则 3…

JMH微基准测试框架学习笔记

一、简介 JMH&#xff08;Java Microbenchmark Harness&#xff09;是一个用于编写、构建和运行Java微基准测试的框架。它提供了丰富的注解和工具&#xff0c;用于精确控制测试的执行和结果测量&#xff0c;从而帮助我们深入了解代码的性能特性。 二、案例实战 在你的pom文件…

数据结构从入门到精通——直接选择排序

直接选择排序 前言一、选择排序的基本思想&#xff1a;二、直接选择排序三、直接选择排序的特性总结&#xff1a;四、直接选择排序的动画展示五、直接选择排序的代码展示test.c 六、直接选择排序的优化test.c 前言 直接选择排序是一种简单的排序算法。它的工作原理是每一次从未…

Hadoop大数据应用:HDFS 集群节点缩容

目录 一、实验 1.环境 2.HDFS 集群节点缩容 二、问题 1.数据迁移有哪些状态 2.数据迁移失败 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 主机架构软件版本IP备注hadoop NameNode &#xff08;已部署&#xff09; SecondaryNameNode &#xff08;已部署…

Epuck2机器人固件更新及IP查询

文章目录 前言一、下载固件更新软件包&#xff1a;二、查询机器人在局域网下的IP 前言 前面进行了多机器人编队仿真包括集中式和分布式&#xff0c;最近打算在实物机器人上跑一跑之前的编队算法。但由于Epuck2机器人长时间没使用&#xff0c;故对其进行固件的更新&#xff0c;…

直播预约丨《袋鼠云大数据实操指南》No.1:从理论到实践,离线开发全流程解析

近年来&#xff0c;新质生产力、数据要素及数据资产入表等新兴概念犹如一股强劲的浪潮&#xff0c;持续冲击并革新着企业数字化转型的观念视野&#xff0c;昭示着一个以数据为核心驱动力的新时代正稳步启幕。 面对这些引领经济转型的新兴概念&#xff0c;为了更好地服务于客户…

CTF题型 匿名函数考法例题总结

CTF题型 匿名函数考法&例题总结 文章目录 CTF题型 匿名函数考法&例题总结一 .原理分析二 .重点匿名函数利用1.create_function()如何实现create_function代码注入 2.array_map()3.call_user_func()4.call_user_func_array()5.array_filter() 三.例题讲解1.[Polar 靶场 …

详细分析Python模块中的雪花算法(附模板)

目录 前言1. 基本知识2. 模板3. Demo 前言 分布式ID的生成推荐阅读&#xff1a;分布式ID生成方法的超详细分析&#xff08;全&#xff09; 1. 基本知识 Snowflake 算法是一种用于生成全局唯一 ID 的分布式算法&#xff0c;最初由 Twitter 设计并开源 它被设计用于解决分布式…

【5G NB-IoT NTN】3GPP R17 NB-IoT NTN介绍

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…