OpenGL ES 2.0 games possibility

Search This thread
Jun 15, 2007
1,091
9
FINALLY!!! It took all freaking day, but I finally got the stupid Matrix math stuff perfectly. Note that you'll need a projection matrix(courtesy of my handy glPerspective function), you might want a view matrix(courtesy of my handy gluLookAt function), and whatever world matrix you want(courtesy of glRotate.., glTranslate, and glScale), in that order. It took a while to get everything to look right even when I finished modifying the actual matrix functions just because I couldn't remember where to put certain parts. Anyway, enjoy everyone.

I'll attach a little sample of an app using some of these functions, along with the Matrices.h file and the function used to draw the sample app(not attaching the whole file because I have some proprietary stuff elsewhere in the file).
 

Attachments

  • Matrices.zip
    25 KB · Views: 52

robert-qfh

Member
Jan 15, 2010
39
0
Very nice. thanks Marcus. I implemented the dlopen() + dlsym() way of loading the library. Works nicely, didn't test on a Droid though. Find it attached, the file is called gles2wrapper.h and meant to be a drop-in replacement for gl2.h. If you have several .c/.cpp files calling gl() functions, you will have to copy the variable declaration to a separate .c file and make the declarations in the header "extern", otherwise you'll probably get duplicate symbols.

There are Eclipse projects in the sample folder, and another (CDT) project in the jni folder.
 

Attachments

  • glesv2-sample.zip
    38.4 KB · Views: 46
Jun 15, 2007
1,091
9
Very nice. thanks Marcus. I implemented the dlopen() + dlsym() way of loading the library. Works nicely, didn't test on a Droid though. Find it attached, the file is called gles2wrapper.h and meant to be a drop-in replacement for gl2.h. If you have several .c/.cpp files calling gl() functions, you will have to copy the variable declaration to a separate .c file and make the declarations in the header "extern", otherwise you'll probably get duplicate symbols.

There are Eclipse projects in the sample folder, and another (CDT) project in the jni folder.

