2014-09-02 16 views
12

Ho bisogno di un modo per eseguire il rendering su una trama GL_TEXTURE_EXTERNAL_OES. Ho provato a legare la texture a un framebuffer ma ho ricevuto l'errore GL_INVALID_ENUM. Ecco alcuni esempi di codice:Come eseguire il rendering su 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); 

Il mio obiettivo finale è quello di modificare il telaio fotocamera utilizzando SurfaceTexture applicando alcuni filtri su di esso. Pertanto, il mio programma shader ha sia come input sia come output la stessa texture GL_TEXTURE_EXTERNAL_OES. È possibile? Se no ci sono soluzioni alternative? Per la mia applicazione è essenziale che la trama di output sia GL_TEXTURE_EXTERNAL_OES, non è possibile utilizzare una trama GL_TEXTURE_2D.

risposta

0

Non è possibile eseguire il rendering su una trama GL_TEXTURE_EXTERNAL_OES. GL_TEXTURE_EXTERNAL_OES è la trama esterna a cui vengono sottoposti rendering da altri dispositivi come la fotocamera del dispositivo. Hai accesso in lettura a questa texture. Se è necessario modificare la modalità di rendering della texture, sarà necessario scrivere un programma shader per farlo.

È necessario eseguire una serie di passaggi prima di poter accedere ai dati della trama OES. L'OES struttura esterna deve essere inizializzato nel modo seguente:

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

È quindi avvolgere OES trama in un oggetto SurfaceTexture e si imposta per aggiornare per ogni fotogramma. La classe deve implementare l'interfaccia SurfaceTexture.OnFrameAvailableListener:

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

Quando l'inizializzazione della fotocamera, è necessario puntare per utilizzare il GL_TEXTURE_EXTERNAL_OES in questo modo:

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

Ora nel tuo public void onFrameAvailable(SurfaceTexture surfaceTexture) richiamata, si esegue il rendering di uno dei GL_TEXTURE oggetti in questo modo:

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

nel metodo renderFrame() è necessario effettuare le seguenti operazioni:

1 - Imposta visualizzazione

2 - Bind alla struttura esterna: glBindTexture(GL_TEXTURE_EXTERNAL_OES, texId);

3 - Impostare tutte le variabili del programma Shader compreso matrici di trasformazione

4 - Infine rendere la trama con una chiamata a glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Se il tuo obiettivo è cambiare il modo in cui viene resa la trama, devi implementare un programma di ombreggiatura GLES per farlo. Ecco un esempio di un semplice shader di vertex tessitura:

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

E qui è lo shader frammento associato:

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

Si noti che lo shader frammento ha la #extension GL_OES_EGL_image_external : require nella parte superiore del file shader. Questo è molto importante, è necessario consentire allo shader di leggere dalla trama GL_TEXTURE_EXTERNAL_OES. Ora puoi cambiare il programma shader per rendere i dati della texture esterna come preferisci.

Problemi correlati