OpenGL和相机preVIEW - premultipliedα - 混合聚在一起“过饱和”色 [英] OpenGL and Camera Preview - premultiplied alpha - blending together gets “over saturated” color

查看:403
本文介绍了OpenGL和相机preVIEW - premultipliedα - 混合聚在一起“过饱和”色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,这里是我的OpenGL问题我实在无法修复。一切工作正常在Galaxy S1和里面好像有差不多了GPU的S2。
但是,当我试图使AR-应用我总是一个问题,在我的相机preVIEW的顶部透明像素。它只有当像素是透明的出现,看起来像烧色或价值溢出或者类似的东西。所以,请告诉我,我做错了,或尝试,如果你有一个S3。也许我的是刚刚打破?
我创建了一个小testprogram你。请看看这个:

Okay here is my OpenGL Problem I really can't fix. Everything works fine on the Galaxy S1 and on an S2 which seems to have almost the same GPU. But when I try to make an AR-App 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();
    }
}

该CameraView看起来像:

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

该GameRenderer:

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

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

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

}

这么好,多数民众赞成。貌似相机preVIEW被过度曝光我的GL片段。
请至少尝试这个code。我还是希望有刚有毛病我的手机。
谢谢你的好意的帮助,
 托比亚斯

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

推荐答案

好吧,我得到了一个答案。
问题是Alpha值的premultiplication。
因此,在最简单的方法是足够的写:

Alright, I got an answer for that. The problem was the premultiplication for the alpha values. So in the easiest way it is enough to write:

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在那里,我不能写我自己的着色器code进行管理。
因此,希望这有助于任何人谁具有同样的问题!
谢谢,
 托比亚斯

Even though I don't see why it worked perfectly fine on older systems and it I'm still not sure how to manage this on Gl1.0 where I can't write my own shader code. So hope this helps to anyone who has the same problem! Thanks, Tobias

这篇关于OpenGL和相机preVIEW - premultipliedα - 混合聚在一起“过饱和”色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