簡體   English   中英

在Android上讀取OpenGL ES的深度緩沖區

[英]Read the depth buffer of OpenGL ES on Android

我正在嘗試在Android上的OpenGL ES中讀取深度緩沖區,但是所有值均為零。 有人可以解釋為什么。

    public void onSurfaceChanged(GL10 unused, int width, int height) {
    // Adjust the viewport based on geometry changes,
    // such as screen rotation
    GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    GLES20.glClearDepthf(1.0f);
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    GLES20.glEnable(GLES20.GL_DEPTH_TEST);
    GLES20.glDepthMask( false );

    GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width / height;

    // this projection matrix is applied to object coordinates
    // in the onDrawFrame() method
    Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 4, 9);
}

讀取深度緩沖區:

        FloatBuffer buffer = FloatBuffer.allocate(720*945);
    GLES20.glReadPixels(0, 0, 720, 945, GLES20.GL_DEPTH_COMPONENT, GLES20.GL_FLOAT, buffer);
    float[] depth = buffer.array();
    for (int i = 0; i < 720*945; i++){
            Log.i("Depth", ""+depth[i]);
    }

該模型已繪制在屏幕上: ScreenShot

編輯

我將項目移至ES 3.0。 我創建一個FrameBuffer,顏色和深度紋理,然后附加。出現錯誤GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

 GLES30.glEnable(GLES30.GL_TEXTURE_2D);

    GLES30.glGenTextures(1, colorTex, 0);
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, colorTex[0]);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA, fboWidth, fboHeight, 0, GLES30.GL_RGBA, GLES30.GL_FLOAT, null);

    GLES30.glGenTextures(1, depthTex, 0);
    GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, depthTex[0]);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_S, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_WRAP_T, GLES30.GL_CLAMP_TO_EDGE);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MAG_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexParameteri(GLES30.GL_TEXTURE_2D, GLES30.GL_TEXTURE_MIN_FILTER, GLES30.GL_NEAREST);
    GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_DEPTH_COMPONENT24, fboWidth, fboHeight, 0, GLES30.GL_DEPTH_COMPONENT, GLES30.GL_FLOAT, null);


    GLES30.glGenFramebuffers(1, fb, 0);
    GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER, fb[0]);

    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_COLOR_ATTACHMENT0, GLES30.GL_TEXTURE_2D, colorTex[0], 0);

    checkStatus("Color Test");

    GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER, GLES30.GL_DEPTH_ATTACHMENT, GLES30.GL_TEXTURE_2D, depthTex[0], 0);

    checkStatus("Depth Test");

}

問題1:如何解決以上錯誤?

Q2:如何檢查深度紋理中的深度值

OpenGL ES在深度緩沖區上不支持glReadPixels() 如果在glReadPixels()調用之后調用glGetError() ,則應該看到返回了GL_INVALID_OPERATION

我僅找到針對此功能的供應商特定擴展: NV_read_depth_stencil 該功能在最新的ES規范(3.2)中仍然不是標准的。

除了此擴展之外,我想不出任何方法來讀取ES 2.0中的深度值。

在ES 3.0和更高版本中,至少存在一種間接方式。 這些版本支持深度紋理。 使用此功能,您可以使用以下步驟獲得深度。

  1. 使用紋理作為深度附件將場景渲染到FBO。
  2. 使用着色器渲染屏幕大小的四邊形,以對上一步中生成的深度紋理進行采樣,並將該值寫入顏色緩沖區。
  3. 在顏色緩沖區上使用glReadPixels()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM