在具有目标 GL_TEXTURE_2D 的纹理上渲染相机预览

Posted

技术标签:

【中文标题】在具有目标 GL_TEXTURE_2D 的纹理上渲染相机预览【英文标题】:Render camera preview on a Texture with target GL_TEXTURE_2D 【发布时间】:2015-05-14 05:36:59 【问题描述】:

我正在尝试在目标为 GL_TEXTURE_2D 的 OpenGL 纹理上渲染相机预览。我非常了解 SurfaceTexture,但我无法使用它,因为它仅适用于 GL_TEXTURE_EXTERNAL_OES。在 SurfaceTexture 的文档中,它是这样写的:

 Each time the texture is bound it must be bound to the GL_TEXTURE_EXTERNAL_OES target rather than the GL_TEXTURE_2D target

我不能使用GL_TEXTURE_EXTERNAL_OES,因为我必须对现有代码进行大量更改。

有没有一种方法也可以快速实现?

【问题讨论】:

【参考方案1】:

我能想到的唯一方法是听SurfaceTexture,当新框架出现时,您只需在GL_TEXTURE_2D 目标上重新绘制它。

当谈到 OpenGL ES 领域时,事情会变得非常复杂。让我尝试以我有限的经验向您解释这一点。下面是一些伪代码。

    如果要将相机数据渲染到屏幕外纹理,则需要屏幕外帧缓冲区。您可能需要的一些功能。

    GLES20.glGenTextures(1, textures, 0);
    GLES20.glGenFramebuffers(1, frames, 0);
    GLES20.glGenRenderbuffers(1, frameRender, 0);
    GLES20.glActiveTexture(ActiveTexture);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
                width, height, 0, GLES20.GL_RGBA,
                GLES20.GL_UNSIGNED_BYTE, directIntBuffer);
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER,
                frameRender[0]);
    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER,
                GLES20.GL_DEPTH_COMPONENT16, width, height);
    GLES20.glViewport(0, 0, width, height);
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frames[0]);
    GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER,
                GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,
                textures[0], 0);
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER,
                GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER,
                frameRender[0]);
    

    编译您的 vertexfragment 着色器并链接您的 program

    准备vertextextureCoordinatesdrawList 缓冲区。

    将你的SurfaceTexture从相机绑定到某个GL_TEXTURE

    GLES20.glActiveTexture(GLES20.GL_TEXTURE1);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, cameraSurfaceTextureHandle);
    

    GLES20.glUseProgram(yourProgram),将以上所有内容链接在一起,GLES20.glDrawElements

【讨论】:

你能给我一些代码吗?我对OpenGL很陌生。只是 OpenGL 函数调用。 如果您查看github.com/google/grafika/blob/master/src/com/android/grafika/…,RECMETHOD_FBO 路径显示渲染到纹理部分。大多数与相机相关的活动都显示了 SurfaceTexture 部分。 顺便说一句,我得到的预览失真了。这是一个小视频 - tosc.in/omerjerk/SCR_20150318_023219.mp4 谁能评论一下这里可能出了什么问题? 这里的directIntBuffer 是什么?它是用像素填充还是以适当的大小为空?还有,初始化是什么,onDrawFrame方法是做什么的? 我可以将它与 grafika 中的这一行联系起来:// 创建纹理存储。 GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, 宽度, 高度, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);

以上是关于在具有目标 GL_TEXTURE_2D 的纹理上渲染相机预览的主要内容,如果未能解决你的问题,请参考以下文章

应该是每个纹理单元应用glEnable(GL_TEXTURE_2D)

为啥纹理(GL_TEXTURE_2D)不能与(VertexArray)VAO一起使用

GL_TEXTURE_3D 是啥意思?

Android Opengl OES 纹理渲染到 GL_TEXTURE_2D

Android Opengl OES 纹理渲染到 GL_TEXTURE_2D

立方体侧面的纹理与opengl