Here's a WebGL-powered invitation to the GNU Hackers Meeting 2013, which is taking place in Paris on August 22-25 :)

http://www.beuc.net/demo-ghm/v1/

Free, hardware-accelerated WebGL support is recent under GNU/Linux, you'll need Mesa/Mesa-DRI 9 and Linux kernel 3.6 from Debian sid plus a recent Firefox, though a Mesa-software fallback is usually available in earlier versions. Meanwhile, here's a WebM capture:

(Curious about the capture process?)

Work is underway on an extended version of this invitation/demo, peek here :)

http://www.beuc.net/demo-ghm/v2/

Posted Sun Jul 7 13:13:54 2013 Tags:

Great news!

The Learn OpenGL ES website recently switched its licensing to Creative Commons BY-SA 3.0 :)

http://www.learnopengles.com/announcing-the-new-qa-and-forums-and-a-roundup/

It provides tutorials for OpenGL ES using Java/Android and WebGL, and is focusing on a more community-oriented creative process. Give them cheers!

Posted Sat Feb 23 21:25:46 2013 Tags:

Base attack

Meritous is a nice, addictive action-adventure dungeon crawl game. Each new game is unique since the dungeon is built in a semi-random fashion. Last but not least, the engine, graphics and sound effects are GPL'd :)

The game is based on SDL 1.2, which has an unofficial Android variant, so I decided to try and port it on my cell phone! The port was surprinsingly smooth and only non-SDL fixes (move big stack allocation to heap) were necessary. Who said it was difficult to program in C on Android? ;)

It was also an opportunity to study the build system for F-Droid, an app market for free software apps, where APKs are rebuilt from source. The spec-like file is here.

The game packaging is also being ressurected for Debian but is being distressfully held hostage in the NEW queue for 2 weeks!

You can download the very first (aka beta) Android version:

  • for free at F-Droid
  • for 0.50€ at GPlay - because publishing at GPlay costs $25 (+30% of sells..)

Comments welcome!

Posted Wed Jan 9 17:41:35 2013 Tags:

FreeGLUT on Android

The OpenGL ES port of FreeGLUT is progressing :)

Now we have:

  • Basic Android/EGL port

  • Full X11/EGL port (using Mesa EGL), so we can test GLES on desktop :)

  • Geometry functions: upgrade from glBegin to glVertexPointer and GLES compatibility (triangulation). We also plan to provide shaders-compatible (OpenGL >= 2) geometry functions.

In addition, the work is available in the official repository! http://freeglut.svn.sourceforge.net/viewvc/freeglut/trunk/freeglut/freeglut/

Question: Mesa and Android ship GLES 1&2 in separate libraries. So at first glance, we'll have to ship 3 FreeGLUT builds:

  • freeglut.so / .a

  • freeglut-gles2.so / .a with -DFREEGLUT_GLES2 (-lGLESv2 + GLES2/gl2.h)

  • freeglut-gles1.so / .a with -DFREEGLUT_GLES1 (-lGLESv1_CM + GLES/gl.h)

Though, EAGL (on iPhone) can initialize either GLES 1 or 2 at run-time. Maybe it's possibly to do that by dlopen'ing the GLES library dynamically, but this won't work for static builds - and make distro packagers cringe unless I'm mistaken ;)

Do you think there's a way to provide a unified version?

Posted Sun Mar 18 12:51:28 2012 Tags:

I'm working on porting FreeGLUT for Android, and FreeGLUT is switching to CMake.

I'm more familiar with the GNU Autotools myself, and I'm used to cross-compile with a simple:

./configure --host=arm-linux-androideabi

Can we do that with CMake? Well, it's not well-documented, but yes :) Let's see how to do that for Android (smartphones) and MinGW (.exe for windows).


The principle is:

  • write a "toolchain" CMake script that defines the cross-compiler,

  • mention you're using a "GNU" compiler (a.k.a. GCC) so CMake automatically looks for prefixed cross-compilers tools such as arm-linux-androideabi-cpp or arm-linux-androideabi-ld.

  • pass the toolchain script to CMake using the predefined CMAKE_TOOLCHAIN_FILE variable.

  • REMOVE all the CMake-generated files when you change anything, CMake does not rebuild its cache when the toolchain script or PATH is modified, this creates misleading errors. Hence, building in a subdirectory is crucial.

