[Android Q&A, Help & Troubleshooting] TobiasReich:
Hello everyone,

I have an Android OpenGL Problem with my Galaxy S3 (Android 4.0.4) which I really can't fix.

Everything works fine on the Galaxy S1 and on an S2 which seems to have almost the same GPU.

I try to make an AR-App but I always get a problem with transparent pixels on top of my camera preview. It only appears when the pixels are transparent and looks like "Burned colors" or value overflow or something like that.

So please tell me what I'm doing wrong or try it if you have a S3. Maybe mine is just broken?? I created a small testprogram for you. Please take a look at this:

public class MainActivity extends Activity {
private GLSurfaceView mGLView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new GLSurfaceView(this);
mGLView.setEGLContextClientVersion(2);
mGLView.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
mGLView.getHolder().setFormat(PixelFormat.TRANSLUCENT);
mGLView.setZOrderOnTop(true);
GameRenderer renderer = new GameRenderer();
mGLView.setRenderer(renderer);
setContentView(new CameraView(this), new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
addContentView(mGLView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}

@Override
protected void onPause() {
super.onPause();
mGLView.onPause();
}

@Override
protected void onResume() {
super.onResume();
mGLView.onResume();
}
}

The CameraView looks like that:

public class CameraView extends SurfaceView implements SurfaceHolder.Callback{

SurfaceHolder surfaceHolder;
Camera camera;

public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}

/**
* @param context
*/
public CameraView(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
try {
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(w, h);
camera.setParameters(parameters);
} catch (Exception e) {
Log.w("CameraView", "Exception:" , e);
}
camera.startPreview();
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
} catch (IOException exception) {
camera.release();
camera = null;
}
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
camera.stopPreview();
camera.release();
camera = null;
}
}

The GameRenderer:

public class GameRenderer implements GLSurfaceView.Renderer {

private final String vertexShaderCode =
"uniform mat4 uMVPMatrix; \n" +
"attribute vec4 vPosition; \n" +
"void main(){ \n" +
" gl_Position = uMVPMatrix * vPosition; \n" +
"} \n";

private final String fragmentShaderCode =
"void main(){ \n" +
" gl_FragColor = vec4(1.0, 1.0, 1.0, 0.3); \n" +
"} \n";

private int loadShader(int type, String shaderCode){
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}

// END OF SHADER STUFF

private int mProgram;
private int maPositionHandle;
private int muMVPMatrixHandle;

private FloatBuffer triangleVB;

public GameRenderer() {
}

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
GLES20.glClearColor(0,0,0,0);
initShapes();
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mProgram, vertexShader);
GLES20.glAttachShader(mProgram, fragmentShader);
GLES20.glLinkProgram(mProgram);
maPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GLES20.glUseProgram(mProgram);
MatrixStack.initStack();
}

public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
drawGround();
}

private void drawGround() {
GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 0, triangleVB);
GLES20.glEnableVertexAttribArray(maPositionHandle);
Matrix.multiplyMM(MatrixStack.getMVPMatrix(), 0, MatrixStack.getMVMatrix(), 0, MatrixStack.getMVMatrix(), 0);
Matrix.multiplyMM(MatrixStack.getMVPMatrix(), 0, MatrixStack.getPMatrix(), 0, MatrixStack.getMVPMatrix(), 0);
GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixStack.getMVPMatrix(), 0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
GLES20.glDisableVertexAttribArray(maPositionHandle);
}

public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
Matrix.frustumM(MatrixStack.getPMatrix(), 0, -ratio, ratio, -1, 1, 1, 1000);
muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
Matrix.setLookAtM(MatrixStack.getMVMatrix(), 0, 0, 0,-1, 0, 0, 0, 0, 1, 0);
}

private void initShapes(){
float triangleCoords[] = {
-15f, -2f, 15f,
15f, -2f, 15f,
-15f, -2f, -15f,
15f, -2f, -15f
};
ByteBuffer vbb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
vbb.order(ByteOrder.nativeOrder());
triangleVB = vbb.asFloatBuffer();
triangleVB.put(triangleCoords);
triangleVB.position(0);
}
}

And a small MatrixStack Class but I don't think there will be a problem here:

public class MatrixStack {

private static Stack<float[]> matrixStack = new Stack<float[]>();

private static float[] MVMatrix = new float[16];
private static float[] PMatrix = new float[16];
private static float[] MVPMatrix = new float[16];

protected static void initStack(){
float[] basisMatrix = new float[16];
Matrix.setIdentityM(basisMatrix, 0);
matrixStack.push(basisMatrix);
MVMatrix = basisMatrix;
Matrix.setIdentityM(PMatrix, 0);
}

public static float[] getMVMatrix(){
return MVMatrix;
}

public static float[] getPMatrix(){
return PMatrix;
}

public static float[] getMVPMatrix(){
return MVPMatrix;
}

}

So well, thats all.

Looks like the camera preview is "overexposing" my gl fragment.

Please try this code at least.

I still hope there is just something wrong with my phone.

Thank you anyway for your help,

Tobias