Permalink
Browse files

Android sample application

  • Loading branch information...
julienr committed Mar 8, 2011
1 parent ac70545 commit 03f761c57c49d08ac5b437dbfe5f520fd840aff2
View
@@ -11,11 +11,14 @@ class FontHelper {
//Draw a text string of given size centered on coordinates (x,y)
//if autoGLState is on, will enable vertex and texcoords array before drawing and DISABLE them after drawing
- static void drawCenteredAt (Font* font, const char* str, float size, float x, float y, bool autoGLState) {
+ static void drawCenteredAt (Font* font, const char* str, float size, float x, float y, bool autoGLState, float rotation=0) {
glPushMatrix();
float fw, fh;
font->getExtent(str, size, &fw, &fh);
- glTranslatef(x-fw/2.0f, y-fh/2.0f, 0);
+ glTranslatef(x, y, 0);
+// glTranslatef(x-fw/2.0f, y-fh/2.0f, 0);
+ glRotatef(rotation, 0, 0, 1);
+ glTranslatef(-fw/2.0f, -fh/2.0f, 0);
font->draw(str,size,autoGLState);
glPopMatrix();
}
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- BEGIN_INCLUDE(manifest) -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="net.fhtagn.libfont.android_demo"
+ android:versionCode="1"
+ android:versionName="1.0">
+
+ <!-- This is the platform API where NativeActivity was introduced. -->
+ <uses-sdk android:minSdkVersion="8" />
+
+ <!-- This .apk has no Java code itself, so set hasCode to false. -->
+ <application android:label="@string/app_name" android:hasCode="false">
+
+ <!-- Our activity is the built-in NativeActivity framework class.
+ This will take care of integrating with our NDK code. -->
+ <activity android:name="android.app.NativeActivity"
+ android:label="@string/app_name"
+ android:configChanges="orientation|keyboardHidden"
+ android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
+ <!-- Tell NativeActivity the name of or .so -->
+ <meta-data android:name="android.app.lib_name"
+ android:value="native-activity" />
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest>
+<!-- END_INCLUDE(manifest) -->
View
@@ -0,0 +1,7 @@
+all:
+ ndk-build
+ ant debug
+
+clean:
+ ndk-build clean
+ ant clean
Binary file not shown.
@@ -0,0 +1,17 @@
+# This file is used to override default values used by the Ant build system.
+#
+# This file must be checked in Version Control Systems, as it is
+# integral to the build system of your project.
+
+# This file is only used by the Ant script.
+
+# You can use this to override default values such as
+# 'source.dir' for the location of your java source folder and
+# 'out.dir' for the location of your output folder.
+
+# You can also use it define how the release builds are signed by declaring
+# the following properties:
+# 'key.store' for the location of your keystore and
+# 'key.alias' for the name of the key to use.
+# The password will be asked during the build when you use the 'release' target.
+
View
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="LibfontDemo" default="help">
+
+<!-- The local.properties file is created and updated by the 'android'
+ tool.
+ It contains the path to the SDK. It should *NOT* be checked into
+ Version Control Systems. -->
+ <property file="local.properties" />
+
+ <!-- The build.properties file can be created by you and is never touched
+ by the 'android' tool. This is the place to change some of the
+ default property values used by the Ant rules.
+ Here are some properties you may want to change/update:
+
+ source.dir
+ The name of the source directory. Default is 'src'.
+ out.dir
+ The name of the output directory. Default is 'bin'.
+
+ Properties related to the SDK location or the project target should
+ be updated using the 'android' tool with the 'update' action.
+
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems.
+
+ -->
+ <property file="build.properties" />
+
+ <!-- The default.properties file is created and updated by the 'android'
+ tool, as well as ADT.
+ This file is an integral part of the build system for your
+ application and should be checked into Version Control Systems. -->
+ <property file="default.properties" />
+
+ <!-- Custom Android task to deal with the project target, and import the
+ proper rules.
+ This requires ant 1.6.0 or above. -->
+ <path id="android.antlibs">
+ <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
+ <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
+ <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
+ </path>
+
+ <taskdef name="setup"
+ classname="com.android.ant.SetupTask"
+ classpathref="android.antlibs" />
+
+<!-- extension targets. Uncomment the ones where you want to do custom work
+ in between standard targets -->
+<!--
+ <target name="-pre-build">
+ </target>
+ <target name="-pre-compile">
+ </target>
+
+ [This is typically used for code obfuscation.
+ Compiled code location: ${out.classes.absolute.dir}
+ If this is not done in place, override ${out.dex.input.absolute.dir}]
+ <target name="-post-compile">
+ </target>
+-->
+
+
+ <!-- Execute the Android Setup task that will setup some properties
+ specific to the target, and import the build rules files.
+
+ The rules file is imported from
+ <SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml
+
+ To customize existing targets, there are two options:
+ - Customize only one target:
+ - copy/paste the target into this file, *before* the
+ <setup> task.
+ - customize it to your needs.
+ - Customize the whole script.
+ - copy/paste the content of the rules files (minus the top node)
+ into this file, *after* the <setup> task
+ - disable the import of the rules by changing the setup task
+ below to <setup import="false" />.
+ - customize to your needs.
+ -->
+ <setup />
+
+</project>
@@ -0,0 +1 @@
+target=android-7
@@ -0,0 +1,165 @@
+#include "Activity.h"
+
+
+#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
+#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "native-activity", __VA_ARGS__))
+
+Activity::Activity (android_app* app)
+ : app(app),
+ display(EGL_NO_DISPLAY),
+ surface(EGL_NO_SURFACE),
+ context(EGL_NO_CONTEXT) {}
+
+
+bool Activity::_initGL () {
+ /*
+ * 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 dummy, format;
+ EGLint numConfigs;
+ EGLConfig config;
+
+ display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ eglInitialize(display, 0, 0);
+
+ /* Here, the application chooses the configuration it desires. In this
+ * sample, we have a very simplified selection process, where we pick
+ * the first EGLConfig that matches our criteria */
+ eglChooseConfig(display, attribs, &config, 1, &numConfigs);
+
+ /* 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);
+
+ ANativeWindow_setBuffersGeometry(app->window, 0, 0, format);
+
+ surface = eglCreateWindowSurface(display, config, app->window, NULL);
+ context = eglCreateContext(display, config, NULL, NULL);
+
+ if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
+ LOGE("Unable to eglMakeCurrent");
+ return false;
+ }
+
+ eglQuerySurface(display, surface, EGL_WIDTH, &width);
+ eglQuerySurface(display, surface, EGL_HEIGHT, &height);
+
+ glViewport(0,0, width, height);
+
+ postInit();
+
+ return true;
+}
+
+void Activity::_deinitGL () {
+ if (display != EGL_NO_DISPLAY) {
+ eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ if (context != EGL_NO_CONTEXT)
+ eglDestroyContext(display, context);
+ if (surface != EGL_NO_SURFACE)
+ eglDestroySurface(display, surface);
+ eglTerminate(display);
+ }
+ display = EGL_NO_DISPLAY;
+ surface = EGL_NO_SURFACE;
+ context = EGL_NO_CONTEXT;
+}
+
+uint64_t Activity::_getTimeMillis () {
+ timeval tv;
+ gettimeofday(&tv, NULL);
+ return tv.tv_sec*1000 + tv.tv_usec/1000;
+}
+
+void Activity::_draw () {
+ if (display == EGL_NO_DISPLAY)
+ return;
+
+ drawImpl();
+
+ eglSwapBuffers(display, surface);
+}
+
+bool Activity::handleInput (AInputEvent* event) {
+ return false;
+}
+
+void Activity::handleCmd (int32_t cmd) {
+ switch (cmd) {
+ case APP_CMD_SAVE_STATE:
+ saveState(&app->savedState, &app->savedStateSize);
+ break;
+ case APP_CMD_INIT_WINDOW:
+ if (app->window != NULL) {
+ _initGL();
+ _draw();
+ }
+ break;
+ case APP_CMD_TERM_WINDOW:
+ _deinitGL();
+ break;
+ }
+}
+
+static void handle_cmd(struct android_app* app, int32_t cmd) {
+ ((Activity*)app->userData)->handleCmd(cmd);
+}
+
+static int32_t handle_input(struct android_app* app, AInputEvent* event) {
+ return ((Activity*)app->userData)->handleInput(event);
+}
+
+void Activity::run () {
+ app->userData = this;
+ app->onAppCmd = handle_cmd;
+ app->onInputEvent = handle_input;
+
+ if (app->savedState != NULL) {
+ restoreState(app->savedState, app->savedStateSize);
+ //State restored, free the memory
+ free(app->savedState);
+ app->savedState = NULL;
+ app->savedStateSize = 0;
+ }
+
+ lastSimulate = _getTimeMillis();
+
+ while (1) {
+ int ident;
+ int events;
+ android_poll_source* source;
+ while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) {
+ if (source != NULL)
+ source->process(app, source);
+
+ //We are exiting
+ if (app->destroyRequested != 0) {
+ _deinitGL();
+ return;
+ }
+ }
+
+ //Simulate
+ const uint64_t now = _getTimeMillis();
+ const double elapsedS = (now-lastSimulate)/1000.0;
+ simulate(elapsedS);
+ lastSimulate = now;
+
+ //Draw
+ _draw();
+ }
+
+}
+
Oops, something went wrong.

0 comments on commit 03f761c

Please sign in to comment.