From ee177d37df85b982d6c528a7b79e3cd9ca9749d6 Mon Sep 17 00:00:00 2001 From: Egor Yusov Date: Mon, 11 Nov 2019 07:42:14 -0800 Subject: Moved Native App from master repository --- NativeApp/src/Android/AndroidAppBase.cpp | 266 +++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 NativeApp/src/Android/AndroidAppBase.cpp (limited to 'NativeApp/src/Android/AndroidAppBase.cpp') diff --git a/NativeApp/src/Android/AndroidAppBase.cpp b/NativeApp/src/Android/AndroidAppBase.cpp new file mode 100644 index 0000000..f3e341c --- /dev/null +++ b/NativeApp/src/Android/AndroidAppBase.cpp @@ -0,0 +1,266 @@ +/* Copyright 2015-2018 Egor Yusov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "AndroidAppBase.h" +#include "Timer.h" + +#include +//#include +//#include +#include +//#include + +namespace Diligent +{ + +int AndroidAppBase::InitDisplay() +{ + if( !initialized_resources_ ) + { + Initialize(); + + LoadResources(); + initialized_resources_ = true; + } + else + { + // initialize OpenGL ES and EGL + if( EGL_SUCCESS != Resume( app_->window ) ) + { + UnloadResources(); + LoadResources(); + } + } + + ShowUI(); + + //tap_camera_.SetFlip( 1.f, -1.f, -1.f ); + //tap_camera_.SetPinchTransformFactor( 2.f, 2.f, 8.f ); + + return 0; +} + +void AndroidAppBase::InitSensors() +{ + sensor_manager_ = ASensorManager_getInstance(); + accelerometer_sensor_ = ASensorManager_getDefaultSensor( sensor_manager_, ASENSOR_TYPE_ACCELEROMETER ); + sensor_event_queue_ = ASensorManager_createEventQueue( sensor_manager_, app_->looper, LOOPER_ID_USER, NULL, NULL ); +} + +// +// Just the current frame in the display. +// +void AndroidAppBase::DrawFrame() +{ + // APP_CMD_CONFIG_CHANGED event is generated seveal frames + // before the screen is actually resized. The only robust way + // to detect window resize is to check it very frame + if(CheckWindowSizeChanged()) + WindowResize(0,0); + + float fFPS; + if( monitor_.Update( fFPS ) ) + { + UpdateFPS( fFPS ); + } + + static Diligent::Timer Timer; + static double PrevTime = Timer.GetElapsedTime(); + auto CurrTime = Timer.GetElapsedTime(); + auto ElapsedTime = CurrTime - PrevTime; + PrevTime = CurrTime; + + Update(CurrTime, ElapsedTime); + + Render(); + + Present(); + //if( EGL_SUCCESS != pRenderDevice_->Present() ) + //{ + // UnloadResources(); + // LoadResources(); + //} +} + + +// +// Process the next input event. +// +int32_t AndroidAppBase::HandleInput( android_app* app, AInputEvent* event ) +{ + AndroidAppBase* eng = (AndroidAppBase*)app->userData; + return eng->HandleInput( event ); +} + +// +// Process the next main command. +// +void AndroidAppBase::HandleCmd( struct android_app* app, int32_t cmd ) +{ + AndroidAppBase* eng = (AndroidAppBase*)app->userData; + switch( cmd ) + { + case APP_CMD_SAVE_STATE: + break; + + case APP_CMD_INIT_WINDOW: + // The window is being shown, get it ready. + if( app->window != NULL ) + { + eng->InitDisplay(); + eng->DrawFrame(); + } + break; + + case APP_CMD_CONFIG_CHANGED: + case APP_CMD_WINDOW_RESIZED: + // This does not work as the screen resizes few frames + // after the event has been received + // eng->WindowResize(0,0); + break; + + case APP_CMD_TERM_WINDOW: + // The window is being hidden or closed, clean it up. + eng->TermDisplay(); + eng->has_focus_ = false; + break; + + case APP_CMD_STOP: + break; + + case APP_CMD_GAINED_FOCUS: + eng->ResumeSensors(); + //Start animation + eng->has_focus_ = true; + break; + + case APP_CMD_LOST_FOCUS: + eng->SuspendSensors(); + // Also stop animating. + eng->has_focus_ = false; + eng->DrawFrame(); + break; + + case APP_CMD_LOW_MEMORY: + //Free up GL resources + eng->TrimMemory(); + break; + } +} + +//------------------------------------------------------------------------- +//Sensor handlers +//------------------------------------------------------------------------- +void AndroidAppBase::ProcessSensors( int32_t id ) +{ + // If a sensor has data, process it now. + if( id == LOOPER_ID_USER ) + { + if( accelerometer_sensor_ != NULL ) + { + ASensorEvent event; + while( ASensorEventQueue_getEvents( sensor_event_queue_, &event, 1 ) > 0 ) + { + } + } + } +} + +void AndroidAppBase::ResumeSensors() +{ + // When our app gains focus, we start monitoring the accelerometer. + if( accelerometer_sensor_ != NULL ) + { + ASensorEventQueue_enableSensor( sensor_event_queue_, accelerometer_sensor_ ); + // We'd like to get 60 events per second (in us). + ASensorEventQueue_setEventRate( sensor_event_queue_, accelerometer_sensor_, + (1000L / 60) * 1000 ); + } +} + +void AndroidAppBase::SuspendSensors() +{ + // When our app loses focus, we stop monitoring the accelerometer. + // This is to avoid consuming battery while not being used. + if( accelerometer_sensor_ != NULL ) + { + ASensorEventQueue_disableSensor( sensor_event_queue_, accelerometer_sensor_ ); + } +} + +//------------------------------------------------------------------------- +//Misc +//------------------------------------------------------------------------- +void AndroidAppBase::SetState( android_app* state, const char* native_activity_class_name ) +{ + app_ = state; + native_activity_class_name_ = native_activity_class_name; + doubletap_detector_.SetConfiguration( app_->config ); + drag_detector_.SetConfiguration( app_->config ); + pinch_detector_.SetConfiguration( app_->config ); +} + +bool AndroidAppBase::IsReady() +{ + if( has_focus_ ) + return true; + + return false; +} + +//void Engine::TransformPosition( ndk_helper::Vec2& vec ) +//{ +// vec = ndk_helper::Vec2( 2.0f, 2.0f ) * vec +// / ndk_helper::Vec2( pDeviceContext_->GetMainBackBufferDesc().Width, pDeviceContext_->GetMainBackBufferDesc().Height ) +// - ndk_helper::Vec2( 1.f, 1.f ); +//} + +void AndroidAppBase::ShowUI() +{ + JNIEnv *jni; + app_->activity->vm->AttachCurrentThread( &jni, NULL ); + + //Default class retrieval + jclass clazz = jni->GetObjectClass( app_->activity->clazz ); + jmethodID methodID = jni->GetMethodID( clazz, "showUI", "()V" ); + jni->CallVoidMethod( app_->activity->clazz, methodID ); + + app_->activity->vm->DetachCurrentThread(); + return; +} + +void AndroidAppBase::UpdateFPS( float fFPS ) +{ + JNIEnv *jni; + app_->activity->vm->AttachCurrentThread( &jni, NULL ); + + //Default class retrieval + jclass clazz = jni->GetObjectClass( app_->activity->clazz ); + jmethodID methodID = jni->GetMethodID( clazz, "updateFPS", "(F)V" ); + jni->CallVoidMethod( app_->activity->clazz, methodID, fFPS ); + + app_->activity->vm->DetachCurrentThread(); + return; +} + +} -- cgit v1.2.3