Teapot on Android I got myself a second-hand Samsung Galaxy S at last, and started hacking on it!

The very first thing I wanted to try was porting the OpenGL wikibook C++ samples, that we wrote with OpenGL ES 2 in mind.

I started writing a minimal GLUT-compatible wrapper to run the samples as-is, using the Android NDK, and I'm making progress :) The Android NDK is getting nicer with Android 2.3, though it still feels less supported than Java apps (e.g. the resize events seem buggy and the keycodes header is incomplete...). Nonetheless, it's nice to be able to write C++ portable apps.

You can see how to use the wrapper, and how it works internally, at:

http://en.wikibooks.org/wiki/OpenGL_Programming/Installation/Android

One of the limitations is that GLES2 is not a true subset of OpenGL 2.1, in particular:

  • the shader version is declared differently (#version 100 vs. #version 120)
  • GLES2 shaders require float precision hints, but OpenGL 2.1 doesn't support them at all

I needed to pre-process these differences away, checking on GL_ES_VERSION_2_0 in the C++ source code to define a GLES2 macro in the shaders:

#ifdef GLES2
varying lowp vec4 f_color;
# else
varying vec4 f_color;
#endif

Is there a better way?

Posted Tue Jan 24 21:45:07 2012 Tags:

If you want to use FreeType in your native C/C++ Android app, you'll need to cross-compile it. The Android system uses FreeType internally but it doesn't expose it to native apps.

First, prepare the cross-compiler from the NDK:

/usr/src/android-ndk-r7/build/tools/make-standalone-toolchain.sh \
  --platform=android-9 \
  --install-dir=/usr/src/ndk-standalone-9
PATH=/usr/src/ndk-standalone-9/bin:$PATH

Then use it to cross-compile freetype:

tar xf freetype-2.4.8.tar.bz2
cd freetype-2.4.8/
CFLAGS="-std=gnu99" ./configure --host=arm-linux-androideabi --prefix=/freetype \
  --without-zlib
make
make install DESTDIR=$(pwd)

See this discussion for the --std option.

--without-zlib uses the internal copy of zlib inside freetype rather than one independently recompiled for Android. Otherwise you'd get errors such as:

./obj/local/armeabi/libfreetype.a(ftgzip.o): In function `ft_gzip_file_init':
ftgzip.c:(.text+0x3c4): undefined reference to `inflateInit2_'
./obj/local/armeabi/libfreetype.a(ftgzip.o): In function `ft_gzip_file_done':
ftgzip.c:(.text+0x43c): undefined reference to `inflateEnd'
./obj/local/armeabi/libfreetype.a(ftgzip.o): In function `ft_gzip_file_reset':
ftgzip.c:(.text+0x514): undefined reference to `inflateReset'
./obj/local/armeabi/libfreetype.a(ftgzip.o): In function `ft_gzip_file_fill_output':
ftgzip.c:(.text+0x780): undefined reference to `inflate'

Then write an Android.mk file in the new freetype/ directory:

#####
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := freetype
LOCAL_SRC_FILES := lib/libfreetype.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/include/freetype2
include $(PREBUILT_STATIC_LIBRARY)
#####

See docs/STANDALONE-TOOLCHAIN.html and docs/PREBUILTS.html in the NDK for details. The CLEAR_VARS bit is not documented, but is necessary to avoid mixed-up paths; it is used in the native_app_glue NDK module.

To use FreeType in your project, edit your Android.mk:

...
LOCAL_STATIC_LIBRARIES := ... freetype
...
$(call import-module,freetype)

You will need to specify the freetype directory location as well, using the NDK_MODULE_PATH variable. For instance, you can copy freetype in your project directory and build using:

    ndk-build NDK_MODULE_PATH=. ...

[Latest version of these instructions can be found at the OpenGL Wikibook]

Posted Sun Jan 29 17:24:39 2012 Tags: