gpt4 book ai didi

opengl-es - 如何渲染到 GL_TEXTURE_EXTERNAL_OES?

转载 作者:行者123 更新时间:2023-12-02 21:40:58 24 4
gpt4 key购买 nike

我需要一种渲染GL_TEXTURE_EXTERNAL_OES纹理的方法。我尝试将纹理绑定(bind)到帧缓冲区,但出现 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 接口(interface):

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 - 设置视口(viewport)

2 - 绑定(bind)到外部纹理: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纹理中读取。您现在可以更改着色器程序以按照您希望的方式渲染外部纹理数据。

关于opengl-es - 如何渲染到 GL_TEXTURE_EXTERNAL_OES?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25618977/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com