WindowsEntryPoint

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_Windows.cpp
 \Title        OpenGL ES 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: WinMain
 ***********************************************************************************************************************/
 
 #include "OpenGLESHelloAPI.h"
 

Windows class name to register.

 #define WINDOW_CLASS_NAME _T("PVROpenGLESHelloAPI")
 

Name of the application.

 #define APPLICATION_NAME _T("HelloAPI")
 

Title to display for errors.

 #define ERROR_TITLE _T("Error")
 

Variable set by the message handler to finish the demo.

 bool HasUserQuit = false;
 
 /*!*********************************************************************************************************************
 \param			nativeWindow                Handle to the window
 \param			message                     The message to handle
 \param			windowParameters            Additional message information
 \param			longWindowParameters        Additional message information
 \return	Result code to send to the OS
 \brief	Processes event messages for the main window
 ***********************************************************************************************************************/
 LRESULT CALLBACK handleWindowMessages(HWND nativeWindow, UINT message, WPARAM windowParameters, LPARAM longWindowParameters)
 {
 	switch (message)
 	{
 	case WM_SYSCOMMAND:

Handle two system messages: screen saving and monitor power. These need to be prevented while rendering for a short time.

 		{
 			switch (windowParameters)
 			{
 			case SC_SCREENSAVE:
 			case SC_MONITORPOWER:
 			{

Return 0 to let Windows know not to sleep or turn the monitor off right now.

 				return 0;
 			}
 			}
 			break;
 		}
 	case WM_CLOSE:

Handle the close message when a user clicks the quit icon of the window.

 		{

Tell the demo that it should stop rendering.

 			HasUserQuit = true;
 

Post a quit message.

 			PostQuitMessage(0);
 

Return 1 to let Windows know the message has been successfully handled.

 			return 1;
 		}
 	}
 

Calls the default window procedure for messages not handled.

 	return DefWindowProc(nativeWindow, message, windowParameters, longWindowParameters);
 }
 
 /*!*********************************************************************************************************************
 \param		applicationInstance		    Specific instance of the application
 \param[out]	nativeWindow			    Native window type to create
 \param[out]	deviceContext			    Native device context to create
 \return	Whether the function succeeded or not.
 \brief	Creates a native window and display for the application to render into.
 ***********************************************************************************************************************/
 bool createWindowAndDisplay(HINSTANCE applicationInstance, HWND& nativeWindow, HDC& deviceContext, SurfaceData surfaceData)
 {

Describe the native window in a window class structure.

 	WNDCLASS nativeWindowDescription;
 	nativeWindowDescription.style = CS_HREDRAW | CS_VREDRAW;
 	nativeWindowDescription.lpfnWndProc = handleWindowMessages;
 	nativeWindowDescription.cbClsExtra = 0;
 	nativeWindowDescription.cbWndExtra = 0;
 	nativeWindowDescription.hInstance = applicationInstance;
 	nativeWindowDescription.hIcon = LoadIcon(applicationInstance, "ICON");
 	nativeWindowDescription.hCursor = 0;
 	nativeWindowDescription.lpszMenuName = 0;
 	nativeWindowDescription.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
 	nativeWindowDescription.lpszClassName = WINDOW_CLASS_NAME;
 

Register the windows class with the OS.

 	ATOM registerClass = RegisterClass(&nativeWindowDescription);
 	if (!registerClass)
 	{
 		MessageBox(0, _T("Failed to register the window class"), ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION);
 	}
 

Create a rectangle describing the area of the window.

 	RECT windowRectangle;
 	SetRect(&windowRectangle, 0, 0, surfaceData.width, surfaceData.height);
 	AdjustWindowRectEx(&windowRectangle, WS_CAPTION | WS_SYSMENU, false, 0);
 

Create the window from the available information.

 	nativeWindow = CreateWindow(WINDOW_CLASS_NAME, APPLICATION_NAME, WS_VISIBLE | WS_SYSMENU, CW_USEDEFAULT, CW_USEDEFAULT, windowRectangle.right - windowRectangle.left,
 		windowRectangle.bottom - windowRectangle.top, NULL, NULL, applicationInstance, NULL);
 	if (!nativeWindow)
 	{
 		MessageBox(0, _T("Failed to create the window"), ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION);
 		return false;
 	}
 

Get the associated device context from the window.

 	deviceContext = GetDC(nativeWindow);
 	if (!deviceContext)
 	{
 		MessageBox(nativeWindow, _T("Failed to create the device context"), ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION);
 		return false;
 	}
 	return true;
 }
 
 /*!*********************************************************************************************************************
 \param			nativeWindow				The native window to release
 \param			deviceContext				The native display to release
 \brief	Releases all resources allocated by the windowing system.
 ***********************************************************************************************************************/
 void releaseWindowAndDisplay(HWND nativeWindow, HDC deviceContext)
 {

Release the device context.

 	if (deviceContext)
 	{
 		ReleaseDC(nativeWindow, deviceContext);
 	}
 

Destroy the window.

 	if (nativeWindow)
 	{
 		DestroyWindow(nativeWindow);
 	}
 }
 
 /*!*********************************************************************************************************************
 \param			applicationInstance         Application instance created by the Operating System
 \param			previousInstance            Always NULL
 \param			commandLineString           Command line std::string passed from the Operating System, ignored.
 \param			showCommand                 Specifies how the window is to be shown, ignored.
 \return	Result code to send to the Operating System
 \brief	Main function of the program, executes other functions.
 ***********************************************************************************************************************/
 int WINAPI WinMain(HINSTANCE applicationInstance, HINSTANCE previousInstance, TCHAR* /*commandLineString*/, int /*showCommand*/)
 {

Windows variables

 	OpenGLESAPI helloAPI;
 

Setup the windowing system, getting a window and a display.

 	createWindowAndDisplay(applicationInstance, helloAPI._surfaceData.window, helloAPI._surfaceData.deviceContext, helloAPI._surfaceData);
 

Setup OpenGL ES state and objects.

 	helloAPI.initializeEGL();
 	helloAPI.initializeGLES();
 
 	int i = 0;

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

 	for (uint32_t i = 0; i < 800; ++i)
 	{
 		if (!helloAPI.drawFrame() || !helloAPI.swapEGLBuffers())
 		{

The message handler setup for the window system will signal this variable when the window is closed, and close the application.

 			if (HasUserQuit)
 			{
 				break;
 			}
 			break;
 		}
 

Check for messages from the windowing system. These will pass through the callback registered earlier.

 		MSG eventMessage;
 		PeekMessage(&eventMessage, helloAPI._surfaceData.window, NULL, NULL, PM_REMOVE);
 		TranslateMessage(&eventMessage);
 		DispatchMessage(&eventMessage);
 	}
 

Release any resources created in the Initialize functions.

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

Release the windowing system resources.

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

Destroy the eglWindow.

 	return 0;
 }