2014-09-02 4 views
12

GL_TEXTURE_EXTERNAL_OES 텍스처로 렌더링 할 방법이 필요합니다. 텍스처를 프레임 버퍼에 바인딩하려고했지만 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); 

최종 목표는 일부 필터를 적용하여 SurfaceTexture를 사용하여 카메라 프레임을 수정하는 것입니다. 따라서 쉐이더 프로그램은 입출력이 모두 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 텍스처를 포장하고 각 프레임에 대해 업데이트하도록 설정합니다. 당신의 public void onFrameAvailable(SurfaceTexture surfaceTexture) 콜백에서 지금

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

, 당신이 중 하나에 렌더링 : 카메라를 초기화하는 경우

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

, 당신은 GL_TEXTURE_EXTERNAL_OES 그래서 같이 사용하도록 지정해야합니다 : 귀하의 클래스는 SurfaceTexture.OnFrameAvailableListener 인터페이스를 구현해야합니다 그래서 같은 GL_TEXTURE 제품 : 당신의 renderFrame() 방법에서

GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
camTexture.updateTexImage(); 
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을 가지고

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

참고 다음은 간단한 텍스처 정점 셰이더의 예입니다. 이것은 매우 중요합니다. 셰이더가 GL_TEXTURE_EXTERNAL_OES 텍스처에서 읽을 수 있도록 허용해야합니다. 이제 셰이더 프로그램을 변경하여 원하는 방식으로 외부 텍스처 데이터를 렌더링 할 수 있습니다.