Wayland入门9.5:第一个EGL窗口

一篇文章介绍了如何使用共享内存的方式创建并显示窗口,本文介绍使用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,&registry_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窗口

你可能感兴趣的:(Wayland开发入门,linux,wayland,desktop)