Here's a simple toolchain script:

SET(CMAKE_SYSTEM_NAME Linux)  # Tell CMake we're cross-compiling
include(CMakeForceCompiler)
# Prefix detection only works with compiler id "GNU"
# CMake will look for prefixed g++, cpp, ld, etc. automatically
CMAKE_FORCE_C_COMPILER(arm-linux-androideabi-gcc GNU)
SET(ANDROID TRUE)

Note: SET(ANDROID TRUE) is not mandatory for CMake, it's just used to detect an Android build in the particular case of FreeGLUT development.

Here's how to invoke it:

PATH=/usr/src/ndk-standalone-9/bin:$PATH
cd /usr/src/freeglut-3.0.0/
mkdir cross-android/ && cd cross-android/
cmake \
  -D CMAKE_TOOLCHAIN_FILE=../android_toolchain.cmake \
  -D CMAKE_INSTALL_PREFIX=/freeglut \
  ..
make -j4
make install DESTDIR=$(pwd)

Now here's a slightly more complex toolchain for MinGW.

The main issue with MinGW is that there are at least 4 possible prefixes depending on which version and which distro you're using. So I ask the user to specify it with GNU_HOST:

SET(CMAKE_SYSTEM_NAME Windows)
include(CMakeForceCompiler)
IF("${GNU_HOST}" STREQUAL "")
    SET(GNU_HOST i586-mingw32msvc)
ENDIF()
# Prefix detection only works with compiler id "GNU"
CMAKE_FORCE_C_COMPILER(${GNU_HOST}-gcc GNU)
# CMake doesn't automatically look for prefixed 'windres', do it manually:
SET(CMAKE_RC_COMPILER ${GNU_HOST}-windres)

I wanted to print an error when GNU_HOST is not specified, but the toolchain script is loaded multiple times, and the command-line variables are not always set (CMake is not super-clean in that regard). So I defined a default, that works.

Sample invocation:

  apt-get install mingw-w64

  mkdir cross-woe/ && cd cross-woe/
  cmake \
    -D GNU_HOST=x86_64-w64-mingw32 \
    -D CMAKE_TOOLCHAIN_FILE=../mingw_cross_toolchain.cmake \
    -D CMAKE_INSTALL_PREFIX=/freeglut \
    ..
  make -j4
  make install DESTDIR=$(pwd)

I used this technique to cross-compile my projects, or other projects that use CMake. mingw-cross-env uses this technique (abeilt with explicit definition of all compiler tools) to provide pre-built windows libraries without altering the existing CMake scripts.

Do you people have tips or a better technique to cross-compile with CMake?

Posted Sat Mar 3 13:38:45 2012 Tags:

Today, there were events all around Europe to block ACTA.

In Paris, the protest started at Place de la Bastille :

APRIL was present, with in particular its president Lionel Allorge, and two members who wore the traditional anti-DRM suit :

Jérémie Zimmermann from La Quadrature du Net gave a speech and urged people to contact their legal representatives, in addition to protesting in the street :

The protest was cheerful and free of violence :

It got decent media coverage :

Notable places it crossed include Place des Victoires :

and Palais Royal, where it ended :

Next protest is in 2 weeks, on March 10th. Update your agenda!

Posted Sat Feb 25 18:47:44 2012 Tags:

I recently faced an environment where there is no MTA.

WTF? The reason is that people who work there get security audits on a regular basis, and the security people are usually mo...deratly skilled guys who blindly run a set of scripts, e.g. by ordering to disable Apache modules that "where seen enabled in /etc/apache2/mods-available/"...

To avoid spending days arguing with them and nitpicking with non-technical managers, the system is trimmed to the minimum - and there is no MTA. No MTA, so no cron output, so difficulty to understand why last night's cron job failed miserably.

Since it was not my role to reshape the whole business unit, I decided to hack a super-light, but functional way to get my cron output:

cat <<'EOF' > /usr/sbin/sendmail
#!/bin/bash
(
    echo "From me  $(LANG=C date)"
    cat
    echo
) >> /var/mail/all
EOF
chmod 755 /usr/sbin/sendmail

