LinuxX11EntryPoint

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

 /*!*********************************************************************************************************************
 \File         OpenGLESHelloAPI_LinuxX11.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 initialize 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"
 
 /*!*********************************************************************************************************************
 \param[in]			nativeDisplay               Handle to the display
 \param[in]			error                       The error event to handle
 \return		Result code to send to the X window system
 \brief	Processes event messages for the main window
 ***********************************************************************************************************************/
 int handleX11Errors(Display* nativeDisplay, XErrorEvent* error)
 {

Get the X Error

 	char errorStringBuffer[256];
 	XGetErrorText(nativeDisplay, error->error_code, errorStringBuffer, 256);
 

Print the error

 	printf("%s", errorStringBuffer);
 

Exit the application

 	exit(-1);
 	return 0;
 }
 
 /*!*********************************************************************************************************************
 \param[out]		nativeDisplay				Native display to create
 \return		Whether the function succeeded or not.
 \brief	Creates a native isplay for the application to render into.
 ***********************************************************************************************************************/
 bool createNativeDisplay(Display** nativeDisplay)
 {

Check for a valid display

 	if (!nativeDisplay)
 	{
 		return false;
 	}
 

Open the display

 	*nativeDisplay = XOpenDisplay(0);
 	if (!*nativeDisplay)
 	{
 		printf("Error: Unable to open X display\n");
 		return false;
 	}
 	return true;
 }
 
 /*!*********************************************************************************************************************
 \param[in]			nativeDisplay				Native display used by the application
 \param[out]		nativeWindow			    Native window type to create
 \return		Whether the function succeeded or not.
 \brief	Creates a native window for the application to render into.
 ***********************************************************************************************************************/
 bool createNativeWindow(Display* nativeDisplay, Window* nativeWindow SurfaceData surfaceData)
 {

Get the default screen for the display

 	int defaultScreen = XDefaultScreen(nativeDisplay);
 

Get the default depth of the display

 	int defaultDepth = DefaultDepth(nativeDisplay, defaultScreen);
 

Select a visual info

 	std::unique_ptr<XVisualInfo> visualInfo(new XVisualInfo);
 	XMatchVisualInfo(nativeDisplay, defaultScreen, defaultDepth, TrueColor, visualInfo.get());
 	if (!visualInfo.get())
 	{
 		printf("Error: Unable to acquire visual\n");
 		return false;
 	}
 

Get the root window for the display and default screen

 	Window rootWindow = RootWindow(nativeDisplay, defaultScreen);
 

Create a color map from the display, root window and visual info

 	Colormap colorMap = XCreateColormap(nativeDisplay, rootWindow, visualInfo->visual, AllocNone);
 

Now setup the final window by specifying some attributes

 	XSetWindowAttributes windowAttributes;
 

Set the color map that was just created

 	windowAttributes.colormap = colorMap;
 

Set events that will be handled by the app, add to these for other events.

 	windowAttributes.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask;
 

Create the window

 	*nativeWindow = XCreateWindow(nativeDisplay, // The display used to create the window
 		rootWindow, // The parent (root) window - the desktop
 		0, // The horizontal (x) origin of the window
 		0, // The vertical (y) origin of the window
 		surfaceData.width, // The width of the window
 		surfaceData.height, // The height of the window
 		0, // Border size - set it to zero
 		visualInfo->depth, // Depth from the visual info
 		InputOutput, // Window type - this specifies InputOutput.
 		visualInfo->visual, // Visual to use
 		CWEventMask | CWColormap, // Mask specifying these have been defined in the window attributes
 		&windowAttributes); // Pointer to the window attribute structure
 

Make the window viewable by mapping it to the display

 	XMapWindow(nativeDisplay, *nativeWindow);
 

Set the window title

 	XStoreName(nativeDisplay, *nativeWindow, ApplicationName);
 

Setup the window manager protocols to handle window deletion events

 	Atom windowManagerDelete = XInternAtom(nativeDisplay, "WM_DELETE_WINDOW", True);
 	XSetWMProtocols(nativeDisplay, *nativeWindow, &windowManagerDelete, 1);
 
 	return true;
 }
 
 /*!*********************************************************************************************************************
 \param[in]			nativeDisplay               The native display to release
 \param[in]			nativeWindow                The native window to destroy
 \brief	Releases all resources allocated by the windowing system
 ***********************************************************************************************************************/
 void releaseNativeResources(Display* nativeDisplay, Window nativeWindow)
 {

Destroy the window

 	if (nativeWindow)
 	{
 		XDestroyWindow(nativeDisplay, nativeWindow);
 	}
 

Release the display.

 	if (nativeDisplay)
 	{
 		XCloseDisplay(nativeDisplay);
 	}
 }
 
 /*!*********************************************************************************************************************
 \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*/)
 {

HelloAPI handle

 	OpenGLESAPI helloAPI;
 

Get access to a native display

 	createNativeDisplay(&helloAPI._surfaceData.deviceContext);
 

Setup the windowing system, create a window

 	createNativeWindow(helloAPI._surfaceData.deviceContext, &helloAPI._surfaceData.window);
 

Setup OpenGLES 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)
 	{
 		if (!helloAPI.drawFrame() || !helloAPI.swapEGLBuffers())
 		{
 			break;
 		}
 

Check for messages from the windowing system.

 		int numberOfMessages = XPending(helloAPI._surfaceData.deviceContext);
 		for (int i = 0; i < numberOfMessages; i++)
 		{
 			XEvent event;
 			XNextEvent(helloAPI._surfaceData.deviceContext, &event);
 
 			switch (event.type)
 			{

Exit on window close

 			case ClientMessage:

Exit on mouse click

 			case ButtonPress:
 			case DestroyNotify:
 				return false;
 			default:
 				break;
 			}
 		}
 	}
 

Release any resources we created in the Initialize functions

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

Release the windowing system resources

 	releaseNativeResources(helloAPI._surfaceData.deviceContext, helloAPI._surfaceData.window);
 

Destroy the eglWindow

 	return 0;
 }