Awesome. That should help a lot. On the Droid side, there seems to be(I've had only 1 report back from anyone with a droid) a problem, but I'm not entirely sure why. The guy got a cursor finalization error from NativeStart.run(tried to finalize a cursor that wasn't closed) and ended up with just a black screen, but I have no idea what that means or why it would only happen on the Droid. I put up a request for assistance a couple days ago in my thread in the general android development forum, but haven't gotten a response. Unfortunately, I don't have a Droid to test on, so I can't verify anything. (Although there's a 50/50 chance of that changing in March-- I've decided to go to GDC after all)
 

blunden

Senior Member
Jun 11, 2009
1,002
327
[...]Google really needs to get off their duff in the Android team and ensure they put together a good dev rel program - bring on board some key ATI/NVIDIA dev role folks who can help bring some key Tier 1 mobile developers on board.... Man even the pathetic Palm guys are showing some good content now on Palm Pre/Pixi.

GPGPU/Mobile CUDA style programability for the GPU is VERY interesting for some non graphics apps; (e.g. image processing, etc)
Agreed. That would be really interesting to see. :) You would have to consider the battery drain of the GPU in full load though I assume. Hopefully there are lots of things that could be done using the GPU that won't drain too much. :)
 

Jibreil

Senior Member
Jan 11, 2007
1,551
284
Mumbai
Google needs to enable installing Apps/Games on SD Card for true OpenGL ES 2.0 games to publish on the market as these games vary from 100MB to 200MB in file size and installing on phone memory doesn't leave much room for other apps.
 

d1mbu1b

Member
Jan 25, 2010
29
2
frame rates and openGL/JNI architecture

What frame rates are you all seeing with this DemoActivity code.
I have setcpu to 1GHz and I am getting 7.25 fps with san-angeles.
I was extremely disapointed expecting at least 30.

I have yet to learn the android application stack.
So I dont know if its a JNI issue or simply thats what the render rate is.

I am concerned since I am porting an ES implementation.
I am trying to decide to pass the context and surface once to a JNI thread and do all the GLES code by hand and control my own frame rate;
or do it the way the san-angeles example does it and allow the GLSurfaceVIew and Renderer to hike up and down the JNI stack each frame.
Who know what kind of over head there is calling a *.so from java ?

Any thoughts.
 

pr0cl1v1ty

Senior Member
Jan 27, 2008
835
237
32
College Station, TX
Google needs to enable installing Apps/Games on SD Card for true OpenGL ES 2.0 games to publish on the market as these games vary from 100MB to 200MB in file size and installing on phone memory doesn't leave much room for other apps.

this is completely and entirely true. although we have this ability to do ourselves but then again we wont have EA or Gameloft creating games just for XDA *i wish lol* some good iphone graphical games range from 50mb and up
 
Jun 15, 2007
1,091
9
What frame rates are you all seeing with this DemoActivity code.
I have setcpu to 1GHz and I am getting 7.25 fps with san-angeles.
I was extremely disapointed expecting at least 30.

I have yet to learn the android application stack.
So I dont know if its a JNI issue or simply thats what the render rate is.

I am concerned since I am porting an ES implementation.
I am trying to decide to pass the context and surface once to a JNI thread and do all the GLES code by hand and control my own frame rate;
or do it the way the san-angeles example does it and allow the GLSurfaceVIew and Renderer to hike up and down the JNI stack each frame.
Who know what kind of over head there is calling a *.so from java ?

Any thoughts.

Hmm, at that frame rate you'd be seeing actual noticeable stuttering. I definitely haven't seen that with that triangle demo I made for ES 2.0. It seemed to be perfectly smooth, implying upwards of 20fps.

That aside, having it all in the JNI would likely be significantly faster, although you might run into some problems. For one, you don't have access to EGL from the JNI, so you don't have much of a way to handle things like swapping the buffers. Another possible problem(in that I'm not sure how/if it works) would be actual controls. If you don't give back control or don't pass any data between the java side and the jni, then you'd have to handle all input and sensors yourself in C, which as far as I've seen, isn't possible.

EDIT: Ahh, you're asking about frame rates for the basic san-angeles, not my little demo for ES 2.0 I threw together using that as a base, aren't you? Hmm, I hadn't actually bothered trying that demo before ripping it apart and putting my code, so I can't testify to what frame rate you should be seeing.
 
Last edited:

d1mbu1b

Member
Jan 25, 2010
29
2
Thanks for the reply.
The all java NeHe tutorials have a decent frame rate. So I have to assume if the one per frame JNI calls are slowing it down.
I must be missing something simple.
like maybe wait() is being called in GLSurfaceView.GLThread.runGuarded()...

For one, you don't have access to EGL from the JNI, so you don't have much of a way to handle things like swapping the buffers. .
Here is my theory...
I figured i would modify my own GLSurfaceView.java
There exists a private EGLHelper class which has the bindings for EGLDisplay, EGLSurface, and EGLContext. Then just release contol via one time JNI call in the thread mGLThread.guardedRun(); not sure these binding objects can tranlate to the void pointers that eglSwapBuffers expects. (BIG IF). I found swap buffers in /system/lib/egl/libEGL_adreno.so and /system/lib/egl/libGLES_android.so
However the ndk include does not have a function prototype for it. thus trying to force the use of GLSurfaceView.

Another possible problem(in that I'm not sure how/if it works) would be actual controls. If you don't give back control or don't pass any data between the java side and the jni, then you'd have to handle all input and sensors yourself in C, which as far as I've seen, isn't possible.
Since the render loop is in its own thread (GLThread) I THINK its coverred.
I think I can still take advantage of the Activity class and a JNI method(s) for passing UI data to the native code. This way I can still conform to the android "ideal" and still take advantage of the nice UI tools.

What a mess. I highly doubt khronos had any of this in mind.
 
Jun 15, 2007
1,091
9
Thanks for the reply.
The all java NeHe tutorials have a decent frame rate. So I have to assume if the one per frame JNI calls are slowing it down.
I must be missing something simple.
like maybe wait() is being called in GLSurfaceView.GLThread.runGuarded()...


Here is my theory...
I figured i would modify my own GLSurfaceView.java
There exists a private EGLHelper class which has the bindings for EGLDisplay, EGLSurface, and EGLContext. Then just release contol via one time JNI call in the thread mGLThread.guardedRun(); not sure these binding objects can tranlate to the void pointers that eglSwapBuffers expects. (BIG IF). I found swap buffers in /system/lib/egl/libEGL_adreno.so and /system/lib/egl/libGLES_android.so
However the ndk include does not have a function prototype for it. thus trying to force the use of GLSurfaceView.


Since the render loop is in its own thread (GLThread) I THINK its coverred.
I think I can still take advantage of the Activity class and a JNI method(s) for passing UI data to the native code. This way I can still conform to the android "ideal" and still take advantage of the nice UI tools.

What a mess. I highly doubt khronos had any of this in mind.

For the second-to-last bit, if I understand you correctly, wouldn't you have to deal with making everything thread safe then, and use semaphores/etc to make sure that you aren't reading the position/whatever variables for the display at the same time they're being altered by your control functions?

At any rate, this is all so complicated mainly because we're trying to use the ndk. In the straight sdk, all this stuff is fairly straight forward and runs at a decent rate, they just haven't implemented ES 2.0 in the SDK yet. I'm willing to deal with these kind of hassles though in order to be ahead of the curve like this.
 

d1mbu1b

Member
Jan 25, 2010
29
2
For the second-to-last bit, if I understand you correctly, wouldn't you have to deal with making everything thread safe then, and use semaphores/etc to make sure that you aren't reading the position/whatever variables for the display at the same time they're being altered by your control functions?.
yes. but its made a bit easier since the render thread will always only read the data. good point however.

I managed to compile, link, and run a wholly native GLES executable.
Unfortunately, it dies on the create Surface step.
It performed all eglInitialization calls all the way up to eglCreateWindowSurface():
with the listed results.
I have seen this on the iphone and on the beagleboard (TI OMAP/powervr) when I didnt get the exact color depth correct. still digging.

*** In any event you can see the version returned by eglInitialize()

Code:
int eglHelloInit()
{
  EGLDisplay eglDisplay;
  EGLSurface eglSurface;
  EGLContext eglContext;
  EGLint versMajor;
  EGLint versMinor;
  EGLBoolean result;

    eglDisplay = eglGetDisplay(0);
    if (eglDisplay == EGL_DEFAULT_DISPLAY)
      fprintf(stderr, "default display\n");
    else if (eglDisplay == EGL_NO_DISPLAY)
      fprintf(stderr, "no display\n");
    else
      fprintf(stderr, "other display\n");

    result = eglInitialize(eglDisplay, &versMajor, &versMinor);
    printf("GL version %d.%d\n", versMajor, versMinor);

    if (result)
    {
        EGLint numConfigs;

        if (eglGetConfigs(eglDisplay, 0, 0, &numConfigs))
        {
            printf("%d egl configs\n", numConfigs);

            EGLConfig configs[32];
            eglGetConfigs(eglDisplay, configs, 32, &numConfigs);

            int i;
            for (i = 0; i < numConfigs; i++)
            {
                EGLint redBits;
                EGLint greenBits;
                EGLint blueBits;
                EGLint alphaBits;

                EGLint bufferSize;
                EGLint depthSize;
                EGLint stencilSize;

                EGLint caveat;
                EGLint native;

                EGLint level;
                EGLint surfaceType;
                EGLint visualType;
                EGLint visualID;

                eglGetConfigAttrib(eglDisplay, configs[i], EGL_RED_SIZE,    &redBits);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_GREEN_SIZE,  &greenBits);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_BLUE_SIZE,   &blueBits);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_ALPHA_SIZE,  &alphaBits);

                eglGetConfigAttrib(eglDisplay, configs[i], EGL_BUFFER_SIZE, &bufferSize);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_DEPTH_SIZE,  &depthSize);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_STENCIL_SIZE, &stencilSize);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_CONFIG_CAVEAT, &caveat);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_NATIVE_RENDERABLE, &native);

                eglGetConfigAttrib(eglDisplay, configs[i], EGL_LEVEL, &level);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_SURFACE_TYPE, &surfaceType);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_NATIVE_VISUAL_TYPE, &visualType);
                eglGetConfigAttrib(eglDisplay, configs[i], EGL_NATIVE_VISUAL_ID, &visualID);
                printf
                (
                     "config %d: rgba=%d:%d:%d:%d(%d), ds=%d:%d, "
                     "caveat=%04x, native=%d, level=%d, surface=%04x, visual=%04x, id=%d\n",
                     i + 1,
                     redBits, greenBits, blueBits, alphaBits, bufferSize, depthSize, stencilSize,
                     caveat, native, level, surfaceType, visualType, visualID
                 );
            }

            EGLint configAttribs[] =
            {
                //EGL_RED_SIZE, 4,
                //EGL_GREEN_SIZE, 4,
                //EGL_BLUE_SIZE, 4,
                //EGL_ALPHA_SIZE, 4,
                //EGL_DEPTH_SIZE, 16,
                //EGL_BUFFER_SIZE, 16,
                EGL_NONE
                //EGL_BUFFER_SIZE, 32,
                //EGL_SURFACE_TYPE, EGL_WINDOW_BIT, // EGL_WINDOW_BIT, EGL_PIXMAP_BIT,
            };

            EGLConfig eglConfig = 0;
            if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &numConfigs) || (numConfigs != 1))
            {
                printf("failed to find usable config =(\n");
            }
            else
            {
                GLint configID;
                eglGetConfigAttrib(eglDisplay, eglConfig, EGL_CONFIG_ID, &configID);
                printf("chose config %d\n", configID);
            }

            eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, 0);
            if (eglContext == EGL_NO_CONTEXT)
                printf("failed to allocate context\n");

            eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, 0, 0);
            if (eglSurface == EGL_NO_SURFACE)
                printf("failed to create surface\n");

            return eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
        }
        else
            printf("GL get configs failed\n");
    }
    else
        printf("GL init failed\n");


  return(1);
}

