Android Entry Point#

/*!***************************************************************************
 \File         OpenGLESHelloAPI_Android.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: android_main
 *****************************************************************************/

 #include "OpenGLESHelloAPI.h"

 #include <stdio.h>
 #include <android/log.h>
 #include <android/window.h>
 #include <android_native_app_glue.h>

Data structure containing variables used in the application.

struct HelloAPIData
{
   OpenGLESAPI helloAPI;

Should the app still be animating?

bool isAnimating;

Is everything required initialised?

bool isInitialized;

Has an error occurred?

   bool errorOccurred;
};

/*!***************************************************************************
\brief Handle Android commands
\param[in] application Application structure passed in from the OS
\param[in] commandID Command Id to be handle
*****************************************************************************/
static void HandleAndroidCommands(struct android_app* application, int32_t commandID)
{
   HelloAPIData* applicationData = (HelloAPIData*)application->userData;

   switch (commandID)
   {
   case APP_CMD_INIT_WINDOW:

The window is being shown, get it ready.

if (application->window != NULL)
{

Get width and height of screen.

           applicationData->helloAPI._surfaceData.width = ANativeWindow_getWidth(application->window);
           applicationData->helloAPI._surfaceData.height = ANativeWindow_getHeight(application->window);
           applicationData->helloAPI._surfaceData.window = application->window;

           if (!applicationData->helloAPI.initializeEGL() || !applicationData->helloAPI.initializeGLES())
           {
               applicationData->errorOccurred = true;
           }
           else
           {
               applicationData->isInitialized = true;
           }
       }
   case APP_CMD_RESUME:
       applicationData->isAnimating = true;
       break;

   case APP_CMD_TERM_WINDOW:
   {
       applicationData->helloAPI.releaseGLState();
       applicationData->helloAPI.releaseEGLState();
       applicationData->isInitialized = false;
   }
   case APP_CMD_PAUSE:
   case APP_CMD_SAVE_STATE:
       applicationData->isAnimating = false;
       break;
   }
}

/*!***************************************************************************
\param[in]     application                 Application structure passed in from the OS
\brief Main function of the program, executes other functions.
*****************************************************************************/
void android_main(struct android_app* application)
{
   OpenGLESAPI HelloAPI;

Application Data.

HelloAPIData applicationData = { HelloAPI, false, false, false };

Set the user data of the application to our application data.

application->userData = &applicationData;

Set the command handler to the custom handling function.

application->onAppCmd = HandleAndroidCommands;

Event handling variables.

int eventIdentifier;
int events;
struct android_poll_source* pollSource;

Renders a triangle while the Android application is active.

while (true)
{

Block while there are events to process or if not animating.

while ((eventIdentifier = ALooper_pollAll(applicationData.isInitialized && applicationData.isAnimating ? 0 : -1, NULL, &events, (void**)&pollSource)) >= 0)
{
    if (pollSource != NULL)
    {
        pollSource->process(application, pollSource);
    }

Check for early exit that has not been handled by the Android commands system.

    if (application->destroyRequested != 0)
    {
        applicationData.helloAPI.releaseEGLState();
        applicationData.helloAPI.releaseGLState();
        return;
    }
}

Once events are processed, and assuming that animation is going to occur, continue animating.

       if (applicationData.isAnimating)
       {
           if (!applicationData.helloAPI.drawFrame())
           {
               break;
           }

           if (!applicationData.helloAPI.swapEGLBuffers())
           {
               break;
           }
       }
   }
}