OpenGL performance question

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

OpenGL performance question

Postby eugenk » Thu Jan 31, 2008 4:05 pm

Hi ALL ! Now I'm writing some complex OpenGL application, involves many objects. I notice, that animation performance on emulator decreases very much, when the number of objects is large (about 1000). So the first question. What will be application speed on real GooglePhone comparatively with emulator (Athlon 64 3000Mhz, 1GB) ? The second question. How can I speed up my application ? Most of my objects is not animated and draws one time. Is there some method to save non animated objects as bitmap, and then draw this bitmap without rendering ?
Posts: 29
Joined: Wed Jan 30, 2008 8:07 pm
Location: Russian Federation, Moscow


Re: OpenGL performance question

Postby eugenk » Mon Feb 04, 2008 1:14 pm

Hi ! I have solved this. Notes for one who also need for saving OpenGL drawings as a textures
1) OpenGL drawing may be saved as Buffer using
glReadPixels(int x, int y, int width, int height, int format, int type, Buffer pixels).
where x, y - upper left drawing corner,
width, height - it's width and height,
format must be GL10.GL_RGBA,
type must be GL10.GL_UNSIGNED_BYTE,
Buffer - receiver for saved pixels.

2) After OpenGL drawing was saved, one may convert it to Android bitmap, using
Bitmap.createBitmap(int[] colors, int width, int height, boolean hasAlpha)
where colors - saved pixels from OpenGL drawing,
x,y, width, height - texture Rect,
hasAlpha must be true, because ReadPixels saves alpha-component also.

3) One can draw saved and converted OpenGL drawing using Canvas.drawBitmap. It works much faster, that OpenGL rendering.

4) OpenGL ReadPixels format is incompatible with Android format. At first, mixed up R and B components. At second, mixed up order of horizontal pixel's rows. So, before createBitmap, pixel's array must be corrected by transposition of R and B, and transposition of pixel's rows.

Whole SavePixesl() method:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  2.  protected Bitmap SavePixels(int x, int y, int w, int h, GL10 gl)
  4.      {  
  6.           int b[]=new int[w*h];
  8.           int bt[]=new int[w*h];
  10.           IntBuffer ib=IntBuffer.wrap(b);
  12.           ib.position(0);
  14.           gl.glReadPixels(x, y, w, h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
  16.           for(int i=0; i<h; i++)
  18.           {
  20.                for(int j=0; j<w; j++)
  22.                {
  24.                     //correction of R and B
  26.                     int pix=b[i*w+j];
  28.                     int pb=(pix>>16)&0xff;
  30.                     int pr=(pix<<16)&0x00ff0000;
  32.                     int pix1=(pix&0xff00ff00) | pr | pb;
  34.                     //correction of rows
  36.                     bt[(h-i-1)*w+j]=pix1;
  38.                }
  40.           }                  
  42.           Bitmap sb=Bitmap.createBitmap(bt, w, h, true);
  44.           return sb;
  46.      }
Parsed in 0.034 seconds, using GeSHi

In complex OpenGL application, where only small objects quantity is animated, this trick allows speed up your application in many and many times. How to use this:
1) Suppose, that we have some OpenGL objects quantity. First of all, they must be rendered using OpenGL. Let's do it.
2) After objects was rendered, save them as Android textures with SavePixels() method.
3) With next onDraw() calls, use drawBitmap() method instead rendering.
4) When some objects must be changed at some moment of time, again render them and save as textures.

Hope that this trick will be useful for somebody.
Posts: 29
Joined: Wed Jan 30, 2008 8:07 pm
Location: Russian Federation, Moscow

Postby tikimove » Fri Aug 28, 2009 2:42 pm

Your tip is realy usefull, thanks. But how do you make the OpenGL render without a GLSurfaceView ?
Posts: 30
Joined: Tue Jan 13, 2009 2:59 pm

Postby WarrenFaith » Fri Aug 28, 2009 4:29 pm

This is weird! But hell, the idea to save it as an image and display it is great! Very interesting solution for a performance problem :)
Respectable idea!
Posts: 227
Joined: Fri Mar 13, 2009 10:59 am
Location: Berlin, Germany

Postby _Auron_ » Sat Sep 12, 2009 4:07 am

This is useless in realtime graphics output, or at least completely wasteful. OpenGL rendering is done using hardware graphics acceleration, your method is entirely using the CPU and draws pixel-by-pixel. If you really want to do your method though, you can use glCopyTexSubImage2D() and the G11 (though not every device supports OpenGL ES 1.1) extension glDrawTexiOES(). The first copies the screen content to a texture, and the second draws (without the ability to rotate or color, just a straight blit) to the screen.

Again though, if you're doing any realtime rendering, there is no reason why you'd want to copy a static copy and draw that because the objects would be updating each frame.

tikimove: It's a requirement to render in the Android Framework, and I don't know why you'd want to do otherwise. You may be able to do it using the NDK, but otherwise for an application you'd have to allocate a seperate surface to lock the rendering to, and that's what GLSurfaceView is for. Why don't you want to use it?
Posts: 9
Joined: Fri Jul 10, 2009 7:50 am

Postby isaaclin » Wed Sep 16, 2009 10:18 am

Good idea! Seems like there have a demo application I saw which using the same method to fix this problem. :P
Posts: 3
Joined: Wed Sep 16, 2009 9:56 am


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

Who is online

Users browsing this forum: No registered users and 2 guests