Code:
Script started on Wed Jan 27 15:34:14 2010
sh-3.2$ adb shell
# cd /data
cd /data


# ./eg  hello-egl
./hello-egl


other display


GL version 1.4


GL version 1.4


44 egl configs


config 1: rgba=4:4:4:4(16), ds=0:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 2: rgba=4:4:4:4(16), ds=16:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 3: rgba=4:4:4:4(16), ds=24:8, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 4: rgba=5:5:5:1(16), ds=0:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 5: rgba=5:5:5:1(16), ds=16:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 6: rgba=5:5:5:1(16), ds=24:8, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 7: rgba=5:6:5:0(16), ds=0:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 8: rgba=5:6:5:0(16), ds=16:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 9: rgba=5:6:5:0(16), ds=24:8, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 10: rgba=8:8:8:8(32), ds=0:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 11: rgba=8:8:8:8(32), ds=16:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 12: rgba=8:8:8:8(32), ds=24:8, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 13: rgba=4:4:4:4(16), ds=0:0, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 14: rgba=4:4:4:4(16), ds=16:0, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 15: rgba=4:4:4:4(16), ds=24:8, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 16: rgba=5:5:5:1(16), ds=0:0, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 17: rgba=5:5:5:1(16), ds=16:0, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 18: rgba=5:5:5:1(16), ds=24:8, caveat=3051, native=0, level=0, surface=0403, visual=0000, id=0


