Can not get smooth movement i Z axis with glTranslatef

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

Can not get smooth movement i Z axis with glTranslatef

Postby Hachaso » Thu Feb 25, 2010 10:38 pm

Hi!

I have been testing different OpenGL stuff on my Android Mobile phone, supporting OpenGL ES 1.1.

I have created a 3D plane and I'm trying to zoom out the object using glTranslatef.

This is the call I'm doing:

glTranslatef(0.0f, 0.0f, fOldZ);

fOldZ will be added or subtracted with 0.4f to make it zoom in or out.

The problem I'm seeing is that the object does not move smoothly. It has more of a choppy movement.

Could someone maybe explain what may be wrong?
Can I do something to make it zoom in/out more smoothly?

First I thought it could have been something to do with fixed point values but the function does take float values so it can't be that.

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

Top

Postby zorro » Fri Feb 26, 2010 2:08 pm

Hello. I guess your step (0.4f) is just too big to be used every frame. One OpenGL unit is not that small (in the default initialization, without scaling anything), and 0.4 is nearly half of that. Try using a smaller step or a time-based movement to be sure that the object is moving at the same speed on all the phones, regarding of their processor speed.

With time-based movement i'm saying that you should not move the object by an absolute value (0.4f), but instead use a variable one, depeding on your frame-rate. If the time between 2 successive frames is DT (floating point value, 1.0=1second), then try moving the object with DT*50.0f or DT*100.0f for example. If DT is computed in milliseconds (1000=1second) then translate by DT*0.1f, etc.. You can try different values to find the one that suits your purpose.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Postby Hachaso » Fri Feb 26, 2010 6:32 pm

Hi!

Thanks for the suggestions.

I'm quite new at this so I would appreciate some detailed example or something similar.

I have tried to make the movement smaller like 0.1f instead but that did not help much.

Could you please explain maybe with some code how time-based movement works?

I have tried to understand your explanation but can't really figure it out.
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Sat Feb 27, 2010 12:55 pm

First of all, you are developing only on the emulator, or you have an android device ? On the emulator the performance is really nasty so the smooth movement can only be achieved on a real device.

Anyway, look at the following code:
At the beginning of each frame we compute the time interval betwen frames, dt.
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. public int dt = 0;
  2. public float currentZ = -1.0f;
  3. public long timePreviousUpdate = 0;
  4. public long timeNow;
  5. public boolean bZoomIn = false, bZoomOut = false;
  6. public void onDrawFrame(GL10 gl)
  7. {
  8.         timeNow = System.currentTimeMillis();
  9.         if(timePreviousUpdate == 0)
  10.                 timePreviousUpdate = timeNow;
  11.         dt = (int) (timeNow - timePreviousUpdate);
  12.         timePreviousUpdate = timeNow;
  13.         if (dt > 500)
  14.             dt = 1;
  15.  
Parsed in 0.032 seconds, using GeSHi 1.0.8.4


With dt computed, we use it in every movement calculations to obtain constant movement on all devices, on different hardware/phones. We limit the dt at half of a second (500) to prevent bing jumps in movement after special events (like loading a level, which can take several seconds and dt is really big).

Right now i don't know how you want the object to zoom in/out (by finger or automatically). I used 2 boolean flags for zoomin/out. These must be set true or false in your activity class, at onTouchEvent. The movement is simple. I multiplied the dt with 0.0005 (very small value) because dt is between 1 and 1000 (1000 = 1 second). This can be written more ellegant this way: dt/1000.0f * 0.5f.

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. if(bZoomIn)
  2.       currentZ += dt*0.0005f;
  3. if(bZoomOut)
  4.       currentZ -= dt*0.0005f;
  5.  
  6. gl.glLoadIdentity();
  7. gl.glTranslatef(0.0f, 0.0f, currentZ);
  8. // draw object (...)
  9. }
  10.  
Parsed in 0.031 seconds, using GeSHi 1.0.8.4


If the game runt at 10 FPS: dt = 100, the movement step will be: 100*0.0005f = 0.050
If the game runt at 20 FPS: dt = 50, the movement step will be: 50*0.0005f = 0.025
So when the fps doubles, the new step for movement is half the first one.

This way, in a second, at 10 fps and at 20 FPS we will move the same distance, 0.5 GL units:
1 sec = 10 frames at 10FPS with dt=0.050 => 0.050 * 10 = 0.5 GL units
1 sec = 20 frames at 20FPS with dt=0.025 => 0.025 * 20 = 0.5 GL units
This means constant time-based movement, FPS independent movement, which is critical for any game.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Postby Hachaso » Mon Mar 01, 2010 9:52 pm

Hi zorro!

Thanks a lot for this code snip.
I will test this as soon as I can to verify and let you know how it goes through this Forum.
I'm going to test this on an HTC Magic device.

I'm doing just that, zooming in/out when the screen is touched, using onTouchEvent.

Another small question. Could the low performance be affected of the image size used as texture.
I guess that mip maps are used when you zoom in or out?

Could it be that the Image is too big and it makes the performance slow in the beginning of the zoom out.
Looks like it get smoother the smaller the image gets, when it's more zoomed out.
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Mon Mar 01, 2010 10:36 pm

It's normal to get better performance when the quad is smaller because there are less pixels to put on screen, although the number of texels is the same. But the difference should not be very big on the actual device. How big is your texture, 512x512, 1024x1024 or more?
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Top

Postby Hachaso » Mon Mar 01, 2010 10:39 pm

The texture is 512x512

I noticed that if I used 256x256, the quality was too bad.
So I made sure to use a bigger image and scaled it down so the quality is better.

How do you solve this problem with texture quality?
Also the problem with different screen resolutions, screen sized ?
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Mon Mar 01, 2010 11:15 pm

It's ok to use 512x512, even 1024x1024 if you want to have extra quality.
For mipmap use in Android, you can look at this link:
http://insanitydesign.com/wp/2009/08/01 ... s-mipmaps/

To run your app on different screen sizes, the easiest way is let Android automatically scale your app on every phone (let your app run in compatibility mode).
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Postby Hachaso » Tue Mar 02, 2010 9:22 am

Thanks again!

All the information you have given me is valuable for me. Thanks

You wrote: To run your app on different screen sizes, the easiest way is let Android automatically scale your app on every phone (let your app run in compatibility mode).

How do you tell Android to scale automatically?

Is it by using the different drawable folders for the images?
Maybe something in the Android Manifest file ?
Hachaso
Developer
Developer
 
Posts: 43
Joined: Mon Jan 26, 2009 11:44 am

Postby zorro » Tue Mar 02, 2010 9:42 am

If you do nothing, the App will be scaled automatically.
A must-read page about different screen sizes is here:
http://developer.android.com/guide/prac ... pport.html

If you want explicit control of the scaling, you must use the <supports-screens> flag in the manifest file. This is available from the 1.6 up. Anyway it is good practice to compile your app with the latest SDK (now it's 2.1) and set the minSdkVersion to '3' value to support the old phones too.
User avatar
zorro
Experienced Developer
Experienced Developer
 
Posts: 71
Joined: Mon Aug 10, 2009 3:11 pm
Location: Romania

Top

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

Who is online

Users browsing this forum: No registered users and 2 guests