【问题标题】:Render to texture attached to Frame Buffer Object (texture appears black)渲染到附加到帧缓冲区对象的纹理(纹理显示为黑色)
【发布时间】:2020-09-22 07:28:02
【问题描述】:

我生成了一个帧缓冲对象(FBO),绑定它,将纹理附加到它的GL_COLOR_ATTACHMENT0。然后确保我将其状态设为GL_FRAMEBUFFER_COMPLETE。我有另一个纹理(正在显示),我们称之为workingTexture。现在我想将这个workingTexture 渲染到FBO 上,所以我绑定了这个FBO,然后渲染workingTexture。 然后我绑定默认帧缓冲区(保留用于显示)并尝试渲染附加到 FBO 的纹理,以为我会将我的纹理显示出来,但我得到黑色纹理。

相关代码

生成workingTexture的代码...

int[] workingTexture = new int[1];

glGenTextures(1, workingTexture, 0); // generate workingTexture
glActiveTexture(GL_TEXTURE0);  // attach it to TEXTURE_UNIT0
glBindTexture(GL_TEXTURE_2D, workingTexture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

生成 fbo 的代码

int[] fboName = new int[1];
int[] fboTextureName = new int[1];
final int fboTextureUnit = 1;  // attach this texture to texture unit GL_TEXTURE1
glGenFramebuffers(1, fboName, 0);

int generatedTextureNameForFBO =
                generateTextureForFBO(fboTextureUnit,
                        width, height);
fboTextureName[0] = generatedTextureNameForFBO;

glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                GL_TEXTURE_2D, generatedTextureNameForFBO, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
            // created FBO is not complete
            throw new RuntimeException("FBO status INCOMPLETE ????????");

        }

用于生成附加到 fbo 的纹理的方法

 private int generateTextureForFBO(@IntRange(from = 0) final int textureUnit,
                                  @IntRange(from = 1) final int width,
                                  @IntRange(from = 1) final int height) {
    int[] textureName = new int[1];
    glGenTextures(1, textureName, 0);
    glActiveTexture(GL_TEXTURE0 + textureUnit);
    glBindTexture(GL_TEXTURE_2D, textureName[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
  //        glBindTexture(GL_TEXTURE_2D, 0);
  //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
  //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
  //        glBindTexture(GL_TEXTURE_2D, 0);
    return textureName[0];
}

现在进入绘图部分...

@Override
public void onDrawFrame(GL10 unused) {
    glClear(GL_COLOR_BUFFER_BIT);
    //renderTex(mViewMatrix, 0, texProgram);  // this texture is drawing on screen

    glBindFramebuffer(GL_FRAMEBUFFER, fboName[0]);
    renderTex(mViewMatrix, 0, texProgram);   // rendering workingTexture onto FBO

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    renderTex(mViewMatrix, fboTextureUnit[0], texProgram);  // texture appears black

}

renderTex 是一种渲染纹理的简单方法。它工作正常。

我也检查了GL_ERROR,但没有错误。

我对应用程序创建的 FBO 的理解是每次读取和写入 glCall 都会发生在当前绑定的 FBO 上,所以我对 FBO 的理解不正确,或者我的代码中有错误。

Android 平台 OpenGL|es 20

【问题讨论】:

    标签: android opengl-es textures opengl-es-2.0


    【解决方案1】:

    generateTextureForFBO 中生成的纹理是 mipmap 不完整的。

    如果您不生成mipmaps(由glGenerateMipmap),那么设置GL_TEXTURE_MIN_FILTER 很重要。由于默认过滤器为GL_NEAREST_MIPMAP_LINEAR,因此如果不将缩小功能更改为GL_NEARESTGL_LINEAR,纹理将是mipmap 不完整的。

    通过glTexParameter设置纹理缩小功能(GL_TEXTURE_MIN_FILTER):

    glBindTexture(GL_TEXTURE_2D, textureName[0]);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2014-07-08
      • 1970-01-01
      • 2011-05-14
      • 2016-09-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多