Fastest sprite rendering

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

Fastest sprite rendering

Postby vkornienko » Tue Oct 21, 2008 11:33 am

Hi all!
First of all, sry for my English.
I would like to develop a game for Android platform. It will be based on the sprite animation... So the question is: what is the fastest way for sprite rendering? I mean the fastest way on real devices.
I tried to render 384 (24x16) sprites with size 20x20 pixels using Canvas of SurfaceView (see LunaLander). The result is about 30 fps on my laptop with T8300 2.4GHz CPU.
It is interesting to see result of drawing using OpenGL (textures on the polygons or somehow else).
Has anybody such experience?
vkornienko
Freshman
Freshman
 
Posts: 3
Joined: Tue Oct 21, 2008 11:19 am

Top

Postby MrSnowflake » Tue Oct 21, 2008 1:19 pm

Testing this on the emu won't give you a good result, as the emulator can use other optimizations the real device doesn't have (ie hw accellerated canvas). But make a test app with 2 modes, 1 using the canvas and the other, which draws the same, in OpenGL ES. I'm very interested in the results. The G1 will be released in a couple days, so a lot of users will be able to test this for u. You could even build in some netwerk support which sends the results to you.
User avatar
MrSnowflake
Moderator
Moderator
 
Posts: 1439
Joined: Sat Feb 16, 2008 3:11 pm
Location: Flanders, Belgium

Postby timcharper » Sat Nov 29, 2008 5:31 am

I too am wondering about this.

Is it faster to use the Animate classes to move stuff around? Will this take advantage of 2d acceleration? It seems that a blit clear screen and then re-painting the screen is sub-optimal.

Tim
timcharper
Freshman
Freshman
 
Posts: 2
Joined: Sat Nov 29, 2008 5:25 am
Location: Utah

Postby Ultrano » Sun Jan 04, 2009 9:57 am

I thought I'd post some "benchmark" results. A game with a fullscreen background bitmap, and 600 32x32 sprites on it (each is alphablended). Did not involve timers, just my experienced eye, for now.

Canvas:
- on real device runs a bit slower than the emulator on a C2D 2.4GHz + DDR2@2x400MHz
- around 20fps in that game
- bad: can't specify opacity of a Blt, or I couldn't find it
- good: very easy to start-up with
- good: directly draw text

OpenGL:
- on emulator that game runs at 2fps, on real device it's over 50+ FPS!
- bad: hard to start-up with
- bad: keep textures in POW sizes
- bad: no text, make spritesheets and custom text-drawing funcs
- bad: 1 cheap Australian Android phone comes-out very soon, with no gpu, with 320x240 screen. Oh well, at least it's just like $50 cheaper, and lacks too many G1 features to be important.
- bad: IntBuffer is buggy, so no streaming dynamic data in GL_FIXED format
- good: again, 50+ FPS.
- good: blending! alpha, additive, multiply, subtract - its' awesome
- good: per-vertex color-modifiers, alpha can specify per-quad opacity.
- good: lets you put the game-code in another thread, so finally a real game-loop. As it should be for games.
Ultrano
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Dec 20, 2008 12:53 am

Postby thesombrereokid » Mon Jan 05, 2009 2:02 pm

Ultrano wrote:I thought I'd post some "benchmark" results. A game with a fullscreen background bitmap, and 600 32x32 sprites on it (each is alphablended). Did not involve timers, just my experienced eye, for now.

Canvas:
- on real device runs a bit slower than the emulator on a C2D 2.4GHz + DDR2@2x400MHz
- around 20fps in that game
- bad: can't specify opacity of a Blt, or I couldn't find it
- good: very easy to start-up with
- good: directly draw text

OpenGL:
- on emulator that game runs at 2fps, on real device it's over 50+ FPS!
- bad: hard to start-up with
- bad: keep textures in POW sizes
- bad: no text, make spritesheets and custom text-drawing funcs
- bad: 1 cheap Australian Android phone comes-out very soon, with no gpu, with 320x240 screen. Oh well, at least it's just like $50 cheaper, and lacks too many G1 features to be important.
- bad: IntBuffer is buggy, so no streaming dynamic data in GL_FIXED format
- good: again, 50+ FPS.
- good: blending! alpha, additive, multiply, subtract - its' awesome
- good: per-vertex color-modifiers, alpha can specify per-quad opacity.
- good: lets you put the game-code in another thread, so finally a real game-loop. As it should be for games.



i'd love to know how you got this kind of performance i'm scratching my head here with 2 odd frames a second on the g1 :/ i'm drawing about 200 textured QUADS with glDrawArrays and a floatbuffer with GL_FLOAT data for the vertices and textures
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Postby Ultrano » Tue Jan 06, 2009 7:09 am

2 float-buffers (position and ST-coord) and 1 byte-buffer (RGBA color per vertex).
manually unrolling the quads into GL_TRIANGLES.
Reusing the same 3 buffers, keeping 3 local vars "float posArray[], float uvsArray[], byte clrArray[]". On flushing, writing the data from these arrays into the 3 buffers.

I recently tested someone else's 3D game, and it ran at 20+ FPS with complex models (several k tris, textured, lit)

Aand, we've seen the Neocore demo at 25fps :)
Ultrano
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Dec 20, 2008 12:53 am

Top

Postby Ultrano » Tue Jan 06, 2009 7:21 am

