/** * This is the main entry point of a native application that is using * android_native_app_glue. It runs in its own thread, with its own * event loop for receiving input events and doing other things. */ void android_main(struct android_app* app) { if (!app) return; NvAssetLoaderInit((void*)app->activity->assetManager); Engine* engine = new Engine(app); char* commandLine = NULL; if (getCommandLine(engine, commandLine)) { LOGI("Found command line %s", commandLine); // add command line arguments NvTokenizer cmdtok(commandLine); std::string sarg; while (cmdtok.getTokenString(sarg)) engine->m_commandLine.push_back(sarg); } NvAppBase* sdkapp = NvAppFactory(engine); sdkapp->configurationCallback(sDefaultConfig); engine->mEGL = NvEGLUtil::create(localEGLChooser); if (!engine->mEGL) { // if we have a basic EGL failure, we need to exit immediately; nothing else we can do delete sdkapp; sdkapp = NULL; nv_app_force_quit_no_cleanup(app); } NvEGLAppContext* context = new NvEGLAppContext(engine->mEGL); sdkapp->setGLContext(context); // Make sure glue isn't stripped. app_dummy(); // loop waiting for stuff to do. sdkapp->mainLoop(); delete sdkapp; delete engine; NvAssetLoaderShutdown(); }
/** * This is the main entry point of a native application that is using * android_native_app_glue. It runs in its own thread, with its own * event loop for receiving input events and doing other things. */ void android_main(struct android_app* app) { // Make sure glue isn't stripped. app_dummy(); NvEGLUtil* egl = NvEGLUtil::create(); if (!egl) { // if we have a basic EGL failure, we need to exit immediately; nothing else we can do nv_app_force_quit_no_cleanup(app); return; } Engine* engine = new Engine(*egl, app); long lastTime = egl->getSystemTime(); // loop waiting for stuff to do. while (nv_app_status_running(app)) { // Read all pending events. int ident; int events; struct android_poll_source* source; // If not rendering, we will block forever waiting for events. // If animating, we loop until all events are read, then continue // to draw the next frame of animation. while ((ident = ALooper_pollAll(((nv_app_status_focused(app) && engine->isGameplayMode()) ? 1 : 250), NULL, &events, (void**)&source)) >= 0) { // If we timed out, then there are no pending messages if (ident == ALOOPER_POLL_TIMEOUT) break; // Process this event. if (source != NULL) source->process(app, source); // Check if we are exiting. If so, dump out if (!nv_app_status_running(app)) break; engine->looperIteration(ident); } long currentTime = egl->getSystemTime(); // clamp time - it must not go backwards, and we don't // want it to be more than a half second to avoid huge // delays causing issues. Note that we do not clamp to above // zero because some tools will give us zero delta long deltaTime = currentTime - lastTime; if (deltaTime < 0) deltaTime = 0; else if (deltaTime > 500) deltaTime = 500; lastTime = currentTime; // Update the frame, which optionally updates time and animations // and renders engine->updateFrame(nv_app_status_interactable(app), deltaTime); } delete engine; delete egl; }