geo*_*444 15 opengl-es render-to-texture
我需要一种渲染到GL_TEXTURE_EXTERNAL_OES纹理的方法.我尝试将纹理绑定到帧缓冲区但我得到了GL_INVALID_ENUM错误.以下是一些示例代码:
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纹理.
您无法渲染到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);
然后将 OES 纹理包裹在一个SurfaceTexture对象中,并将其设置为针对每一帧进行更新。你的类必须实现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纹理中读取。您现在可以更改着色器程序以按您希望的任何方式渲染外部纹理数据。
| 归档时间: | 
 | 
| 查看次数: | 2449 次 | 
| 最近记录: |