一,安装依赖软件:sudo apt install zlib1g-dev libssl-dev libgles2-mesa-dev libsystemd-dev libpng-dev libglib2.0-dev libwayland-dev weston libweston-9-dev
二,启动:
# 运行weston
weston -Swayland-1
# 运行程序
./yourprogram
注意:这里启动weston用的wayland-1,所以代码中也要用wayland-1。
三,代码:
#include "wayland-client.h"
#include "wayland-egl.h"
#include "wayland-util.h"
#include <GLES2/gl2.h>
#include <EGL/egl.h>
typedef struct stWlContextStruct {
struct wl_display *wlDisplay;
struct wl_registry *wlRegistry;
struct wl_compositor *wlCompositor;
struct wl_egl_window *wlNativeWindow;
struct wl_surface *wlSurface;
struct wl_shell *wlShell;
struct wl_shell_surface *wlShellSurface;
int width;
int height;
} WLContextStruct;
void handlePing(void *data, struct wl_shell_surface *shellSurface, uint32_t serial) {
wl_shell_surface_pong(shellSurface, serial);
}
void handleConfigure(void *data, struct wl_shell_surface *shellSurface, uint32_t edges, int32_t width, int32_t height) {
}
void handlePopupDone(void *data, struct wl_shell_surface *shellSurface) {
}
const struct wl_shell_surface_listener shellSurfaceListener = {
handlePing,
handleConfigure,
handlePopupDone,
};
void registry_handle_global(void *data, struct wl_registry *registry, uint32_t id, const char *interface, uint32_t version) {
Navinfo::WLContextStruct *p_wlCtx = (Navinfo::WLContextStruct *)data;
if (0 == strcmp(interface, "wl_compositor")) {
p_wlCtx->wlCompositor = (wl_compositor *)wl_registry_bind(registry, id, &wl_compositor_interface, 1);
} else if (0 == strcmp(interface, "wl_compositor")) {
p_wlCtx->wlShell = (struct wl_shell *)wl_registry_bind(registry, id, &wl_shell_interface, 1);
}
}
const struct wl_registry_listener registry_listener = {
registry_handle_global,
NULL,
};
int main() {
// wayland part
unsigned int surfaceWidth = 800;
unsigned int surfaceHeight = 600;
WLContextStruct wlContextStruct;
memset(&wlContextStruct, 0, sizeof(wlContextStruct));
wlContextStruct.wlDisplay = wl_display_connect("wayland-1");
if (NULL == wlContextStruct.wlDisplay) {
LOG_INFO("failed to connect to Wayland display");
return 1;
}
wlContextStruct.wlRegistry = wl_display_get_registry(wlContextStruct.wlDisplay);
wl_registry_add_listener(wlContextStruct.wlRegistry, ®istry_listener, &wlContextStruct);
wl_display_dispatch(wlContextStruct.wlDisplay);
wl_display_roundtrip(wlContextStruct.wlDisplay);
wlContextStruct.wlSurface = wl_compositor_create_surface(wlContextStruct.wlCompositor);
wlContextStruct.wlShellSurface = wl_shell_get_shell_surface(wlContextStruct.wlShell, wlContextStruct.wlSurface);
wl_shell_surface_add_listener(reinterpret_cast<struct wl_shell_surface *>(wlContextStruct.wlShellSurface), &shellSurfaceListener, &wlContextStruct);
wlContextStruct.wlNativeWindow = wl_egl_window_create(wlContextStruct.wlSurface, surfaceWidth, surfaceHeight);
wl_shell_surface_set_title(wlContextStruct.wlShellSurface, "Hi_WL");
wl_shell_surface_set_toplevel(wlContextStruct.wlShellSurface);
// egl part
EGLNativeWindowType eglWindow = (EGLNativeWindowType)wlContextStruct.wlNativeWindow;
EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType)wlContextStruct.wlDisplay);
EGLint major, minor;
eglInitialize(eglDisplay, &major, &minor);
eglBindAPI(EGL_OPENGL_ES_API);
EGLint count;
if (!eglGetConfigs(eglDisplay, nullptr, 0, &count) || count < 1) {
return 1;
}
EGLConfig configFound;
EGLConfig *configs = static_cast<EGLConfig *>(malloc(count * sizeof(EGLConfig)));
if(configs)
{
memset(configs, 0, count * sizeof(EGLConfig));
static const EGLint kConfigAttributes[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 24,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE};
EGLint n;
ret = eglChooseConfig(eglDisplay, kConfigAttributes, configs, count, &n);
if ((ret != EGL_TRUE) || (n < 1)) {
return 1;
}
configFound = configs[0];
free(configs);
configs = nullptr;
}
static const EGLint kContextAttibutes[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLContext eEglContext = eglCreateContext(eglDisplay, configFound, EGL_NO_CONTEXT, kContextAttibutes);
if (eEglContext == EGL_NO_CONTEXT) {
return 1;
}
EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay, configFound, (EGLNativeWindowType)eglWindow, nullptr);
ret = eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eEglContext);
if (ret != EGL_TRUE) {
return 1;
}
// render part
while (true)
{
// render ...
eglSwapBuffers(eglDisplay, eglSurface);
}
return 0;
}