Reputation: 859
I made a simple android application, which renders a square using openGL. The square can be moved using your finger. It works fine, but while moving the square around you can feel a considerable input lag, especially when doing circular motions. Are there any tricks to reduce or mask this lag?
Here's the code:
public class InputTestActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new InputTestView(this));
}
public class InputTestView extends GLSurfaceView {
private InputTestRenderer renderer;
private float prevX;
private float prevY;
public InputTestView(Context context) {
super(context);
renderer = new InputTestRenderer();
setRenderer(renderer);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
renderer.moveEye(prevX - x, prevY -y);
case MotionEvent.ACTION_DOWN:
prevX = x;
prevY = y;
break;
}
return true;
}
}
public class InputTestRenderer implements Renderer {
private final float[] verts = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f };
private final int nrOfVerts = verts.length / 3;
private FloatBuffer vertBuf;
private float eyeX;
private float eyeY;
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glColor4f(1, 0, 0, 1);
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(verts.length * Float.SIZE / 8);
byteBuffer.order(ByteOrder.nativeOrder());
vertBuf = byteBuffer.asFloatBuffer();
vertBuf.put(verts);
vertBuf.position(0);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glOrthof(-width / 2, width / 2, height / 2, -height / 2, 1, 100);
gl.glMatrixMode(GL10.GL_MODELVIEW);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
gl.glLoadIdentity();
synchronized (this) {
gl.glTranslatef(-eyeX, -eyeY, -10);
}
gl.glScalef(200, 200, 1);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuf);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, nrOfVerts);
}
public synchronized void moveEye(float deltaX, float deltaY) {
this.eyeX += deltaX;
this.eyeY += deltaY;
}
}
}
Upvotes: 1
Views: 1553
Reputation: 38707
Suspect your UI thread and your rendering thread are fighting for CPU time. Try adding this line to onSurfaceCreated() :
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
Reducing the renderer's priority ensures that motion events get processed a bit more promptly. Seems to make a difference.
FWIW I dislike GLSurfaceView's design and prefer to aim for a set framerate, usually 50, using Handler.postDelayed() to schedule each frame to be drawn at 20ms intervals.
Upvotes: 1