Texture size problems

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

Texture size problems

Postby Hachaso » Wed Apr 07, 2010 8:40 am

Hi!

Does anyone know how to solve this problem.

If I create a 3D plane and add a texture of size 512x512 I get an FPS of about 15 fps.
If I minimize the texture size to 256x256 I get around 20 fps.
I have been testing this on my HTC Magic.

Is there any way to somehow speed up the fps, using bigger textures??
The reason why I want a bigger texture is because the quality of the image is much better.
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Top

Postby Fozzle » Tue Apr 20, 2010 7:04 pm

Can you post our code perhaps?
That seems really really slow.
Fozzle
Once Poster
Once Poster
 
Posts: 1
Joined: Wed Apr 14, 2010 9:08 pm

Postby Hachaso » Wed Apr 21, 2010 8:43 am

This is practically my draw code.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.     GL11 gl11 = (GL11) gl;
  2.  
  3.         // draw using hardware buffers
  4.  
  5.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, PlaneVertBufferIndex1);
  6.  
  7.         gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
  8.  
  9.  
  10.  
  11.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordBufferIndex);
  12.  
  13.         gl11.glTexCoordPointer(2, GL11.GL_FIXED, 0, 0);
  14.  
  15.  
  16.  
  17.         gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBufferIndex);
  18.  
  19.        
  20.  
  21.         gl11.glBindTexture(GL10.GL_TEXTURE_2D, textures[2]);
  22.  
  23.        
  24.  
  25.         gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
  26.  
  27.        
  28.  
  29.        
  30.  
  31.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, PlaneVertBufferIndex2);
  32.  
  33.         gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
  34.  
  35.        
  36.  
  37.         gl11.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
  38.  
  39.        
  40.  
  41.         gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
  42.  
  43.        
  44.  
  45.        
  46.  
  47.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, PlaneVertBufferIndex3);
  48.  
  49.         gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
  50.  
  51.        
  52.  
  53.         gl11.glBindTexture(GL10.GL_TEXTURE_2D, textures[1]);
  54.  
  55.        
  56.  
  57.         gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
  58.  
  59.        
  60.  
  61.        
  62.  
  63.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, PlaneVertBufferIndex4);
  64.  
  65.         gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
  66.  
  67.        
  68.  
  69.         gl11.glBindTexture(GL10.GL_TEXTURE_2D, textures[3]);
  70.  
  71.        
  72.  
  73.         gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
  74.  
  75.        
  76.  
  77.  
  78.  
  79.         gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);
  80.  
  81.         gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0);
  82.  
  83.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4



I removed the top and bottom planes from the cube since I didn't need them for what I'm testing.
I have also tested to call gl11.glBindTexture(GL10.GL_TEXTURE_2D, 0);
on 2 of the planes to speed up performance.

Is it correct to do it like this?

What if I want to be able to change the textures on the planes when it rotates. Like it would be a list?
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Thu Apr 22, 2010 12:39 pm

The problem is not your texture size.. at least not the only problem. You have 4 textures and you bind them in a single frame. This slows down the FPS, and you are showing just a cube. Image if you need to draw other stuff. To solve this you must bind as fewer textures as possible per frame. For the cube the smartest way is to have a single texture for all the faces, and using texture coordinates you can show on each face a different image. Next, for each face you set up all the buffers and call the render. Again, this is not good. You must make the cube a single array and render it in a single pass, not 4 or 6.

Remember:
- state changes are SLOW
- render calls are SLOW
- texture binds are SLOW

So you have to organize your data this way:

- group as many primitives as you can together in the same array, this way you will have fewer glDraw.. calls
- use as few textures as possible and do not call bind if the texture you need is already binded
- order your data to be drawn depending on textures

Also, try to reuse binded data.
For example, if you have to draw 100 cubes in different positions, you don't have to bind your data 100 times:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. bind texture of the cube
  2.  
  3. bind arrays of the cube
  4.  
  5. for each position
  6.  
  7.      push matrix
  8.  
  9.      gl.glTranslatef
  10.  
  11.      gl.glDrawArrays
  12.  
  13.      pop matrix
Parsed in 0.031 seconds, using GeSHi 1.0.8.4

So for every cube you just call glTranslate and glDrawArrays. This will improve your fps.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Postby Hachaso » Thu Apr 22, 2010 1:14 pm

