OpenGL ES 2.0 games possibility

Search This thread
Jun 15, 2007
1,091
9
I've been hankering to start porting a game I've been working on(originally was going to be for Zune HD but they haven't released the damn 3D SDK. Video of it running in windows is available on youtube, where my username is marcusmaximus04) to android but was hesitant due to the lack of OpenGL ES2.0 support in the Android SDK. However, looking through the file system on my nexus one, I spotted the file libGLESv2.so, which appears to be the shared object file for exactly this!

Obviously, I still can't use the normal SDK to use this, but in theory, one could use the NDK to use OpenGL ES 2.0 features(shaders, etc) through that shared object file.

The purpose of this post is three-fold. One I want to know if anyone has any background with using OpenGL through the NDK or knows of any tutorials for doing so(I'm not entirely sure how that would work...). Two, I wanted to bring this to the attention of all the devs out there who might be holding off from using ES 2.0 features. And three, I wanted to let everyone else know that such a thing is possible, just 'cause it's exciting.

At any rate, even if I can't find any tutorials I'll probably start plugging away at getting this to work and this should make for an exciting couple weeks/months.

Since we have this pretty well working(even on non-rooted phones) I'll post a sample apk. It doesn't look like much, but it does prove that we're using OpenGL ES 2.0(this will only work on the Nexus One). I'll also post the libGLESv2_adreno.so shared library in the same zip file. Enjoy :D.
 

Attachments

  • DemoActivity.zip
    925.1 KB · Views: 478
Last edited:
Jun 15, 2007
1,091
9

robert-qfh

Member
Jan 15, 2010
39
0
Hi Marcus,

to get started, grab the OpenGL ES 2.0 headers from www DOT khronos.org/registry/gles/ and copy the library file from your phone to the NDK installation dir (build/platforms/android-4/arch-arm/usr/lib/). Next you might inspect the libGLESv2.so with objdump to see what functions it provides:
build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-objdump -t libGLESv2.so

It should have the 2.0 functions like glCompileShader(), glCreateProgram(), etc.

Finally, add the following line to the Android.mk file in the jni/ directory of your Android project:
LOCAL_LDLIBS += -Lbuild/platforms/android-4/arch-arm/usr/lib -lGLESv2

If you're lucky, that should allow you to compile and link OpenGL ES 2.0 code. I cannot try this right now but will as soon as I get my Nexus One on monday :D

I haven't done any OpenGL ES coding with the NDK, but it should be straightforward if you've written OpenGL (ES) code before. This might be of use: code DOT google.com/p/glesquake/
 
Jun 15, 2007
1,091
9
Hi Marcus,

to get started, grab the OpenGL ES 2.0 headers from www DOT khronos.org/registry/gles/ and copy the library file from your phone to the NDK installation dir (build/platforms/android-4/arch-arm/usr/lib/). Next you might inspect the libGLESv2.so with objdump to see what functions it provides:
build/prebuilt/linux-x86/arm-eabi-4.2.1/bin/arm-eabi-objdump -t libGLESv2.so

It should have the 2.0 functions like glCompileShader(), glCreateProgram(), etc.

Finally, add the following line to the Android.mk file in the jni/ directory of your Android project:
LOCAL_LDLIBS += -Lbuild/platforms/android-4/arch-arm/usr/lib -lGLESv2

If you're lucky, that should allow you to compile and link OpenGL ES 2.0 code. I cannot try this right now but will as soon as I get my Nexus One on monday :D

I haven't done any OpenGL ES coding with the NDK, but it should be straightforward if you've written OpenGL (ES) code before. This might be of use: code DOT google.com/p/glesquake/

Alright! Thanks for the help. I've done a lot of opengl work before and a little bit of opengl es when i had my g1 but haven't ever used the ndk, so that'll get me started.

EDIT: Sweet, I've dumped the list of functions available and it looks like all the appropriate shader functions are there. I'm attaching the full list output from my computer. I actually had to use arm-eabi-strings, since the objs one showed no objects. Regardless, it's looking good on the OpenGL ES2.0 front, and I've already looked into running opengl code from the NDK which is perfectly possible and ok.

ANOTHER EDIT: Haven't quite gotten it to build yet, but I got it to load gl2.h without any complaints. Now I just have a crapload of errors because the sample project I was using(from the ndk samples, san-angeles) was written for OpenGL ES 1.0 and all the things now done in shaders no longer exist(GL_LIGHTING, GL_MATERIAL, etc). Regardless, I'm considering this a success so far, since all that is expected.

YET ANOTHER EDIT: It runs! I'm not displaying anything yet(so it's not really a good test), but I got the shared library to build using OpenGL ES 2.0 and it runs on my phone. Gonna implement a simple program to display a triangle or something just to prove it works and will provide source code/binaries here(also, if anyone has a Droid or knows someone who does, it'd be great if we could test out to make sure this works on the Droid as well)
 

Attachments

  • openglfunctionlist.txt
    3.3 KB · Views: 117
Last edited:

pr0cl1v1ty

Senior Member
Jan 27, 2008
835
237
32
College Station, TX
I just wanted to drop in and say I'm very interested in what y'all are doing I'm of very good at coding. All I know is Java but ill definantly be following yall and keep up the good work
 
Jun 15, 2007
1,091
9
Decided to post a reply, rather than just adding to that one post.

Well, I encountered a fairly large roadblock:

Code:
E/libEGL  ( 3366): called unimplemented OpenGL ES API

That's what I see now every time I call one of the functions dealing with ES 2.0. I'm hoping there's another library I can use that'll make that go away, but we might not be as easy as I thought to do this.
 

robert-qfh

Member
Jan 15, 2010
39
0
That's bad news indeed. I was hoping that everything is in place and Google just didn't release a new NDK with ES 2.0 support yet, but if the libGLESv20.so is merely a stub, we're pretty much out of luck. I'd probably disassemble the file to see if there's actually some code besides "return unimplemented" in there, but even if there was, I'd have no idea on how to continue...

I'm wondering how they render the fancy rain drop effect on the wallpaper. Looks like a perfect fit for a 2.0 fragment shader, however there are a lot of other ways to create that effect.
 
Jun 15, 2007
1,091
9
That's bad news indeed. I was hoping that everything is in place and Google just didn't release a new NDK with ES 2.0 support yet, but if the libGLESv20.so is merely a stub, we're pretty much out of luck. I'd probably disassemble the file to see if there's actually some code besides "return unimplemented" in there, but even if there was, I'd have no idea on how to continue...

I'm wondering how they render the fancy rain drop effect on the wallpaper. Looks like a perfect fit for a 2.0 fragment shader, however there are a lot of other ways to create that effect.

Well I managed to view the assembly code, but can't get it into any form that I can/want to read(I know how to read assembly but unless you spend hours with it, it's damn near impossible to decode anything. Plus, I haven't looked at ARM assembly before). Know of a good program to convert it into C?

At any rate, I'll attach the disassembler dump(ran it using arm-eabi-objdump with flags -DS). From looking at it briefly, all the implemented functions look like they might be stubs since they're pretty bare bones and have almost all the same instructions(with a slight modification to one single instruction). But it's hard to tell with assembly. Let me know if you can make anything of it. I had to attach the file in a .zip by the way because it was too big.
 

Attachments

  • dump.zip
    25 KB · Views: 53
Jun 15, 2007
1,091
9
SUCCESS!!!! So, it looks like those functions were stubs. Google seems to have done it intentionally for whatever reason. They took the .so that actually worked(libGLESv2_adreno200.so) and shoved it under /system/lib/egl, which the ndk doesn't seem able to access(gives you a runtime error if you linked against it). However, If you just copy that file to /system/lib (yes, this requires root unfortunately) then you can use it. I successfully drew a triangle using shaders :D.

I'll try to get it to attach that xxx_adreno200.so file to the .apk so it can be used without messing around with such things(and work without root). If I can, then I'll throw it on here so everyone can see. Right now it's just a triangle, but tomorrow: the world.

EDIT: Alright, I attached the .apk(it's in the zip file, xda still doesn't allow posting .apks). I tried to attach the libGLESv2_adreno200.so library to it, so it wouldn't require moving the local one but it just wouldn't accept it. So, at least for the mean time, if you want to actually run that app without having it crash you'll have to do an adb remount and then the following in the terminal(or adb shell) as root:

Code:
cd /system/lib/egl
cp libGLESv2_adreno200.so ../

Once you do that, when you run the app it should display a yellowish triangle on a blue background(it was from the second tutorial from the OpenGL ES 2.0 sdk for PowerVX). Like I said, it's not much right now, but it is using custom shaders to display that triangle.

ANOTHER EDIT: I decided to change the test program a little. All I changed was the fragment and vertex shaders, which I made to change the color of the pixels based on where they are on the triangle. This should show(to those of you who know OpenGL) that it really is using custom shaders, since it's one triangle and it's clearly not using fixed-function pipeline shading ;).
 

Attachments

  • DemoActivity.zip
    8 KB · Views: 149
Last edited:

robert-qfh

Member
Jan 15, 2010
39
0
Well done, Marcus! I'm glad you found that working library.

You should be able to embed the library search path in your own library by using the rpath directive while linking your program. See "man ld" for more information. You need to get the NDK to call the compiler like this:
gcc ... -Wl,-rpath=/system/lib/egl

That should allow you to use that library without copying it around, and therefore make it work on non-root phones as well.

I guess all you need to do is add the directive to the LOCAL_LDLIBS variable in Android.mk, or maybe it has LOCAL_LDFLAGS, which would be more appropriate.
 
Jun 15, 2007
1,091
9
Well done, Marcus! I'm glad you found that working library.

You should be able to embed the library search path in your own library by using the rpath directive while linking your program. See "man ld" for more information. You need to get the NDK to call the compiler like this:
gcc ... -Wl,-rpath=/system/lib/egl

That should allow you to use that library without copying it around, and therefore make it work on non-root phones as well.

I guess all you need to do is add the directive to the LOCAL_LDLIBS variable in Android.mk, or maybe it has LOCAL_LDFLAGS, which would be more appropriate.

Ya, I tried adding it to LOCAL_LDLIBS, but that just seemed to make it use that path for the local library on my computer when building it. It still failed to find that library on my phone when I ran it. I'll try poking around a little more since that would obviously be ideal.
 

robert-qfh

Member
Jan 15, 2010
39
0
Alright. Are you sure you used rpath and not rpath-link?

BTW, there's a libGLESv2.so in the 2.1 emulator image. Did you try using that? I wonder if the emulator supports ES 2.0...
 
Jun 15, 2007
1,091
9
Alright. Are you sure you used rpath and not rpath-link?

BTW, there's a libGLESv2.so in the 2.1 emulator image. Did you try using that? I wonder if the emulator supports ES 2.0...

I didn't touch either actually, just changed the name of the library and the path it had. I haven't done a lot of make files beyond the most basic operations so a little study might be necessary.

Haven't tried the emulator image one, but the one from the phone just had those stubs. It would be really strange if the emulator had the actual functionality and the phone didn't.

I think you're right that if there's hope then it lies in the makefile, so I'll keep looking into that.

EDIT: Just tried adding --rpath=/system/lib/egl everywhere I could possibly think of and all with no change.
 
Last edited:
Jun 15, 2007
1,091
9
Hmm I can't try this yet, but it looks like it uses the property java.library.path to determine where to look for shared libraries. Maybe I can have it look in /system/lib/egl too?

Ack, tried it, didn't do anything. Still can't find that library.

So ya, I'm giving up on this front for now. Google obviously has some of this ready but doesn't want us using it for now, so I'll just wait for them to give us access unless I get some new info. In the meantime, I'll continue the work I've already started on porting that game from the video I linked to. At least we now have the tools to test this stuff.
 
Last edited:

pr0cl1v1ty

Senior Member
Jan 27, 2008
835
237
32
College Station, TX
Hmm I can't try this yet, but it looks like it uses the property java.library.path to determine where to look for shared libraries. Maybe I can have it look in /system/lib/egl too?

Ack, tried it, didn't do anything. Still can't find that library.

So ya, I'm giving up on this front for now. Google obviously has some of this ready but doesn't want us using it for now, so I'll just wait for them to give us access unless I get some new info. In the meantime, I'll continue the work I've already started on porting that game from the video I linked to. At least we now have the tools to test this stuff.

thats depressing :( i was checking this thread like 10 times a day waiting for new info to popup lol call me obsessed but i respect your work
 

robert-qfh

Member
Jan 15, 2010
39
0
Yet another idea to try. On Linux you can specify the library search path using the environment variable LD_LIBRARY_PATH, e.g. if you run a program like this
LD_LIBRARY_PATH=/some/path /path/to/program
then the linker will search that path for libraries.

Maybe it's possible to set that variable from within the Java code, but before the JNI library is loaded:

static {
// Set environment variable LD_LIBRARY_PATH
System.loadLibrary("your_jni_lib");
}

Finally another idea, so we cannot link our library to the OpenGL ES library. But we could probably dlopen() it from within the JNI library and grab all the function pointers using dlsym(). I will get my Nexus One in a few hours, and ES 2.0 will be one of the first things I'm going to look into :)

EDIT: Marcus, would you mind posting the source code of your ES 2.0 triangle demo application? Basically all I need is the gl....() stuff. I haven't done too much Shader stuff so far, so that would save me a lot of time.
 
Last edited:
Jun 15, 2007
1,091
9
Yet another idea to try. On Linux you can specify the library search path using the environment variable LD_LIBRARY_PATH, e.g. if you run a program like this
LD_LIBRARY_PATH=/some/path /path/to/program
then the linker will search that path for libraries.

Maybe it's possible to set that variable from within the Java code, but before the JNI library is loaded:

static {
// Set environment variable LD_LIBRARY_PATH
System.loadLibrary("your_jni_lib");
}

Finally another idea, so we cannot link our library to the OpenGL ES library. But we could probably dlopen() it from within the JNI library and grab all the function pointers using dlsym(). I will get my Nexus One in a few hours, and ES 2.0 will be one of the first things I'm going to look into :)

EDIT: Marcus, would you mind posting the source code of your ES 2.0 triangle demo application? Basically all I need is the gl....() stuff. I haven't done too much Shader stuff so far, so that would save me a lot of time.

Sure. I'll post it when I get home from work tonight. I don't have anything proprietary in there yet. :cool:

For the setting of the environment variable, from my understanding that's basically what System.SetProperty("java.library.path"... is supposed to do. But it still couldn't find the library and didn't seem to have any effect.

The dlopen bit might work. I was thinking of trying that but haven't had any time. I'm not really too sure on how these shared libraries are used, whether once they're open any other program can find and use them or whether the path to them has to be given explicitly at link time for the program that wants to use them and just generally having one loaded won't help.

EDIT: By the way, @pr0cl1v1ty: Don't worry, I'm not going to stop digging into ES 2.0 entirely. I'm just not going to be pushing as much for getting it to work on non-rooted phones. I've got bigger fish to fry.
 
Last edited: