Adding control to the OpenGL spinning cube
Posted by Marco Dinacci on 0 commentsThis demo extends on the Create a spinning cube OpenGL to show how to control the cube using a D-pad. We're going to increment the speed rotation along the X and Y axes using the directional keys of the D-pad.
The biggest change is that we now have our custom class that extends the SurfaceView
.
We do this so we can override the onKeyUp
method and be notified when the user uses the D-pad.
The onCreate
of our Activity
looks like this:
public class SpinningCubeActivity2 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// go fullscreen
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// create our custom view
GLSurfaceView view = new OpenGLSurfaceView(this);
view.setRenderer((Renderer)view);
setContentView(view);
}
}
GLSurfaceView
also implements the Renderer
interface.
The onSurfaceCreated
and onSurfaceChanged
method are exactly the same as in the previous recipe, most of the changes occur in the onDrawFrame
as we introduce four new parameters:
mXrot
and mYrot to control the rotation of the cube along the X and Y axis.mXspeed
andmYSpeed
to store the speed of the rotation along the X and Y axis.
class OpenGLSurfaceView extends GLSurfaceView implements Renderer {
private Cube mCube;
private float mXrot;
private float mYrot;
private float mXspeed;
private float mYspeed;
public OpenGLSurfaceView(Context context) {
super(context);
// give focus to the GLSurfaceView
requestFocus();
setFocusableInTouchMode(true);
mCube = new Cube();
}
@Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0.0f, 0.0f, -10.0f);
gl.glRotatef(mXrot, 1.0f, 0.0f, 0.0f);
gl.glRotatef(mYrot, 0.0f, 1.0f, 0.0f);
mCube.draw(gl);
gl.glLoadIdentity();
mXrot += mXspeed;
mYrot += mYspeed;
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_DPAD_LEFT)
mYspeed -= 0.1f;
else if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT)
mYspeed += 0.1f;
else if(keyCode == KeyEvent.KEYCODE_DPAD_UP)
mXspeed -= 0.1f;
else if(keyCode == KeyEvent.KEYCODE_DPAD_DOWN)
mXspeed += 0.1f;
return true;
}
// unchanged
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
GL10.GL_NICEST);
}
// unchanged
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
}
Cube
is inherited from the previous recipe. Don't forget to call the requestFocus()
and setFocusableInTouchMode(true)
in the constructor of the view or else the key events will not be received.
The complete code is available.