wayland(xdg_wm_base) + egl + opengles 渲染使用纹理贴图的旋转 3D 立方体实例(十三)

时间:2024-04-01 22:23:09
#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" #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" #define WIDTH 800 #define HEIGHT 600 struct wl_display *display = NULL; struct wl_compositor *compositor = NULL; struct xdg_wm_base *wm_base = NULL; struct wl_registry *registry = NULL; //opengles global var GLuint projectionLocation; GLuint modelLocation; GLuint viewLocation; GLuint simpleCubeProgram; GLuint samplerLocation; GLuint textureId; 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; }; 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 = wl_registry_bind(registry, name, &wl_compositor_interface, 1); } else if (strcmp(interface, "xdg_wm_base") == 0) { 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("Failed to connect to Wayland display!\n"); return false; } if ((registry = wl_display_get_registry(display)) == NULL) { printf("Faield to get Wayland registry!\n"); return false; } wl_registry_add_listener(registry, &registry_listener, NULL); wl_display_dispatch(display); if (!compositor) { printf("Could not bind Wayland protocols!\n"); return false; } return true; } bool initializeWindow(struct window *window) { initWaylandConnection(); window->surface = wl_compositor_create_surface (compositor); window->xdg_surface = xdg_wm_base_get_xdg_surface(wm_base, window->surface); if (window->xdg_surface == NULL) { printf("Failed to get Wayland xdg surface\n"); return false; } else { xdg_surface_add_listener(window->xdg_surface, &xdg_surface_listener, window); window->xdg_toplevel = xdg_surface_get_toplevel(window->xdg_surface); xdg_toplevel_add_listener(window->xdg_toplevel, &xdg_toplevel_listener, window); xdg_toplevel_set_title(window->xdg_toplevel, "egl_wayland_texture"); } return true; } void releaseWaylandConnection(struct window *window) { if(window->xdg_toplevel) xdg_toplevel_destroy(window->xdg_toplevel); if(window->xdg_surface) xdg_surface_destroy(window->xdg_surface); wl_surface_destroy(window->surface); xdg_wm_base_destroy(wm_base); wl_compositor_destroy(compositor); wl_registry_destroy(registry); wl_display_disconnect(display); } bool createEGLSurface(EGLDisplay eglDisplay, EGLConfig eglConfig, EGLSurface *eglSurface, struct window *window) { window->egl_window = wl_egl_window_create(window->surface, WIDTH, HEIGHT); if (window->egl_window == EGL_NO_SURFACE) { printf("Can't create egl window\n"); return false; } else { printf("Created wl egl window\n"); } *eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, window->egl_window, NULL); return true; } void deInitializeGLState(GLuint shaderProgram) { // Frees the OpenGL handles for the program glDeleteProgram(shaderProgram); } void releaseEGLState(EGLDisplay eglDisplay) { if (eglDisplay != NULL) { // To release the resources in the context, first the context has to be released from its binding with the current thread. eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); // Terminate the display, and any resources associated with it (including the EGLContext) eglTerminate(eglDisplay); } } //" gl_Position = projection * modelView * vec4(vertexPosition, 1.0);\n" static const char glVertexShader[]