config 19: rgba=5:6:5:0(16), ds=0:0, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 20: rgba=5:6:5:0(16), ds=16:0, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 21: rgba=5:6:5:0(16), ds=24:8, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 22: rgba=8:8:8:8(32), ds=0:0, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 23: rgba=8:8:8:8(32), ds=16:0, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 24: rgba=8:8:8:8(32), ds=24:8, caveat=3051, native=0, level=0, surface=0407, visual=0000, id=0


config 25: rgba=4:4:4:4(16), ds=0:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 26: rgba=4:4:4:4(16), ds=16:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 27: rgba=4:4:4:4(16), ds=24:8, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 28: rgba=5:5:5:1(16), ds=0:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 29: rgba=5:5:5:1(16), ds=16:0, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 30: rgba=5:5:5:1(16), ds=24:8, caveat=3038, native=0, level=0, surface=0403, visual=0000, id=0


config 31: rgba=5:6:5:0(16), ds=0:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


config 32: rgba=5:6:5:0(16), ds=16:0, caveat=3038, native=0, level=0, surface=0407, visual=0000, id=0


chose config 6


failed to create surface


Could not initialize egl 


# exit
exit


sh-3.2$ exit
exit

Script done on Wed Jan 27 15:34:32 2010
 
Last edited:
Jun 15, 2007
1,091
9
Oh by the way, I'm gonna be holding off on development for a while. For some reason my debugger completely ate it last night and now whatever I try to debug crashes immediately with a SegFault. I'm still trying to pin down the issue but so far rebooting the phone, uninstalling the app before trying to install over it and debug, restarting my computer, and reinstalling Eclipse on my computer hasn't worked.
 