It works! :)

There is a companion logrotate script, to avoid filling the file system:

cat <<'EOF' > /etc/logrotate.d/mail-all
/var/mail/all {
  daily
  rotate 10
  compress
  delaycompress
  notifempty
  create 622 root mail
}
EOF

Bootstrap with:

touch /var/mail/all
logrotate -f /var/mail/all

You now can check your sys-mails with:

mutt -f /var/mail/all

;)

Posted Mon Feb 13 22:18:46 2012 Tags:

I'm working on porting FreeGLUT to Android!

Since I don't have access so the repository (I'm not a regular contributor), and since it will be a BIG patch, I thought I'd try a git-svn branch. So this won't be a post on OpenGL for once ;)

I'm not an expert at managing Git branch but here's how I set it up.

In this case, let's forget about importing tags: they don't have the same directory branch point in the hierarchy (sometimes the freeglut/ module, sometimes the parent directory), and git-svn only correctly supports set of sane tags that track the same initial directory.

SVN is SLOW, especially remotely. I suggest you make a rsync copy of the repository first, it will greatly speed up the import :

rsync -avHSP freeglut.svn.sourceforge.net::svn/freeglut/ freeglut.svn/

Then start the import with git-svn :

git svn clone --trunk=trunk/freeglut/freeglut file://$(pwd)/freeglut.svn/ freeglut-git/

And edit .git/config to point to https://freeglut.svn.sourceforge.net/svnroot/freeglut :

[svn-remote "svn"]
    url = https://freeglut.svn.sourceforge.net/svnroot/freeglut
    fetch = trunk/freeglut/freeglut:refs/remotes/trunk

I work with 2 branches:

  • master : the SVN on-going sync - may be rebased to push with git svn dcommit
  • android : my feature branch - not rebased and hence trackable by contributors

Here's how I synchronize the upstream repository and merge it regularly with my feature branch:

git svn fetch
git checkout master
git merge remotes/trunk

git checkout android  # my feature branch
git merge master
# if conflict
git add .../sthing.c
git commit -m "Merge master"
git push

Any better way?

The ongoing work is available at https://gitorious.org/freeglut/android :)

Posted Sun Feb 12 22:43:13 2012 Tags:

If you ever get this cryptic error when loading an Android native app:

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{org.wikibooks.OpenGL/android.app.NativeActivity}: java.lang.IllegalArgumentException: Unable to load native library: /data/data/org.wikibooks.OpenGL/lib/libnative-activity.so
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1768)
       at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1784)
       at android.app.ActivityThread.access$1500(ActivityThread.java:123)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:939)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:130)
       at android.app.ActivityThread.main(ActivityThread.java:3835)
       at java.lang.reflect.Method.invokeNative(Native Method)
       at java.lang.reflect.Method.invoke(Method.java:507)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
       at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Unable to load native library: /data/data/org.wikibooks.OpenGL/lib/libnative-activity.so
       at android.app.NativeActivity.onCreate(NativeActivity.java:199)
       at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
       at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1722)
       ... 11 more

This may mean that Java couldn't find the ANativeActivity_onCreate function in your code, because it was stripped by the compiler.

If you use the native_app_glue NDK module, you may have noticed this strange code:

    // Make sure glue isn't stripped.
    app_dummy();

Let's experiment what happens with and without this line:

Calling app_dummy:

$ arm-linux-androideabi-objdump -T libs/armeabi/libnative-activity.so  | grep ANativeActivity_onCreate
000067fc g    DF .text  000000f8 ANativeActivity_onCreate

Not calling app_dummy :

$ arm-linux-androideabi-objdump -T libs/armeabi/libnative-activity.so | grep ANativeActivity_onCreate
$   # nothing

native_app_glue mainly defines Android callbacks. Since none of them are called directly by your code, the compiler strips the android_native_app_glue.o module entirely. If you use app_dummy however, it embeds it. Fortunately the compiler cannot strip the module on a per-function basis ;)

That's why you need to call app_dummy when using the native_app_glue NDK module.

This looks like a ugly work-around though - isn't there a cleaner way?

Posted Tue Feb 7 21:12:05 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:

This blog is powered by ikiwiki.