WaylandEntryPoint

Basic Tutorial that shows step-by-step how to initialise OpenGL ES 2.0, use it for drawing a triangle and terminate it.

 /*!*********************************************************************************************************************
 \File         OpenGLESHelloAPI_LinuxWayland.cpp
 \Title        OpenGL ES 2.0 HelloAPI Tutorial
 \Author       PowerVR by Imagination, Developer Technology Team
 \Copyright    Copyright (c) Imagination Technologies Limited.
 \brief        Basic Tutorial that shows step-by-step how to initialise OpenGL ES 2.0, use it for drawing a triangle and terminate it.
 			  Entry Point: main
 ***********************************************************************************************************************/
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include "OpenGLESHelloAPI.h"
 
 wl_registry* wlRegistry = NULL;
 wl_compositor* wlCompositor = NULL;
 wl_shell* wlShell = NULL;
 wl_seat* wlSeat = NULL;
 wl_surface* wlSurface = NULL;
 wl_pointer* wlPointer = NULL;
 wl_shell_surface* wlShellSurface = NULL;
 short pointerXY[2];
 
 static void pointer_handle_enter(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t sx, wl_fixed_t sy) {}
 
 static void pointer_handle_leave(void* data, struct wl_pointer* pointer, uint32_t serial, struct wl_surface* surface) {}
 
 static void pointer_handle_motion(void* data, struct wl_pointer* pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
 {
 	pointerXY[0] = (short)sx;
 	pointerXY[1] = (short)sy;
 }
 
 static void pointer_handle_button(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
 {
 	if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED)
 	{
 		wl_shell_surface_move(wlShellSurface, wlSeat, serial);
 	}
 }
 
 static void pointer_handle_axis(void* data, struct wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {}
 
 static const struct wl_pointer_listener pointer_listener = {
 	pointer_handle_enter,
 	pointer_handle_leave,
 	pointer_handle_motion,
 	pointer_handle_button,
 	pointer_handle_axis,
 };
 
 static void seat_handle_capabilities(void* data, struct wl_seat* seat, uint32_t caps)
 {
 	if ((caps & WL_SEAT_CAPABILITY_POINTER) && !wlPointer)
 	{
 		wlPointer = wl_seat_get_pointer(seat);
 		wl_pointer_add_listener(wlPointer, &pointer_listener, NULL);
 	}
 	else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && wlPointer)
 	{
 		wl_pointer_destroy(wlPointer);
 		wlPointer = NULL;
 	}
 }
 static void seat_handle_name(void* data, struct wl_seat* seat, const char* name) {}
 
 static const struct wl_seat_listener seatListener = { seat_handle_capabilities, seat_handle_name };
 
 static void registerGlobalCallback(void* data, wl_registry* registry, uint32_t name, const char* interface, uint32_t version)
 {
 	if (strcmp(interface, "wl_compositor") == 0)
 	{
 		wlCompositor = (wl_compositor*)wl_registry_bind(registry, name, &wl_compositor_interface, 1);
 	}
 	else if (strcmp(interface, "wl_shell") == 0)
 	{
 		wlShell = (wl_shell*)wl_registry_bind(registry, name, &wl_shell_interface, 1);
 	}
 	else if (strcmp(interface, "wl_seat") == 0)
 	{
 		wlSeat = (wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, 1);
 		wl_seat_add_listener(wlSeat, &seatListener, NULL);
 	}
 }
 
 static void globalObjectRemove(void* data, struct wl_registry* wl_registry, uint32_t name) {}
 
 static const wl_registry_listener registryListener = { registerGlobalCallback, globalObjectRemove };
 
 static void ping_cb(void* data, struct wl_shell_surface* shell_surface, uint32_t serial)
 {
 	wl_shell_surface_pong(shell_surface, serial);
 }
 
 static void configure_cb(void* /*data*/, struct wl_shell_surface* /*shell_surface*/, uint32_t /*edges*/, int32_t /*width*/, int32_t /*height*/) {}
 
 static void popupDone_cb(void* /*data*/, struct wl_shell_surface* /*shell_surface*/) {}
 
 static void redraw(void* data, struct wl_callback* callback, uint32_t time)
 {
 	printf("Redrawing\n");
 }
 
 static const struct wl_callback_listener FrameListener = { redraw };
 
 static void configure_cb(void* data, struct wl_callback* callback, uint32_t time)
 {
 	if (callback == NULL)
 		redraw(data, NULL, time);
 }
 
 static struct wl_callback_listener ConfigureCbListener = {
 	configure_cb,
 };
 
 static const struct wl_shell_surface_listener shellSurfaceListeners = { ping_cb, configure_cb, popupDone_cb };
 
 bool initWaylandConnection(OpenGLESAPI& helloAPI)
 {
 	if ((helloAPI._surfaceData.deviceContext = wl_display_connect(NULL)) == NULL)
 	{
 		printf("Failed to connect to Wayland display!");
 		return false;
 	}
 
 	if ((wlRegistry = wl_display_get_registry(helloAPI._surfaceData.deviceContext)) == NULL)
 	{
 		printf("Failed to get Wayland registry!");
 		return false;
 	}
 
 	wl_registry_add_listener(wlRegistry, &registryListener, NULL);
 	wl_display_dispatch(helloAPI._surfaceData.deviceContext);
 	if (!wlCompositor) // || !internalOS.seat)
 	{
 		printf("Could not bind Wayland protocols!");
 		return false;
 	}
 
 	return true;
 }
 
 bool initializeWindow(OpenGLESAPI& helloAPI)
 {
 	if (!initWaylandConnection(helloAPI))
 		return false;
 
 	wlSurface = wl_compositor_create_surface(wlCompositor);
 	if (wlSurface == NULL)
 	{
 		printf("Failed to create Wayland surface");
 		return false;
 	}
 
 	wlShellSurface = wl_shell_get_shell_surface(wlShell, wlSurface);
 	if (wlShellSurface == NULL)
 	{
 		printf("Failed to get Wayland shell surface");
 		return false;
 	}
 
 	wl_shell_surface_add_listener(wlShellSurface, &shellSurfaceListeners, NULL);
 	wl_shell_surface_set_toplevel(wlShellSurface);
 	wl_shell_surface_set_title(wlShellSurface, "OpenGLESHelloApi");
 	return true;
 }
 
 void releaseWaylandConnection(wl_display* dislay)
 {
 	wl_shell_surface_destroy(wlShellSurface);
 	wl_surface_destroy(wlSurface);
 	if (wlPointer)
 	{
 		wl_pointer_destroy(wlPointer);
 	}
 	wl_seat_destroy(wlSeat);
 	wl_shell_destroy(wlShell);
 	wl_compositor_destroy(wlCompositor);
 	wl_registry_destroy(wlRegistry);
 	wl_display_disconnect(dislay);
 }
 
 /*!*********************************************************************************************************************
 \param[in]			argc           Number of arguments passed to the application, ignored.
 \param[in]			argv           Command line strings passed to the application, ignored.
 \return		Result code to send to the Operating System
 \brief	Main function of the program, executes other functions.
 ***********************************************************************************************************************/
 int main(int /*argc*/, char** /*argv*/)
 {
 	OpenGLESAPI helloAPI;
 

Get access to a native display.

 	initializeWindow(helloAPI);
 
 	helloAPI._surfaceData.window = wl_egl_window_create(wlSurface, helloAPI._surfaceData.width, helloAPI._surfaceData.height);
 	if (helloAPI._surfaceData.window == EGL_NO_SURFACE)
 	{
 		printf("Can't create egl window\n");
 	}
 	else
 	{
 		printf("Created wl egl window\n");
 	}
 

Setup OpenGL ES state and objects.

 	helloAPI.initializeEGL();
 	helloAPI.initializeGLES();
 

Renders a triangle for 800 frames using the state setup in the previous function.

 	for (int i = 0; i < 800; ++i)
 	{
 		wl_display_dispatch_pending(helloAPI._surfaceData.deviceContext);
 		if (!helloAPI.drawFrame() || !helloAPI.swapEGLBuffers())
 		{
 			break;
 		}
 	}
 

Release any resources we created in the Initialise functions.

 	helloAPI.releaseGLState();
 	helloAPI.releaseEGLState();
 

Release the Wayland connection.

 	releaseWaylandConnection(helloAPI._surfaceData.deviceContext);
 

Destroy the eglWindow.

 	return 0;
 }