文章目录
- 前言
- 一、获取 glm 库文件
- 二、使用环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照效果的3d 立方体
- 1. egl_wayland_light.cpp
- 2. Matrix.h 和 Matrix.cpp
- 3. xdg-shell-client-protocol.h 和 xdg-shell-protocol.c
- 4. 编译
- 5. 运行
- 总结
- 参考资料
前言
本文主要介绍如何使用 wayland(xdg_wm_base) + egl + opengles3.0 绘制一个使用冯氏光照模型(Phong Lighting Model)的绕Y轴旋转的正方体,主要涉及环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照,使用一个固定位置和颜色的光源。
软硬件环境:
硬件:PC
软件:ubuntu22.04 egl1.4 opengles3.0 weston9.0
一、获取 glm 库文件
glm是一个C++数学库,用于进行OpenGL开发时常用的数学计算,例如向量、矩阵、四元数等。它提供了许多方便的函数和工具,可以简化在OpenGL程序中进行数学计算的过程。在使用 glm之前,您需要包含适当的 glm 头文件(glm 库就是一个头文件,没有.so库)。获取 glm 相关的头文件,有以下两种方式:
- ubuntu 上安装 glm 库
具体的安装过程,可以查看《opengles 顶点坐标变换常用的矩阵(九)》 这篇文章 - 从 github 获取
直接从 glm github 仓库地址 下载即可
二、使用环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照效果的3d 立方体
1. egl_wayland_light.cpp
egl_wayland_light.cpp 代码如下
#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"#include <glm/vec3.hpp> // glm::vec3
#include <glm/vec4.hpp> // glm::vec4
#include <glm/gtc/type_ptr.hpp>#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;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;
};// Light parameters
glm::vec3 lightPos(0.0f, 3.0f, 0.0f); // 建立一个在立方体正上方的光源(Y轴正方向上位置为3.0处)
glm::vec3 lightColor(1.0f, 1.0f, 1.0f); //光源颜色为白色//viewPos parameters
glm::vec3 viewPos(0.0f, 0.0f, 3.0f);// Object parameters
glm::vec3 objectColor(1.0f, 0.0f, 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 = (struct wl_compositor *)wl_registry_bind(registry, name, &wl_compositor_interface, 1);} else if (strcmp(interface, "xdg_wm_base") == 0) {wm_base = (struct xdg_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