I'm doing my first steps in OpenGL for Android, for developing Augmented Reality apps and I'm having a bad time integrating OpenGL shapes in front of the camera image. The program is supposed to draw a square in the XZ plane (assuming that Z axis is pointing up) over the camera image, but I'm getting two squares and they are smaller than if I don't use the camera.
Here's a bit of code.
In the main activity, I set the views and sensors like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer
MyRenderer renderer = new Lesson02();
glSurface.setRenderer(renderer);
glSurface.getHolder().setFormat(PixelFormat.TRANSLUCENT);
//Set the GLSurface as View to this Activity
setContentView(glSurface);
mCameraView = new CameraView(this);
addContentView(mCameraView, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
List<Sensor> listSensors = mSensorManager
.getSensorList(Sensor.TYPE_ACCELEROMETER);
if (listSensors.size() > 0) {
mSensorManager.registerListener(renderer,
listSensors.get(0), SensorManager.SENSOR_DELAY_UI);
}
listSensors = mSensorManager.getSensorList(Sensor.TYPE_MAGNETIC_FIELD);
if (listSensors.size() > 0) {
mSensorManager.registerListener(renderer,
listSensors.get(0), SensorManager.SENSOR_DELAY_UI);
}
}
The onDraw method of my renderer do something like this:
public void onDrawFrame(GL10 gl) {
// Get rotation matrix from the sensor
SensorManager.getRotationMatrix(rotationMatrix, null,
mAccelerometerValues, mMagneticValues);
// As the documentation says, we are using the device as a compass in
// landscape mode
SensorManager.remapCoordinateSystem(rotationMatrix,
SensorManager.AXIS_Y,
SensorManager.AXIS_MINUS_X,
remappedRotationMatrix);
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Load remapped matrix
gl.glMatrixMode(GL10.GL_MODELVIEW);
//Reset The Current Modelview Matrix
gl.glLoadIdentity();
gl.glLoadMatrixf(remappedRotationMatrix, 0);
// Draw square
gl.glTranslatef(-1.2f, 18.0f, 0.0f);
//gl.glTranslatef(0.0f, -1.2f, -6.0f); //Move down 1.2 Unit And Into The Screen 6.0
square.draw(gl); //Draw the square
}
Finally, I inicialize everything within the onSurfaceCreated method like this:
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
/*
* By default, OpenGL enables features that improve quality but reduce
* performance. One might want to tweak that especially on software
* renderer.
*/
gl.glDisable(GL10.GL_DITHER);
/*
* Some one-time OpenGL initialization can be made here probably based
* on features of this particular context
*/
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
}
If I comment the line
glSurface.getHolder().setFormat(PixelFormat.TRANSLUCENT);
within the activity it draws the square good and smooth, and only once. But when I make it translucent or even transparent, it draws two smaller squares that are not well-drawn when I spin the mobile.
If anyone knows what's going on, it'd be very appreciated.
Thanks!!
Just found out the solution looking at the demos. Within my main activity, I need to set the EGL configuration chooser. Something like this should be written in the onCreate method of the main activity (in which I add the opengl view and the camera view):
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
// We want an 8888 pixel format because that's required for a
//translucent window. And we want a depth buffer.
glSurface.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // <-- NEW LINE ADDED
//Set our own Renderer
MyRenderer renderer = new MyRenderer ();
glSurface.setRenderer(renderer);
glSurface.getHolder().setFormat(PixelFormat.TRANSLUCENT);
//Set the GLSurface as View to this Activity
setContentView(glSurface);
mCameraView = new CameraView(this);
addContentView(mCameraView, new LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT));
// More code ...
}
Apparently, that line is necessary for having a translucent opengl window.