当前位置: 首页 > news >正文

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[] 

相关文章:

  • JavaSE(上)-Day7
  • 什么是委托,委托的本质是什么?
  • 爱奇艺 CTR 场景下的 GPU 推理性能优化
  • LeetCode 热题100 链表专题解析
  • ElasticSearch第二章(ES8.X的使用)
  • jvm的垃圾回收器以及触发full gc的场景
  • 概率基础——逻辑回归多分类法
  • git 安装、创建仓库、常用命令、克隆下载、上传项目、删除分支 -- 一篇文章总结
  • Lua中文语言编程源码-第二节,更改lbaselib.c基础库模块, 使Lua支持中文关键词(与操作相关的)
  • [论文精读]Dynamic Coarse-to-Fine Learning for Oriented Tiny Object Detection
  • [LLM]大模型八股知识点(一)
  • 【二分查找】算法例题
  • 【数据结构】单链表详解
  • 【C语言】—— 指针三 : 参透数组传参的本质
  • 记录一下在Pycharm中虚拟环境的创建
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • AHK 中 = 和 == 等比较运算符的用法
  • Angular 响应式表单之下拉框
  • Python中eval与exec的使用及区别
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • Spring Boot MyBatis配置多种数据库
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • Wamp集成环境 添加PHP的新版本
  • Zepto.js源码学习之二
  • 回顾 Swift 多平台移植进度 #2
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 聚类分析——Kmeans
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 最简单的无缝轮播
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • Python 之网络式编程
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #每日一题合集#牛客JZ23-JZ33
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (pytorch进阶之路)CLIP模型 实现图像多模态检索任务
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (十一)c52学习之旅-动态数码管
  • (转)JVM内存分配 -Xms128m -Xmx512m -XX:PermSize=128m -XX:MaxPermSize=512m
  • (转)大型网站的系统架构
  • (转载)从 Java 代码到 Java 堆
  • .form文件_一篇文章学会文件上传
  • .NET分布式缓存Memcached从入门到实战
  • .net获取当前url各种属性(文件名、参数、域名 等)的方法
  • .net快速开发框架源码分享
  • .NET中统一的存储过程调用方法(收藏)
  • /run/containerd/containerd.sock connect: connection refused
  • :中兴通讯为何成功
  • @Autowired标签与 @Resource标签 的区别
  • @EnableConfigurationProperties注解使用
  • @KafkaListener注解详解(一)| 常用参数详解
  • @RequestBody与@ResponseBody的使用
  • [20171113]修改表结构删除列相关问题4.txt
  • [BUG]vscode插件live server无法自动打开浏览器
  • [bzoj2957]楼房重建