本文主要是介绍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, ®istry_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 立方体实例(十一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!