wayland(xdg_wm_base) + egl + opengles 渲染旋转的 3D 立方体实例(十一)

2024-02-26 11:04

本文主要是介绍wayland(xdg_wm_base) + egl + opengles 渲染旋转的 3D 立方体实例(十一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 一、实现旋转的3D 立法体需要用到的技术
    • 1. 模型矩阵
    • 2. 视图矩阵
    • 3. 投影矩阵
    • 4. 背面剔除
  • 二、opengles3.0 渲染旋转的 3D 立方体实例
    • 1. egl_wayland_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轴旋转的正方体,涉及顶点坐标变化,模型,视图,投影矩阵等相关内容
软硬件环境:
硬件:PC
软件:ubuntu22.04 egl1.4 opengles3.0 weston9.0


一、实现旋转的3D 立法体需要用到的技术

绘制一个绕Y轴旋转的正方体,涉及顶点坐标变化,模型,视图,投影矩阵以及背面剔除等相关内容

1. 模型矩阵

要实现旋转,故需要使用一个矩阵来实现,在这里直接使用Matrix.c 中封装好的如下接口即可

matrixRotateX(modelMatrix, angleX);
matrixRotateY(modelMatrix, angleY);
matrixRotateZ(modelMatrix, angleZ);

2. 视图矩阵

默认的视点是在坐标(0,0,0)处(即在立方体内部),为了看到立方体的全貌,需要将视点沿着Z轴正方向移动(移动到立方体外面),也需要使用一个矩阵来实现,在这里直接使用Matrix.c 中封装好的如下接口即可

matrixTranslate(viewMatrix, 0.0f, 0.0f, -7.0f);       //视点沿着Z轴移动到Z坐标为7处

移动的距离越远,立方体看上去会越小,出现缩放的效果

3. 投影矩阵

由于使用视图矩阵将视点移动到Z坐标为7(7 大于1,超出了可视范围)处,故需要使用投影矩阵,否则会看不到立方体,也需要使用一个矩阵来实现,在这里直接使用Matrix.c 中封装好的如下接口即可

/* Setup the perspective */matrixPerspective(projectionMatrix, 45, (float)width / (float)height, 0.1f, 100);    //角度为45°

4. 背面剔除

opengles3.0 默认背面剔除功能是关闭的,需要使能, 否则立方体的正面会不显示(透视),直接调用如下语句即可

glEnable(GL_CULL_FACE);         //enable back face cull

这里需要注意一下,在OpenGLES中,所绘制的图形是通过一个个的三角形组合成的。OpenGLES通过分析顶点数据的顺序得知哪些面是正面、哪些面是背面。默认规则:
正面:按照逆时针顶点连接顺序的三角形面
背面:按照顺时针顶点连接书序的三角形面
顺时针或逆时针:由观察者的方向来确定

正面和背面是由三角形的顶点顺序和观察者方向共同决定的,随着观察者的角度变化,正背面也会跟着改变,这也与现实中的情况相吻合。

二、opengles3.0 渲染旋转的 3D 立方体实例

1. egl_wayland_cube3_0.c

egl_wayland_cube3_0.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 "Matrix.h"
#include "xdg-shell-client-protocol.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;struct window {struct wl_surface *surface;struct xdg_surface *xdg_surface;struct xdg_toplevel *xdg_toplevel;struct wl_egl_window *egl_window;
};//opengles global varGLuint projectionLocation;
GLuint modelLocation;
GLuint viewLocation;
GLuint simpleCubeProgram; float projectionMatrix[16];
float modelMatrix[16];
float viewMatrix[16];
float angleX = 30.0f;
float angleY = 0.0f;
float angleZ = 0.0f;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,

这篇关于wayland(xdg_wm_base) + egl + opengles 渲染旋转的 3D 立方体实例(十一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/748650

相关文章

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

使用Python绘制3D堆叠条形图全解析

《使用Python绘制3D堆叠条形图全解析》在数据可视化的工具箱里,3D图表总能带来眼前一亮的效果,本文就来和大家聊聊如何使用Python实现绘制3D堆叠条形图,感兴趣的小伙伴可以了解下... 目录为什么选择 3D 堆叠条形图代码实现:从数据到 3D 世界的搭建核心代码逐行解析细节优化应用场景:3D 堆叠图

java向微信服务号发送消息的完整步骤实例

《java向微信服务号发送消息的完整步骤实例》:本文主要介绍java向微信服务号发送消息的相关资料,包括申请测试号获取appID/appsecret、关注公众号获取openID、配置消息模板及代码... 目录步骤1. 申请测试系统2. 公众号账号信息3. 关注测试号二维码4. 消息模板接口5. Java测试

MySQL数据库的内嵌函数和联合查询实例代码

《MySQL数据库的内嵌函数和联合查询实例代码》联合查询是一种将多个查询结果组合在一起的方法,通常使用UNION、UNIONALL、INTERSECT和EXCEPT关键字,下面:本文主要介绍MyS... 目录一.数据库的内嵌函数1.1聚合函数COUNT([DISTINCT] expr)SUM([DISTIN

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

java String.join()方法实例详解

《javaString.join()方法实例详解》String.join()是Java提供的一个实用方法,用于将多个字符串按照指定的分隔符连接成一个字符串,这一方法是Java8中引入的,极大地简化了... 目录bVARxMJava String.join() 方法详解1. 方法定义2. 基本用法2.1 拼接

Linux lvm实例之如何创建一个专用于MySQL数据存储的LVM卷组

《Linuxlvm实例之如何创建一个专用于MySQL数据存储的LVM卷组》:本文主要介绍使用Linux创建一个专用于MySQL数据存储的LVM卷组的实例,具有很好的参考价值,希望对大家有所帮助,... 目录在Centos 7上创建卷China编程组并配置mysql数据目录1. 检查现有磁盘2. 创建物理卷3. 创

Java List排序实例代码详解

《JavaList排序实例代码详解》:本文主要介绍JavaList排序的相关资料,Java排序方法包括自然排序、自定义排序、Lambda简化及多条件排序,实现灵活且代码简洁,文中通过代码介绍的... 目录一、自然排序二、自定义排序规则三、使用 Lambda 表达式简化 Comparator四、多条件排序五、