added android project and linked to engine source with successful compilation
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,3 +6,7 @@ engine.vcxproj.user
|
|||||||
ipch/
|
ipch/
|
||||||
engine.VC.opendb
|
engine.VC.opendb
|
||||||
engine.sdf
|
engine.sdf
|
||||||
|
android/build/
|
||||||
|
android/.gradle/
|
||||||
|
android/.externalNativeBuild/
|
||||||
|
|
||||||
|
|||||||
54
android/CMakeLists.txt
Normal file
54
android/CMakeLists.txt
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Sets the minimum version of CMake required to build your native library.
|
||||||
|
# This ensures that a certain set of CMake features is available to
|
||||||
|
# your build.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.4.1)
|
||||||
|
|
||||||
|
# build native_app_glue as a static lib
|
||||||
|
add_library(
|
||||||
|
app-glue STATIC
|
||||||
|
${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# Specifies a library name, specifies whether the library is STATIC or
|
||||||
|
# SHARED, and provides relative paths to the source code. You can
|
||||||
|
# define multiple libraries by adding multiple add.library() commands,
|
||||||
|
# and CMake builds them for you. When you build your app, Gradle
|
||||||
|
# automatically packages shared libraries with your APK.
|
||||||
|
|
||||||
|
# now build app's shared lib
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++14")
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
native-lib SHARED
|
||||||
|
../libs/yoga/yoga/YGNodeList.c
|
||||||
|
../libs/yoga/yoga/Yoga.c
|
||||||
|
../libs/tinyxml2/tinyxml2.cpp
|
||||||
|
src/main/cpp/main.cpp
|
||||||
|
../engine/pch.cpp
|
||||||
|
../engine/util.cpp
|
||||||
|
../engine/image.cpp
|
||||||
|
../engine/texture.cpp
|
||||||
|
../engine/font.cpp
|
||||||
|
../engine/shader.cpp
|
||||||
|
../engine/shape.cpp
|
||||||
|
../engine/layout.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(native-lib PRIVATE
|
||||||
|
${ANDROID_NDK}/sources/android/native_app_glue
|
||||||
|
../libs/glm
|
||||||
|
../libs/tinyxml2
|
||||||
|
../libs/yoga
|
||||||
|
../libs/stb
|
||||||
|
)
|
||||||
|
|
||||||
|
# add lib dependencies
|
||||||
|
target_link_libraries(
|
||||||
|
native-lib
|
||||||
|
android
|
||||||
|
app-glue
|
||||||
|
EGL
|
||||||
|
GLESv3
|
||||||
|
log
|
||||||
|
)
|
||||||
64
android/build.gradle
Normal file
64
android/build.gradle
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.2.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apply plugin: 'android'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 'android-19'
|
||||||
|
buildToolsVersion '24.0.3'
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
// This block is different from the one you use to link Gradle
|
||||||
|
// to your CMake or ndk-build script.
|
||||||
|
externalNativeBuild {
|
||||||
|
// For ndk-build, instead use the ndkBuild block
|
||||||
|
cmake {
|
||||||
|
// Passes optional arguments to CMake.
|
||||||
|
//arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang"
|
||||||
|
// Sets optional flags for the C compiler.
|
||||||
|
//cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2"
|
||||||
|
// Sets a flag to enable format macro constants for the C++ compiler.
|
||||||
|
//cppFlags "-D__STDC_FORMAT_MACROS"
|
||||||
|
arguments '-DANDROID_PLATFORM=android-19',
|
||||||
|
'-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=gnustl_static'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ndk {
|
||||||
|
// Specifies the ABI configurations of your native
|
||||||
|
// libraries Gradle should build and package with your APK.
|
||||||
|
// abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
|
||||||
|
abiFilters 'armeabi-v7a'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// productFlavors {
|
||||||
|
// main {
|
||||||
|
// externalNativeBuild {
|
||||||
|
// cmake {
|
||||||
|
// targets "native-lib-demo"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFile getDefaultProguardFile('proguard-android.txt')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encapsulates your external native build configurations.
|
||||||
|
externalNativeBuild {
|
||||||
|
// Encapsulates your CMake build configurations.
|
||||||
|
cmake {
|
||||||
|
// Provides a relative path to your CMake build script.
|
||||||
|
path "CMakeLists.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1
android/gradle.properties
Normal file
1
android/gradle.properties
Normal file
@@ -0,0 +1 @@
|
|||||||
|
org.gradle.jvmargs=-Xmx1536M
|
||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Wed Apr 10 15:27:10 PDT 2013
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=http\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
|
||||||
164
android/gradlew
vendored
Executable file
164
android/gradlew
vendored
Executable file
@@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn ( ) {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die ( ) {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched.
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >&-
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >&-
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||||
|
function splitJvmOpts() {
|
||||||
|
JVM_OPTS=("$@")
|
||||||
|
}
|
||||||
|
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||||
|
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||||
|
|
||||||
|
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||||
90
android/gradlew.bat
vendored
Normal file
90
android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windowz variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
goto execute
|
||||||
|
|
||||||
|
:4NT_args
|
||||||
|
@rem Get arguments from the 4NT Shell from JP Software
|
||||||
|
set CMD_LINE_ARGS=%$
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
11
android/local.properties
Normal file
11
android/local.properties
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# This file is automatically generated by Android Tools.
|
||||||
|
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
|
||||||
|
#
|
||||||
|
# This file must *NOT* be checked into Version Control Systems,
|
||||||
|
# as it contains information specific to your local configuration.
|
||||||
|
|
||||||
|
# location of the SDK. This is only used by Ant
|
||||||
|
# For customization when using a Version Control System, please read the
|
||||||
|
# header note.
|
||||||
|
sdk.dir=/Users/omimac/android-sdk-macosx
|
||||||
|
ndk.dir=/Users/omimac/android-ndk-r13
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.omigamedev;
|
||||||
|
|
||||||
|
import android.test.ActivityInstrumentationTestCase2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a simple framework for a test of an Application. See
|
||||||
|
* {@link android.test.ApplicationTestCase ApplicationTestCase} for more information on
|
||||||
|
* how to write and extend Application tests.
|
||||||
|
* <p/>
|
||||||
|
* To run this test, you can type:
|
||||||
|
* adb shell am instrument -w \
|
||||||
|
* -e class com.omigamedev.DummyActivityTest \
|
||||||
|
* com.omigamedev.tests/android.test.InstrumentationTestRunner
|
||||||
|
*/
|
||||||
|
public class DummyActivityTest extends ActivityInstrumentationTestCase2<DummyActivity> {
|
||||||
|
|
||||||
|
public DummyActivityTest() {
|
||||||
|
super("com.omigamedev", DummyActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
android/src/main/AndroidManifest.xml
Normal file
17
android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
package="com.omigamedev"
|
||||||
|
android:versionCode="1"
|
||||||
|
android:versionName="1.0">
|
||||||
|
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
|
||||||
|
<activity android:name="android.app.NativeActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
|
<meta-data android:name="android.app.lib_name"
|
||||||
|
android:value="native-lib" />
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
|
</manifest>
|
||||||
338
android/src/main/cpp/main.cpp
Executable file
338
android/src/main/cpp/main.cpp
Executable file
@@ -0,0 +1,338 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2010 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
//BEGIN_INCLUDE(all)
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <memory>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
|
#include <android/sensor.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <android_native_app_glue.h>
|
||||||
|
|
||||||
|
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
|
||||||
|
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Our saved state data.
|
||||||
|
*/
|
||||||
|
struct saved_state {
|
||||||
|
float angle;
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shared state for our app.
|
||||||
|
*/
|
||||||
|
struct engine {
|
||||||
|
struct android_app* app;
|
||||||
|
|
||||||
|
ASensorManager* sensorManager;
|
||||||
|
const ASensor* accelerometerSensor;
|
||||||
|
ASensorEventQueue* sensorEventQueue;
|
||||||
|
|
||||||
|
int animating;
|
||||||
|
EGLDisplay display;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
int32_t width;
|
||||||
|
int32_t height;
|
||||||
|
struct saved_state state;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize an EGL context for the current display.
|
||||||
|
*/
|
||||||
|
static int engine_init_display(struct engine* engine) {
|
||||||
|
// initialize OpenGL ES and EGL
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Here specify the attributes of the desired configuration.
|
||||||
|
* Below, we select an EGLConfig with at least 8 bits per color
|
||||||
|
* component compatible with on-screen windows
|
||||||
|
*/
|
||||||
|
const EGLint attribs[] = {
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLint w, h, dummy, format;
|
||||||
|
EGLint numConfigs;
|
||||||
|
EGLConfig config;
|
||||||
|
EGLSurface surface;
|
||||||
|
EGLContext context;
|
||||||
|
|
||||||
|
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
|
||||||
|
eglInitialize(display, 0, 0);
|
||||||
|
|
||||||
|
/* Here, the application chooses the configuration it desires.
|
||||||
|
* find the best match if possible, otherwise use the very first one
|
||||||
|
*/
|
||||||
|
eglChooseConfig(display, attribs, nullptr,0, &numConfigs);
|
||||||
|
std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]);
|
||||||
|
assert(supportedConfigs);
|
||||||
|
eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs);
|
||||||
|
assert(numConfigs);
|
||||||
|
auto i = 0;
|
||||||
|
for (; i < numConfigs; i++) {
|
||||||
|
auto& cfg = supportedConfigs[i];
|
||||||
|
EGLint r, g, b, d;
|
||||||
|
if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) &&
|
||||||
|
eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) &&
|
||||||
|
eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) &&
|
||||||
|
eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) &&
|
||||||
|
r == 8 && g == 8 && b == 8 && d == 0 ) {
|
||||||
|
|
||||||
|
config = supportedConfigs[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == numConfigs) {
|
||||||
|
config = supportedConfigs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
|
||||||
|
* guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
|
||||||
|
* As soon as we picked a EGLConfig, we can safely reconfigure the
|
||||||
|
* ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
|
||||||
|
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
|
||||||
|
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
|
||||||
|
context = eglCreateContext(display, config, NULL, NULL);
|
||||||
|
|
||||||
|
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
|
||||||
|
LOGW("Unable to eglMakeCurrent");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
eglQuerySurface(display, surface, EGL_WIDTH, &w);
|
||||||
|
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
|
||||||
|
|
||||||
|
engine->display = display;
|
||||||
|
engine->context = context;
|
||||||
|
engine->surface = surface;
|
||||||
|
engine->width = w;
|
||||||
|
engine->height = h;
|
||||||
|
engine->state.angle = 0;
|
||||||
|
|
||||||
|
// Check openGL on the system
|
||||||
|
auto opengl_info = {GL_VENDOR, GL_RENDERER, GL_VERSION, GL_EXTENSIONS};
|
||||||
|
for (auto name : opengl_info) {
|
||||||
|
auto info = glGetString(name);
|
||||||
|
LOGI("OpenGL Info: %s", info);
|
||||||
|
}
|
||||||
|
// Initialize GL state.
|
||||||
|
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
//glShadeModel(GL_SMOOTH);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just the current frame in the display.
|
||||||
|
*/
|
||||||
|
static void engine_draw_frame(struct engine* engine) {
|
||||||
|
if (engine->display == NULL) {
|
||||||
|
// No display.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just fill the screen with a color.
|
||||||
|
glClearColor(((float)engine->state.x)/engine->width, engine->state.angle,
|
||||||
|
((float)engine->state.y)/engine->height, 1);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
eglSwapBuffers(engine->display, engine->surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tear down the EGL context currently associated with the display.
|
||||||
|
*/
|
||||||
|
static void engine_term_display(struct engine* engine) {
|
||||||
|
if (engine->display != EGL_NO_DISPLAY) {
|
||||||
|
eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
if (engine->context != EGL_NO_CONTEXT) {
|
||||||
|
eglDestroyContext(engine->display, engine->context);
|
||||||
|
}
|
||||||
|
if (engine->surface != EGL_NO_SURFACE) {
|
||||||
|
eglDestroySurface(engine->display, engine->surface);
|
||||||
|
}
|
||||||
|
eglTerminate(engine->display);
|
||||||
|
}
|
||||||
|
engine->animating = 0;
|
||||||
|
engine->display = EGL_NO_DISPLAY;
|
||||||
|
engine->context = EGL_NO_CONTEXT;
|
||||||
|
engine->surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the next input event.
|
||||||
|
*/
|
||||||
|
static int32_t engine_handle_input(struct android_app* app, AInputEvent* event) {
|
||||||
|
struct engine* engine = (struct engine*)app->userData;
|
||||||
|
if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) {
|
||||||
|
engine->animating = 1;
|
||||||
|
engine->state.x = AMotionEvent_getX(event, 0);
|
||||||
|
engine->state.y = AMotionEvent_getY(event, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the next main command.
|
||||||
|
*/
|
||||||
|
static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
|
||||||
|
struct engine* engine = (struct engine*)app->userData;
|
||||||
|
switch (cmd) {
|
||||||
|
case APP_CMD_SAVE_STATE:
|
||||||
|
// The system has asked us to save our current state. Do so.
|
||||||
|
engine->app->savedState = malloc(sizeof(struct saved_state));
|
||||||
|
*((struct saved_state*)engine->app->savedState) = engine->state;
|
||||||
|
engine->app->savedStateSize = sizeof(struct saved_state);
|
||||||
|
break;
|
||||||
|
case APP_CMD_INIT_WINDOW:
|
||||||
|
// The window is being shown, get it ready.
|
||||||
|
if (engine->app->window != NULL) {
|
||||||
|
engine_init_display(engine);
|
||||||
|
engine_draw_frame(engine);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case APP_CMD_TERM_WINDOW:
|
||||||
|
// The window is being hidden or closed, clean it up.
|
||||||
|
engine_term_display(engine);
|
||||||
|
break;
|
||||||
|
case APP_CMD_GAINED_FOCUS:
|
||||||
|
// When our app gains focus, we start monitoring the accelerometer.
|
||||||
|
if (engine->accelerometerSensor != NULL) {
|
||||||
|
ASensorEventQueue_enableSensor(engine->sensorEventQueue,
|
||||||
|
engine->accelerometerSensor);
|
||||||
|
// We'd like to get 60 events per second (in us).
|
||||||
|
ASensorEventQueue_setEventRate(engine->sensorEventQueue,
|
||||||
|
engine->accelerometerSensor,
|
||||||
|
(1000L/60)*1000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case APP_CMD_LOST_FOCUS:
|
||||||
|
// When our app loses focus, we stop monitoring the accelerometer.
|
||||||
|
// This is to avoid consuming battery while not being used.
|
||||||
|
if (engine->accelerometerSensor != NULL) {
|
||||||
|
ASensorEventQueue_disableSensor(engine->sensorEventQueue,
|
||||||
|
engine->accelerometerSensor);
|
||||||
|
}
|
||||||
|
// Also stop animating.
|
||||||
|
engine->animating = 0;
|
||||||
|
engine_draw_frame(engine);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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* state) {
|
||||||
|
struct engine engine;
|
||||||
|
|
||||||
|
// Make sure glue isn't stripped.
|
||||||
|
app_dummy();
|
||||||
|
|
||||||
|
memset(&engine, 0, sizeof(engine));
|
||||||
|
state->userData = &engine;
|
||||||
|
state->onAppCmd = engine_handle_cmd;
|
||||||
|
state->onInputEvent = engine_handle_input;
|
||||||
|
engine.app = state;
|
||||||
|
|
||||||
|
// Prepare to monitor accelerometer
|
||||||
|
engine.sensorManager = ASensorManager_getInstance();
|
||||||
|
engine.accelerometerSensor = ASensorManager_getDefaultSensor(
|
||||||
|
engine.sensorManager,
|
||||||
|
ASENSOR_TYPE_ACCELEROMETER);
|
||||||
|
engine.sensorEventQueue = ASensorManager_createEventQueue(
|
||||||
|
engine.sensorManager,
|
||||||
|
state->looper, LOOPER_ID_USER,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
if (state->savedState != NULL) {
|
||||||
|
// We are starting with a previous saved state; restore from it.
|
||||||
|
engine.state = *(struct saved_state*)state->savedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop waiting for stuff to do.
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
// Read all pending events.
|
||||||
|
int ident;
|
||||||
|
int events;
|
||||||
|
struct android_poll_source* source;
|
||||||
|
|
||||||
|
// If not animating, 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(engine.animating ? 0 : -1, NULL, &events,
|
||||||
|
(void**)&source)) >= 0) {
|
||||||
|
|
||||||
|
// Process this event.
|
||||||
|
if (source != NULL) {
|
||||||
|
source->process(state, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If a sensor has data, process it now.
|
||||||
|
if (ident == LOOPER_ID_USER) {
|
||||||
|
if (engine.accelerometerSensor != NULL) {
|
||||||
|
ASensorEvent event;
|
||||||
|
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
|
||||||
|
&event, 1) > 0) {
|
||||||
|
LOGI("accelerometer: x=%f y=%f z=%f",
|
||||||
|
event.acceleration.x, event.acceleration.y,
|
||||||
|
event.acceleration.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we are exiting.
|
||||||
|
if (state->destroyRequested != 0) {
|
||||||
|
engine_term_display(&engine);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.animating) {
|
||||||
|
// Done with events; draw next animation frame.
|
||||||
|
engine.state.angle += .01f;
|
||||||
|
if (engine.state.angle > 1) {
|
||||||
|
engine.state.angle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drawing is throttled to the screen update rate, so there
|
||||||
|
// is no need to do timing here.
|
||||||
|
engine_draw_frame(&engine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//END_INCLUDE(all)
|
||||||
7
android/src/main/cpp/native-lib.cpp
Normal file
7
android/src/main/cpp/native-lib.cpp
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
15
android/src/main/java/com/omigamedev/DummyActivity.java
Normal file
15
android/src/main/java/com/omigamedev/DummyActivity.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.omigamedev;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
public class DummyActivity extends Activity
|
||||||
|
{
|
||||||
|
/** Called when the activity is first created. */
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.main);
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
android/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
BIN
android/src/main/res/drawable-hdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
BIN
android/src/main/res/drawable-ldpi/ic_launcher.png
Normal file
BIN
android/src/main/res/drawable-ldpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
BIN
android/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
BIN
android/src/main/res/drawable-mdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
BIN
android/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
BIN
android/src/main/res/drawable-xhdpi/ic_launcher.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
13
android/src/main/res/layout/main.xml
Normal file
13
android/src/main/res/layout/main.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Hello World, DummyActivity"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
4
android/src/main/res/values/strings.xml
Normal file
4
android/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<string name="app_name">DummyActivity</string>
|
||||||
|
</resources>
|
||||||
@@ -3,6 +3,9 @@
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <OpenGL/gl3.h>
|
#include <OpenGL/gl3.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#elif __ANDROID__
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
|
|||||||
Reference in New Issue
Block a user