2014-04-23 169 views
6

我想從OpenGL紋理讀取與GL_TEXTURE_EXTERNAL_OES綁定的像素/數據。Android從GL_TEXTURE_EXTERNAL_OES讀取像素

將紋理綁定到該目標的原因是,爲了在android上獲取實時攝像頭feed,需要使用綁定到GL_TEXTURE_EXTERNAL_OES的OpenGL紋理創建SurfaceTexture。

由於android使用OpenGL ES,因此我無法使用glGetTexImage()來讀取圖像數據。

因此,我將目標綁定到FBO,然後使用readPixels()讀取它。這是我的代碼:

GLuint framebuffer; 
    glGenFramebuffers(1, &framebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 

    //Attach 2D texture to this FBO 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, cameraTexture, 0); 
    status("glFramebufferTexture2D() returned error %d", glGetError()); 

但是由於某些原因我得到錯誤1282(GL_INVALID_OPERATION)。

回答

0

GL_TEXTURE_EXTERNAL_OES紋理目標通常位於YUV色彩空間中,glReadPixels()要求目標爲RGB。它可能不會自動執行色彩空間轉換。但是,您可以在自己的片段着色器中進行轉換,該着色器將RGB渲染爲其他紋理,然後使用glReadPixels()讀取該紋理。

texture for YUV420 to RGB conversion in OpenGL ES

+0

這是不準確的。在Android上,YUV-> RGB轉換在幕後自動進行。請參閱https://stackoverflow.com/questions/46244179/android-mediacodec-output-format-gles-external-texture-yuv-nv12-to-gles-tex – tmm1

2

我覺得這可能是問題:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_EXTERNAL_OES, cameraTexture, 0); 

您應該cameraTexture不能連接到幀緩衝區,而應該產生GL_TEXTURE_2D

glGenTextures(1, mTextureHandle, 0); 

glBindTexture(GL_TEXTURE_2D, mTextureHandle[0]); 

... 
的格式一個新的紋理

cameraTexture是您從SurfaceTexture獲得的一個,它是用於渲染的源。這個新紋理是您應該渲染的紋理(可以在渲染管線中稍後使用)。那麼做到這一點:

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
GL_TEXTURE_2D, mTextureHandle[0], 0); 

cameraTexture被吸引到幀緩存的連接結構,使用一個簡單的着色器程序繪製,結合cameraTexture當着色器程序中使用:

glBindTexture(GL_TEXTURE_EXTERNAL_OES, cameraTexture); 
+1

這個答案帶來了什麼解決方案? –

+0

我認爲正確的解決方案需要將2個答案結合在一起,首先創建一個新的幀緩衝區和一個新的紋理以及glFramebufferTexture2D,然後您可以使用着色器將YUV數據繪製到幀緩衝區,然後通過glReadPixels讀取它。有點複雜! –