0

好吧,这是我的OpenGL问题,我真的无法修复。一切工作正常的Galaxy S1和S2似乎有几乎相同的GPU。 但是,当我尝试制作AR-App时,我总是会在我的相机预览顶部出现透明像素问题。它只在像素透明且看起来像“烧焦的颜色”或值溢出或类似的东西时出现。所以请告诉我我做错了什么,或者如果你有S3,请尝试一下。也许我的只是坏了? 我为你创建了一个小型测试程序。请看看这个:OpenGL和相机预览 - 预乘alpha - 混合在一起会得到“过饱和”的颜色

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(); 
    } 
} 

的CameraView看起来像这样:

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; 
    } 
} 

的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);    
    }  
} 

和一个小MatrixStack类,但我不认为会有成为一个问题在这里:

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; 
    } 

} 

这么好,那就是所有。看起来像相机预览是“过度曝光”我的gl片段。 请至少尝试此代码。我仍然希望我的手机出现问题。 谢谢你的帮助, Tobias

+0

你可以尝试发布一个干净,容易理解的问题形象?我看到了您在第一篇文章中发布的图片,但这非常繁忙,很难分辨发生了什么。也许就像一个展示这种“过度曝光”的简单渐变?请显示您正在混合的两幅源图像。 – Tim 2012-08-07 22:02:36

回答

2

好的,我得到了一个答案。 问题在于alpha值的预乘。 所以最简单的方法就足以写:

vec3 color = clamp(textureColor.rgb * lightWeighting.xyz, 0.0, 1.0); 
color *= 0.5; // premultiply by alpha 
gl_FragColor = vec4(color, 0.5); 

即使我不明白为什么它的工作在旧系统完全正常而且我仍然不知道如何在Gl1.0管理这个我无法编写自己的着色器代码。 所以希望这有助于任何有同样问题的人! 谢谢, 托比亚斯

+0

遇到同样的问题后,我不觉得你有什么是真正的解决方案。 您所做的只是通过削弱您尝试融入相机预览的颜色来减少“溢出”的情况。 例如,如果您有一个案例,例如某个像素的相机预览是(1.0,1.0,1.0),并且您想在其上混合某些东西,那么您仍然会遇到溢出问题。 我想知道这是什么真正的解决方案... – ZeDuS 2013-08-19 18:22:24

+0

转到http://www.khronos.org/opengles/sdk/docs/man/ 并选择: glBlendEquation。 看起来像三星的Galaxy S3根本没有: “这些方程的结果被限制在[0,1]范围内” – ZeDuS 2013-08-19 18:59:30