Ah, and also .... all tutorials on Android GL I've seen are quite deceptive. Use some common sense and search for complex non-android GLES examples, that start fast and run fast. ES1.1 support, VBOs, minimize calls and binds, etc.
Ultrano
Junior Developer
Junior Developer
 
Posts: 16
Joined: Sat Dec 20, 2008 12:53 am

Postby thesombrereokid » Tue Jan 06, 2009 4:15 pm

i've tried a hell of a lot of stuff and i'm still a bit stumped this is the code where it definatly slows down any ideas where i'm going wrong?

if the application runs but only doing a couple of these draw calls it's fast if it runs with the 150-200 i need it runs about 5fps max

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.        
  2.  
  3. public void draw(View view)
  4.  
  5.         {
  6.  
  7.                 if(my_texture != null)
  8.  
  9.                 {
  10.  
  11.                         flushVertexBuffer();
  12.  
  13.                        
  14.  
  15.                         view.bindTexture(my_texture.my_texture);
  16.  
  17.                        
  18.  
  19.                         view.my_gl10.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
  20.  
  21.                        
  22.  
  23.                         view.my_gl10.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
  24.  
  25.                        
  26.  
  27.                         view.my_gl10.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
  28.  
  29.                 }
  30.  
  31.         }
  32.  
  33.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


view just holds my GL10 object and bindtexture just makes sure the texture isn't already bound and the list is sorted to minimize texture binds also flushvertexbuffer just puts this objects vertexarray into vertexbuffer.

Any ideas where i'm going wrong would be greatly appreciated, thanks
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Postby mortefer » Tue Jan 06, 2009 8:48 pm

As Ultrano stated to me today, use GL_FIXED, not GL_FLOAT for VBOs.
Don't forget to convert coordinates (int int_coord = (int)(float_coord*65536)).
After switching to GL_FIXED application gained smth around 5-6 fps. But this was, as stated above, complex geometry (up to 1,5k vertices per model), ligting, heavy textures.
mortefer
Experienced Developer
Experienced Developer
 
Posts: 54
Joined: Sat Dec 20, 2008 11:24 am

Postby thesombrereokid » Wed Jan 07, 2009 9:55 am

mortefer wrote:As Ultrano stated to me today, use GL_FIXED, not GL_FLOAT for VBOs.
Don't forget to convert coordinates (int int_coord = (int)(float_coord*65536)).
After switching to GL_FIXED application gained smth around 5-6 fps. But this was, as stated above, complex geometry (up to 1,5k vertices per model), ligting, heavy textures.


the thing is when i switched to GL_FIXED my vertexBuffer would crap out if i put the int array in all in one, but if i put them in one at a time it was fine but i'm pretty sure this a bit of a performace hit too and someone around here said int buffers are buggy
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Postby thesombrereokid » Wed Jan 07, 2009 10:36 am

does anyone know if it could be my use of drawarrays is anyone else using drawarrays or are they drawing all thier things or a bunch of them at once with drawelements?

also i probably should've mentioned this before but on starting my application it starts with a blank screen unless i run another 3d application first, probably cause my setup code is wrong i haven't bothered fixing it because i didn't think it could be related to my performance issues but now i'm not so sure
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Postby mortefer » Wed Jan 07, 2009 12:52 pm

i use glDrawArrays. tried glDrawElements no significant differences.
mortefer
Experienced Developer
Experienced Developer
 
Posts: 54
Joined: Sat Dec 20, 2008 11:24 am

Postby thesombrereokid » Thu Jan 08, 2009 4:36 pm

just thought i'd update people for future reference all my problems where down to my looping and initlization, i made it more like the example code and it worked much faster and stopped my locking up the eglsurface still need to get my textures to work though thanks guys :D
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Postby mortefer » Thu Jan 08, 2009 11:43 pm

Found out an interesting thing today (thanx Ultrano).
I implemented a simple FPS monitor using TextView above OpenGL surface. average FPS of the application: ~18.
I used the following string to output the nicely formatted FPS string:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. String.format("%5.2f", 1000.f/delta)+" fps";
Parsed in 0.032 seconds, using GeSHi 1.0.8.4

The next thing i've noted that FPS were down every 5-6 seconds. I've checked console view and guess what? It was garbage collector. Removing this string helped to DOUBLE the fps and even more. Top FPS now are 50. average ~40.
mortefer
Experienced Developer
Experienced Developer
 
Posts: 54
Joined: Sat Dec 20, 2008 11:24 am

Postby thesombrereokid » Thu Jan 15, 2009 3:10 pm

mortefer wrote:Found out an interesting thing today (thanx Ultrano).
I implemented a simple FPS monitor using TextView above OpenGL surface. average FPS of the application: ~18.
I used the following string to output the nicely formatted FPS string:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. String.format("%5.2f", 1000.f/delta)+" fps";
Parsed in 0.033 seconds, using GeSHi 1.0.8.4

The next thing i've noted that FPS were down every 5-6 seconds. I've checked console view and guess what? It was garbage collector. Removing this string helped to DOUBLE the fps and even more. Top FPS now are 50. average ~40.


what do you mean removing this string do you mean making it garbage collect less frequently? how did you do that my fps monitor shows an fps of about 10 fps with 300 polys if i remove my texture binds (i plan on putting all the textures on one sheet like our c++ code does) i can get it up to 18 fps maybe, this still seems a lot slower than everyone else is getting
thesombrereokid
Freshman
Freshman
 
Posts: 9
Joined: Thu Dec 04, 2008 11:53 am

Top
Next

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest