一篇文章介绍了如何使用共享内存的方式创建并显示窗口,本文介绍使用EGL的方式显示窗口。
有了上面的基础,EGL版本就简单一些
display = wl_display_connect(0);
if(!display){
printf("Cannot connect to wayland compositor.\n");
return -1;
}
registry = wl_display_get_registry(display);
wl_registry_add_listener(registry,®istry_listener,NULL);
wl_display_dispatch(display);
wl_display_roundtrip(display);
if (compositor == NULL || shell == NULL)
{
fprintf(stderr, "Can't find compositor or shell\n");
return -1;
}else{
fprintf(stderr, "Found compositor and shell\n");
}
surface = wl_compositor_create_surface(compositor);
if (surface == NULL)
{
fprintf(stderr, "Can't create surface\n");
return -1;
}else{
fprintf(stderr, "Created surface\n");
}
shell_surface = wl_shell_get_shell_surface(shell, surface);
wl_shell_surface_set_toplevel(shell_surface);
连接到wayland服务器,创建窗口,还要添加注册捕获
static void registry_handler(void *data,struct wl_registry *registry, uint32_t id,
const char *interface,uint32_t version){
printf("Got a registry event for %s id %d\n", interface, id);
if (strcmp(interface, "wl_compositor") == 0)
{
compositor = wl_registry_bind(registry, id,&wl_compositor_interface,1);
}else if (strcmp(interface, "wl_shell") == 0){
shell = wl_registry_bind(registry, id,&wl_shell_interface,1);
}
}
static void registry_remover(void *data, struct wl_registry *registry, uint32_t id){}
static const struct wl_registry_listener registry_listener= {
registry_handler,
registry_remover
};
// init egl
EGLint major, minor, config_count, tmp_n;
EGLint config_attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLint context_attribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
egl_display = eglGetDisplay((EGLNativeDisplayType)display);
eglInitialize(egl_display, &major, &minor);
printf("EGL major: %d, minor %d\n", major, minor);
eglGetConfigs(egl_display, 0, 0, &config_count);
printf("EGL has %d configs\n", config_count);
eglChooseConfig(egl_display, config_attribs, &(egl_config), 1, &tmp_n);
egl_context = eglCreateContext(
egl_display,
egl_config,
EGL_NO_CONTEXT,
context_attribs);
// init window
egl_window = wl_egl_window_create(surface, WIDTH, HEIGHT);
egl_surface = eglCreateWindowSurface(
egl_display,
egl_config,
egl_window,
0);
eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
eglSwapBuffers(egl_display, egl_surface);
获取窗口、初始化、获取配置、选择配置、创建上下文、创建EGL窗口、交换显示缓冲区
具体的到EGL开发系列中再说。
窗口绘制完成后,循环显示窗口
while (wl_display_dispatch(display) != -1) {
}
// disconnect
wl_display_disconnect(display);
编译运行显示窗口
默认为黑色背景,我们调整一下。
可以看到代码中有swapbuffer
字样,在标准的OpenGL开发中一般是调用绘图函数,然后使用双缓冲技术交换显示数据。绘制的背景颜色代码应该在此代码的上方。
glClearColor(0.5f, 0.5f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
将背景设置为棕色
效果为:
我们来看一下调用流程图
这是上一篇共享内存的流程图
可以看到,EGL方式相对简单,代码量少,函数调用少。
完整代码在Wayland_Frashman中的EGL文件夹下的9.5.window_EGL下。
本文首发于:Wayland入门9.5:第一个EGL窗口