文章目录
- 前言
- 一、ubuntu 上 opengl 版本的 glxgears
- 二、基于 wayland 窗口协议的 gles-gears
-
- 1.egl_wayland_gears.c
- 2. matrix.c 和 matrix.h
- 3. 编译
- 4. 运行
- 总结
- 参考资料
前言
本文主要介绍如何在linux 下 wayland 窗口中,使用 egl + opengles 控制GPU 渲染 gears 并显示,即实现一个wayland 版本的gles-gears
软硬件环境:
硬件:PC
软件:ubuntu18.04 weston3.0 opengles2.0 egl1.4
一、ubuntu 上 opengl 版本的 glxgears
如下图所示,是在ubuntu 上执行 glxgears 的结果,会出现三个不同颜色的齿轮在不停的旋转,并会打印出帧率。
如果ubuntu 上没有安装 glxgears 程序, 可以通过 sudo apt-get install mesa-utils libgles2-mesa-dev 命令进行安装
- glxgears 是一个简单的 OpenGL 示例程序,用于测试系统中 OpenGL 功能和性能
- glxgears 只是一个简单的示例程序,并不是一个真正的性能测试工具。它主要用于检查 OpenGL
驱动是否正确安装和运行,并提供一个简单的可视化效果。如果需要进行更详细的 OpenGL 性能测试,可以考虑使用专业的性能测试工具,例如 glmark2。 - 运行 glxgears ,需要安装 Mesa 3D 图形库和相关的 OpenGL 开发库;
二、基于 wayland 窗口协议的 gles-gears
参考 Mesa Demos es2gears.c 实现基于 wayland 版本的 gears 总共有三个文件,分别是:egl_wayland_gears.c, matrix.c, matrix.h
1.egl_wayland_gears.c
使用 wayland (使用wl_shell 接口)+ egl + opengles2.0 实现和 glxgears 同样效果的 egl_wayland_gears.c 代码如下
#include <wayland-client.h> #include <wayland-server.h> #include <wayland-egl.h> #include <EGL/egl.h> #include <GLES2/gl2.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <assert.h> #include <unistd.h> #include <time.h> #include "matrix.h" #define WIDTH 640 #define HEIGHT 480 static struct timespec start_time; struct wl_display *display = NULL; struct wl_compositor *compositor = NULL; struct wl_shell *shell = NULL; struct wl_registry *registry = NULL; struct window { struct wl_surface *surface; struct wl_shell_surface *shell_surface; struct wl_egl_window *egl_window; }; #define STRIPS_PER_TOOTH 7 #define VERTICES_PER_TOOTH 46 #define GEAR_VERTEX_STRIDE 6 /* Each vertex consist of GEAR_VERTEX_STRIDE GLfloat attributes */ typedef GLfloat GearVertex[GEAR_VERTEX_STRIDE]; /** * Struct representing a gear. */ struct gear { /** The array of vertices comprising the gear */ GearVertex *vertices; /** The number of vertices comprising the gear */ int nvertices; /** The Vertex Buffer Object holding the vertices in the graphics card */ GLuint vbo; }; /** The view rotation [x, y, z] */ static GLfloat view_rot[3] = { 20.0, 30.0, 0.0 }; /** The gears */ static struct gear *gear1, *gear2, *gear3; /** The current gear rotation angle */ static GLfloat angle = 0.0; /** The location of the shader uniforms */ static GLuint ModelViewProjectionMatrix_location, NormalMatrix_location, LightSourcePosition_location, MaterialColor_location; /** The projection matrix */ static GLfloat ProjectionMatrix[16]; /** The direction of the directional light for the scene */ static const GLfloat LightSourcePosition[4] = { 5.0, 5.0, 10.0, 1.0}; /** *Fills a gear vertex. */ static GearVertex * vert(GearVertex *v, GLfloat x, GLfloat y, GLfloat z, GLfloat n[3]) { v[0][0] = x; v[0][1] = y; v[0][2] = z; v[0][3] = n[0]; v[0][4] = n[1]; v[0][5] = n[2]; return v + 1; } /** *Create a gear wheel. */ static struct gear * create_gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width, GLint teeth, GLfloat tooth_depth) { GLfloat r0, r1, r2; GLfloat da; GearVertex *v; struct gear *gear; double s[5], c[5]; GLfloat normal[3]; int cur_strip_start = 0; int i; /* Allocate memory for the gear */ gear = malloc(sizeof *gear); if (gear == NULL) return NULL; /* Calculate the radii used in the gear */ r0 = inner_radius; r1 = outer_radius - tooth_depth / 2.0; r2 = outer_radius + tooth_depth / 2.0; da = 2.0 * M_PI / teeth / 4.0; /* the first tooth doesn't need the first strip-restart sequence */ assert(teeth > 0); gear->nvertices = VERTICES_PER_TOOTH + (VERTICES_PER_TOOTH + 2) * (teeth - 1); /* Allocate memory for the vertices */ gear->vertices = calloc(gear->nvertices, sizeof(*gear->vertices)); v = gear->vertices; for (i = 0; i < teeth; i++) { /* Calculate needed sin/cos for varius angles */ #if HAVE_SINCOS sincos(i * 2.0 * M_PI / teeth, &s[0], &c[0]); sincos(i * 2.0 * M_PI / teeth + da, &s[1], &c[1]); sincos(i * 2.0 * M_PI / teeth + da * 2, &s[2], &c[2]); sincos(i * 2.0 * M_PI / teeth + da * 3, &s[3], &c[3]); sincos(i * 2.0 * M_PI / teeth + da * 4, &s[4], &c[4]); #else s[0] = sin(i * 2.0 * M_PI /teeth); c[0] = cos(i * 2.0 * M_PI /teeth); s[1] = sin(i * 2.0 * M_PI /teeth + da); c[1] = cos(i * 2.0 * M_PI /teeth + da); s[2] = sin(i * 2.0 * M_PI /teeth + da * 2); c[2] = cos(i * 2.0 * M_PI /teeth + da * 2); s[3] = sin(i * 2.0 * M_PI /teeth + da * 3); c[3] = cos(i * 2.0 * M_PI /teeth + da * 3); s[4] = sin(i * 2.0 * M_PI /teeth + da * 4); c[4] = cos(i * 2.0 * M_PI /teeth + da * 4); #endif /* A set of macros for making the creation of the gears easier */ #define GEAR_POINT(r, da) { (r) * c[(da)], (r) * s[(da)] } #define SET_NORMAL(x, y, z) do { normal[0] = (x); normal[1] = (y); normal[2] = (z); } while(0) #define GEAR_VERT(v, point, sign) vert((v), p[(point)].x, p[(point)].y, (sign) * width * 0.5, normal) #define START_STRIP do { cur_strip_start = (v - gear->vertices); if (cur_s