Thanks Zorro

But if I want to be able to change the textures as I rotate. As it would be a list.
If I in total have like 20 images that I want to show.

I start with image1 on the front face of the cube. I rotate left and come to image2...rotate..image3 and so on.
How can I do this with the 20 images without getting such slow performance?

Maybe create a huge texture Atlas??

Please help.
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Thu Apr 22, 2010 1:40 pm

You can create a huge texture atlas, but it would be difficult to update the atlas if one picture needs to be changed.

If your app is just the cube and nothing else, you can stick with your first implementation, four planes, each with it's own texture, which let's you add new pictures without affecting the others. You can speed up the rendering by making arrays for a single plane, centered in origin, bind the arrays, then render the cube using for each face a texture bind then translate and rotate. This way the only bottleneck will be the texture bind, which is acceptable i guess.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Top

Postby Hachaso » Thu Apr 22, 2010 1:47 pm

Hi Zorro!

I'm quite new at this.

Your wrote:

You can speed up the rendering by making arrays for a single plane, centered in origin, bind the arrays, then render the cube using for each face a texture bind then translate and rotate.

How in code do you mean I should do this?

What is the difference between that an my above method?
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Thu Apr 22, 2010 2:22 pm

First, in your code you use GL11 and hardware buffers, but that is not going to help (in your case). That's because buffers help when you have large amounts of data, while your buffers contain only a small number of vertices. You can use plain GL10 arrays and the FPS should not go down.

In your code you have for each face:
- bind texture face
- setup arrays
- draw face

What am i saying is that you can get rid of 'setup arrays' part and just:

do once: setup arrays
do six times:
- bind texture
- transform face
- draw face

Now, how can you modify your code? I see you have PlaneVertBufferIndex1 for the first face. Make that a quad with the vertices in the following positions: (d,d,0) (d,-d,0) (-d,-d,0) (-d,d,0). D is the half of the face width. As you can see the face is in the XoY plane, the Z is always 0. Now you must draw all the faces using this buffer.

First, translate the modelview matrix to the point where the center of the cube will be.

gl.glLoadIdentity(); // reset matrix
gl.glTranslate (cubex, cubey, cubez);

If you want to rotate the cube, here is where you put your main rotation, around Y axis
gl.glRotatef( angle, 0,1,0);

Then bind the arrays once:
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, PlaneVertBufferIndex1);
gl11.glVertexPointer(3, GL10.GL_FIXED, 0, 0);
gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, textureCoordBufferIndex);
gl11.glTexCoordPointer(2, GL11.GL_FIXED, 0, 0);
gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, indexBufferIndex);

After that draw each face with these transformations:

// face 1 (right in front of the screen)
gl.glPushMatrix();
gl11.glBindTexture ...
gl.glTranslatef(0,0,d); // translate with 'd' towards the camera (on the Z axis), no rotation
gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
gl.glPopMatrix();

// face 2 (on the right)
gl11.glBindTexture ...
gl.glPushMatrix();
gl.glRotatef(90, 0,1,0); // rotate 90 degrees to the right
gl.glTranslatef(0,0,d); // translate 'd' on the same Z axis, which is now rotated
gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
gl.glPopMatrix();

// face 3 (on the left)
gl11.glBindTexture ...
gl.glPushMatrix();
gl.glRotatef(-90, 0,1,0); // rotate 90 degrees to the right
gl.glTranslatef(0,0,d); // translate 'd' on the same Z axis, which is now rotated
gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
gl.glPopMatrix();

// face 4 (in the back)
gl11.glBindTexture ...
gl.glPushMatrix();
gl.glRotatef(180, 0,1,0); // rotate 180 degrees to the right
gl.glTranslatef(0,0,d); // translate 'd' on the same Z axis, which is now rotated
gl11.glDrawElements(GL11.GL_TRIANGLES, 6, GL11.GL_UNSIGNED_SHORT, 0);
gl.glPopMatrix();

With this you have all the faces drawn with the buffers binded only once, at the beginning.
You can try to implement this, it should speed up the cube. If there are problems, let me know.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Postby Hachaso » Thu Apr 22, 2010 2:26 pm

Thanks a lot Zorro.
I will send you a mail as soon as I have tried this.
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Top

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

Who is online

Users browsing this forum: No registered users and 2 guests