You have the code in place, and now you must compile it. To do so, use the helper scripts agcc and ald
described in Chapter 1, and the Makefile shown in Listing 5-16.
Listing 5-16. Makefile for This Chapter’s Example ############################################# # Android Makefile for CH05
############################################# # Android source: Contains GL C headers SYS_DEV = /home/user/mydroid # Compiler script CC = agcc # Linker script LINKER = ald # C files
MAIN_OBJS = cuberenderer.o cube.o # Library name, dynamic executable LIB = libgltest_jni.so DYN = gl-dyn
# Compilation flags & libs
INCLUDES = -I$(SYS_DEV)/frameworks/base/opengl/include CFLAGS = -DNORMALUNIX -DLINUX -DANDROID
LIBS = -lGLES_CM -lui
153
lib: $(MAIN_OBJS) # jni @echo
$(LINKER) -shared -o $(LIB) $(MAIN_OBJS) $(LIBS) @echo Done. Out file is $(LIB)
# Create JNI headers jni:
@echo "Creating JNI C headers..."
javah -jni -classpath ../bin -d include opengl.jni.Natives
# Test dynamic exe dyn:
$(CC) -c test.c $(INCLUDES)
$(LINKER) -o $(DYN) test.o -lgltest_jni -L. @echo
@echo Done. Out file is $(DYN) @echo
.c.o: @echo
$(CC) -Wall -O2 -fpic -c $(CFLAGS) $(INCLUDES) $<
# Deploy lib to device /data folder deploy-test:
@echo "Deploying $(LIB) to /data" adb push $(LIB) /data
clean:
rm -f *.o
First, generate the JNI headers for opengl.jni.Natives.java with the following:
$ make jni
Next, compile the library with the following:
user@ubuntu:~/workspace/ch05.OpenGL/native$ make agcc -Wall -O2 -fpic -c -DNORMALUNIX -DLINUX -DANDROID -
I/home/user/mydroid/frameworks/base/opengl/include cuberenderer.c agcc -Wall -O2 -fpic -c -DNORMALUNIX -DLINUX -DANDROID -
I/home/user/mydroid/frameworks/base/opengl/include cube.c
ald -shared -o libgltest_jni.so cuberenderer.o cube.o -lGLES_CM -lui arm-none-linux-gnueabi-ld: warning: library search path "/usr/lib/jvm/java-6- sun/jre/lib/i386" is unsafe for cross-compilation
154
Done. Out file is libgltest_jni.so
Check for missing symbols with this code:
user@ubuntu:~/workspace/ch05.OpenGL/native$ make dyn
agcc -c test.c -I/home/user/mydroid/frameworks/base/opengl/include ald -o gl-dyn test.o -lgltest_jni -L.
arm-none-linux-gnueabi-ld: warning: library search path "/usr/lib/jvm/java-6- sun/jre/lib/i386" is unsafe for cross-compilation
arm-none-linux-gnueabi-ld: warning: cannot find entry symbol _start; defaulting to 000082e8 Done. Out file is gl-dyn
■Note The compiler will complain about the local system JNI headers: “library search path "/usr/lib/jvm/
java-6-sun/jre/lib/i386" is unsafe for cross-compilation.” This message can be ignored.
Finally, the library must be deployed to the device /data folder so the activity can load it:
user@ubuntu:~ ch05.OpenGL/native$ make deploy-test Deploying libgltest_jni.so to /data
adb push libgltest_jni.so /data 87 KB/s (7389 bytes in 0.082s)
As shown in Figure 5-6, when the project is started in the device, two launchers will be placed in the device desktop: OpenGL Java and OpenGL Native.
155
Figure 5-6. Device launchers for the GL cubes sample
Run both launchers and look at the device log (see Listing 5-17). On the native side, you should see the following messages:
DEBUG/dalvikvm(512): Trying to load lib /data/libgltest_jni.so 0x433a7258 DEBUG/dalvikvm(512): Added shared lib /data/libgltest_jni.so
This indicates that the native library has been successfully loaded by JNI. Now stop the activity using the Devices view (see Figure 5-7), and then try the other activity.
156
Figure 5-7. Stopping an Android activity using the Devices view
Listing 5-17. Device Logs for the Java and Native Implementations of GL Cubes // Java Device Log
07-28 19:46:04.568: INFO/ActivityManager(52): Start proc opengl.test for activity opengl.test/.JavaGLActivity: pid=505 uid=10021 gids={}
07-28 19:46:04.857: INFO/jdwp(505): received file descriptor 10 from ADB 07-28 19:46:05.677: INFO/System.out(505): GLSurfaceView::setRenderer setting 07-28 19:46:06.347: INFO/System.out(505): Vendor:Google Inc.
07-28 19:46:06.376: INFO/System.out(505): Renderer:Android PixelFlinger 1.0 07-28 19:46:06.376: INFO/System.out(505): Version:OpenGL ES-CM 1.0
07-28 19:46:06.416: INFO/System.out(505): Vendor:Google Inc.
07-28 19:46:06.436: INFO/System.out(505): Renderer:Android PixelFlinger 1.0 07-28 19:46:06.476: INFO/System.out(505): Version:OpenGL ES-CM 1.0
07-28 19:46:06.546: INFO/ARMAssembler(505): generated 07-28 19:46:06.638:
INFO/ActivityManager(52): Displayed activity opengl.test/.JavaGLActivity: 2202 ms // Native Log
07-28 19:56:57.167: INFO/ActivityManager(52): Start proc opengl.test for activity opengl.test/.NativeGLActivity: pid=512 uid=10021 gids={}
157
07-28 19:56:58.247: INFO/System.out(512): Loading JNI lib using abs path:/data/libgltest_jni.so
07-28 19:56:58.267: DEBUG/dalvikvm(512): Trying to load lib /data/libgltest_jni.so 0x433a7258
07-28 19:56:58.376: DEBUG/dalvikvm(512): Added shared lib /data/libgltest_jni.so 0x433a7258 07-28 19:56:58.387: DEBUG/dalvikvm(512): No JNI_OnLoad found in /data/libgltest_jni.so 0x433a7258
07-28 19:56:58.548: INFO/System.out(512): GLSurfaceView::setRenderer setting natives listener
07-28 19:56:59.777: INFO/System.out(512): Vendor:Google Inc.
07-28 19:56:59.816: INFO/System.out(512): Renderer:Android PixelFlinger 1.0 07-28 19:56:59.916: INFO/System.out(512): Version:OpenGL ES-CM 1.0
07-28 19:57:00.056: INFO/System.out(512): Vendor:Google Inc.
07-28 19:57:00.158: INFO/System.out(512): Renderer:Android PixelFlinger 1.0 07-28 19:57:00.187: INFO/System.out(512): Version:OpenGL ES-CM 1.0
07-28 19:57:00.187: INFO/System.out(512): GLThread::OnMessage Native:RenderTest initscene 07-28 19:57:00.796: INFO/ActivityManager(52): Displayed activity
opengl.test/.NativeGLActivity: 3971 ms
Figure 5-7 shows the native renderer running in the emulator.
158
When it comes to advanced OpenGL games written for embedded devices, there are some caveats that you should be aware of before starting you porting work, which we’ll look at in the next section.