QNXScreenEntryPoint

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_QNXScreen.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 <sys/time.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <termios.h>
 
 #include <screen/screen.h>
 
 #include "OpenGLESHelloAPI.h"
 
 #if !defined(CONNAME)
 #define CONNAME "/dev/tty"
 #endif
 
 #if !defined(KEYPAD_INPUT)
 #define KEYPAD_INPUT "/dev/con1"
 #endif
 
 uint32_t display;
 screen_context_t screen_context;
 screen_window_t screen_window;
 
 int devfd;
 struct termios termio;
 struct termios termio_orig;
 int keypad_fd;
 int keyboard_fd;
 bool keyboardShiftHeld; // Is one of the shift keys on the keyboard being held down? (Keyboard device only - not terminal).
 
 void initInput()
 {

If this app is in the background, ignore SIGTTIN and SIGTTOU.

 	signal(SIGTTIN, SIG_IGN);
 	signal(SIGTTOU, SIG_IGN);
 

Keyboard handling.

 	if ((devfd = open(CONNAME, O_RDWR | O_NDELAY)) <= 0)
 	{
 		printf("Can't open tty '" CONNAME "'");
 	}
 	else
 	{
 		tcgetattr(devfd, &termio_orig);
 		tcgetattr(devfd, &termio);
 		cfmakeraw(&termio);
 		termio.c_oflag |= OPOST | ONLCR; // Turn back on CR-LF expansion on output.
 		termio.c_cc[VMIN] = 1;
 		termio.c_cc[VTIME] = 0;
 
 		if (tcsetattr(devfd, TCSANOW, &termio) == -1)
 		{
 			printf("Can't set tty attributes for '" CONNAME "'");
 		}
 	}
 

Keypad handling.

 	if ((keypad_fd = open(KEYPAD_INPUT, O_RDONLY | O_NDELAY)) <= 0)
 	{
 		printf("Can't open keypad input device (%s)\n", KEYPAD_INPUT);
 	}
 

Construct read and write path.

 	pid_t ourPid = getpid();
 	char *exePath, srcLink[64];
 	int len = 256;
 	int res;
 	FILE* fp;
 
 	sprintf(srcLink, "/proc/%d/exefile", ourPid);
 	exePath = 0;
 
 	do
 	{
 		len *= 2;
 		delete[] exePath;
 		exePath = new char[len];
 		fp = fopen(srcLink, "r");
 		fgets(exePath, len, fp);
 		res = strlen(exePath);
 		fclose(fp);
 
 		if (res < 0)
 		{
 			printf("Readlink %s failed. The application name, read path and write path have not been set.\n", exePath);
 			break;
 		}
 	} while (res >= len);
 
 	if (res >= 0)
 	{
 		exePath[res] = '\0'; // Null-terminate readlink's result.
 	}
 
 	delete[] exePath;
 
 	/*
 	 Remove the blinking cursor on a screen.
 
 	 This is the equivalent of:
 	 echo -n -e "\033[?25l" > /dev/tty0
 
 	 The above command can be undone with:
 	 echo -n -e "\033[?25h" > /dev/tty0
 	 */
 	FILE* tty = 0;
 	tty = fopen("/dev/tty0", "w");
 	if (tty != 0)
 	{
 		const char txt[] = { 27 /* the ESCAPE ASCII character */
 			,
 			'[', '?', '2', '5', 'l', 0 };
 
 		fprintf(tty, "%s", txt);
 		fclose(tty);
 	}
 }
 
 bool initializeWindow()
 {
 	int size[2];
 	int ePixelFormat;
 	int usage = SCREEN_USAGE_NATIVE;
 
 	screen_create_context(&screen_context, SCREEN_APPLICATION_CONTEXT);
 
 	if (screen_context == 0)
 	{
 		printf("Failed to Create Screen Context");
 		return false;
 	}
 
 	screen_create_window(&screen_window, screen_context);
 
 	if (screen_window == 0)
 	{
 		printf("Failed to Create Screen Window");
 		return false;
 	}
 
 	screen_get_window_property_iv(screen_window, SCREEN_PROPERTY_BUFFER_SIZE, size);
 
 	screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_FORMAT, &ePixelFormat);
 	screen_set_window_property_iv(screen_window, SCREEN_PROPERTY_USAGE, &usage);
 	screen_create_window_buffers(screen_window, 2);
 
 	initInput();
 
 	return true;
 }
 
 void releaseWindow()
 {
 	screen_window = 0;
 	screen_context = 0;
 	display = 0xFFFF;
 
 	close(keyboard_fd);
 	close(keypad_fd);
 }
 
 /*!*********************************************************************************************************************
 \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._surfaceData.deviceContext = (EGLNativeDisplayType)screen_context;
 	helloAPI._surfaceData.window = (EGLNativeWindowType)screen_window;
 
 	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;
 		}
 	}
 
 	helloAPI.releaseGLState();
 	helloAPI.releaseEGLState();
 

Destroy the eglWindow.

 	return 0;
 }