2014-09-02 243 views
12

我需要一種方法來渲染紋理的GL_TEXTURE_EXTERNAL_OES紋理。我嘗試將紋理綁定到framebuffer,但我得到了GL_INVALID_ENUM錯誤。下面是一些示例代碼:如何渲染到GL_TEXTURE_EXTERNAL_OES?

glEnable(GL_TEXTURE_EXTERNAL_OES); 
glGenFramebuffersOES(1, &frameBuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER, frameBuffer); 
glFramebufferTexture2DOES(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, outTexHandle, 0); // I get GL_INVALID_ENUM here 
// set viewport, uniforms and draw 
glBindFramebufferOES(GL_FRAMEBUFFER, 0); 
glDisable(GL_TEXTURE_EXTERNAL_OES); 

我的最終目標是通過在其上應用一些過濾器來修改使用表面紋理的相機框架。因此,我的着色器程序同時具有輸入和輸出紋理相同的GL_TEXTURE_EXTERNAL_OES紋理。這可能嗎?如果沒有,有沒有解決方法?對於我的應用程序來說,輸出紋理必須是GL_TEXTURE_EXTERNAL_OES,我不能使用GL_TEXTURE_2D紋理。

回答

0

您無法渲染到GL_TEXTURE_EXTERNAL_OES紋理。 GL_TEXTURE_EXTERNAL_OES是其他設備(如設備相機)呈現的外部紋理。您已閱讀了此紋理。如果你需要改變紋理的渲染方式,那麼你需要編寫一個着色器程序來完成。

在訪問OES紋理數據之前,您必須執行多個步驟。外部OES質地必須按以下方式進行初始化:

int[] mTextureHandles = new int[1]; 
GLES20.glGenTextures(1, mTextureHandles, 0); 
mTextureHandle = mTextureHandles[0]; 

GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureHandles[0]); 
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

然後你包裹在SurfaceTexture對象OES質地和設置更新每個幀。你的類必須實現SurfaceTexture.OnFrameAvailableListener接口:

camTexture = new SurfaceTexture(mTextureHandle); 
camTexture.setOnFrameAvailableListener(this); 

當初始化相機,你必須指向它使用GL_TEXTURE_EXTERNAL_OES像這樣:

mCamera = Camera.open(); 
try{ 
    mCamera.setPreviewTexture(camTexture); 
}catch(IOException ioe){ 
    ioe.printStackTrace(); 
} 

現在,在您public void onFrameAvailable(SurfaceTexture surfaceTexture)回調,渲染到的一個GL_TEXTURE對象,像這樣:

GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
camTexture.updateTexImage(); 
renderFrame(); 

在你renderFrame()方法,你需要執行以下操作:

1 - 集視

2 - 綁定到外部質地:glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId);

3 - 設置所有包括轉換矩陣的着色器程序

4的變量 - 最後通過調用來渲染紋理glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

如果您的目標是更改紋理呈現方式,則必須實施GLES着色器程序才能完成此操作。下面是一個簡單的紋理頂點着色器的例子:

uniform mat4 uMVPMatrix; 
attribute vec4 aPosition; 
attribute vec4 aTextureCoord; 
varying vec2 vTextureCoord; 
void main() { 
    gl_Position = uMVPMatrix * aPosition; 
    vTextureCoord = vec2(1.0 - aTextureCoord.s, aTextureCoord.t); 
} 

,這裏是相關的片段着色器:

#extension GL_OES_EGL_image_external : require 
precision mediump float; 
uniform samplerExternalOES sTexture; 
varying vec2 vTextureCoord; 
void main(){ 
    gl_FragColor = texture2D(sTexture, vTextureCoord); 
} 

需要注意的是片段着色器有#extension GL_OES_EGL_image_external : require在着色器文件的頂部。這是非常重要的,它需要允許着色器從GL_TEXTURE_EXTERNAL_OES紋理讀取。您現在可以更改着色器程序,以任何您希望的方式渲染外部紋理數據。