d1mbu1b

Member
Jan 25, 2010
29
2
got my answer

turns out even when I hyjack the GLThread in the native code with a while (1) loop the frame rate is still 7 fps...

So I guess that the san-angeles demo is just slow go figure.

I wrapped the nativeRender call in app-android.c with a while (1) and added eglSwapBuffers at the end of the loop.

I compiled by adding the eglSwapBuffers prototypes and linking against a copy of n1:/system/lib/*GL*.so that I adb pulled from the device.
Hop this is worth while for somebody.
 
Jun 15, 2007
1,091
9
Sorry guys, still no updates on the graphics stuff. I still can't debug on my phone and have no idea why. At this point, I think my only choice is to try to back everything up and reinstall Ubuntu entirely. I freaking hate using eclipse in ubuntu, it seems like something is always going wrong with it(Installing Eclipse from the Add/Remove programs screen makes it completely borked, had to just download it from the website and even then had weird UI problems and now can't debug. On my netbook, neither way of installing will let me install any plugins) but there's not much of a choice when it comes to using the NDK, outside of trying to fight with cygwin. Might try Mint or some other distribution if Ubuntu keeps giving me problems.
 

skysurfer27

New member
Dec 25, 2007
4
0
If you're running 9.10 Eclipse was affected when they changed stuff in the new version of GTK, you need to export GDK_NATIVE_WINDOWS=1 before starting eclipse.

Also, are you having trouble with adb not finding the device? I always have to adb kill-server then sudo adb start-server for it to pickup my device and any update wants to kill the server and fire it up as a non-root user again.
 
Jun 15, 2007
1,091
9
If you're running 9.10 Eclipse was affected when they changed stuff in the new version of GTK, you need to export GDK_NATIVE_WINDOWS=1 before starting eclipse.

Also, are you having trouble with adb not finding the device? I always have to adb kill-server then sudo adb start-server for it to pickup my device and any update wants to kill the server and fire it up as a non-root user again.

Interesting. That'd probably solve the UI problems. ADB-wise: no problems. It finds my Nexus One perfectly. I figured out all the kill-server/start-server stuff a while ago. The problem is that when I try to debug(and this all the sudden started happening about a week or 2 ago) I get some massive SegFault-like crash while the debugger tries to connect. A couple times, it even caused my phone to reboot entirely. This happens with all apps(including trying to use one of Google's sample apps) and nothing I've tried so far has fixed it. I even tried reverting my phone to stock firmware and doing a full data wipe and it still happens. I can't see any other explanation other than it's something on my computer's side and deleting/redownloading both the Android SDK and eclipse haven't solved it.
 

skysurfer27

New member
Dec 25, 2007
4
0
Does logcat give any clues to what the phone is going through when the debugger connects? Also, do you know if those wipes cleared the Dalvik cache? I wonder if something stale in there could cause such an issue.
 
Jun 15, 2007
1,091
9
Does logcat give any clues to what the phone is going through when the debugger connects? Also, do you know if those wipes cleared the Dalvik cache? I wonder if something stale in there could cause such an issue.

Ya, logcat gives a (very long) error message. Can't remember the contents that well but I think it was a segfault. Like I said, it only happens when it's trying to connect the debugger. I can just go in afterwards and run the same app that I was trying to debug and it runs perfectly. Can't remember where it occurred 'cause the stack trace went through like 50 different packages. Also, a wipe should erase the dalvik-cache(it clears the entire /data partition), but regardless, I tried doing so manually and it didn't solve the issue.
 
Jun 15, 2007
1,091
9
Hmm after reading the release notes for the latest cyanogen(beta 4), that problem with the debugger may have had to do with JIT in beta 3. I enabled it briefly before turning it off again, but from things I've heard earlier, it can cause problems even after being disabled. I'll try again tonight using beta 4. In case people are wondering why I'm still posting here, I'm going to try to get a texture loader header file written up and post it here along with my matrix functions, so we have a fully functioning OpenGL ES 2.0 implementation.
 
Jun 15, 2007
1,091
9
I managed to get up and running and found my first real bug in the OpenGL ES 2.0 library. The info log always returns gibberish after you try to compile a shader, so we get no meaningful explanation of what error occurred. That'll make shader writing a heck of a lot harder for the time being.