【问题标题】:How to get rid of artefacts when converting `CVImageBufferRef` to OpenGL ES texture with `glTexImage2D`?使用 `glTexImage2D` 将 `CVImageBufferRef` 转换为 OpenGL ES 纹理时如何消除伪影?
【发布时间】:2017-03-19 05:53:59
【问题描述】:

我尝试从CVImageBufferRef加载纹理:

func createTextureFromCVImageBufferRef(buffer: CVImageBufferRef) {
    let bufferHeight = CVPixelBufferGetHeight(buffer)
    let bufferWidth  = CVPixelBufferGetWidth(buffer)
    let bytesPerRow  = CVPixelBufferGetBytesPerRow(buffer)

    let w = bytesPerRow / 4 //  I option
    //let w = bufferWidth   //  II option
    let h = bufferHeight

    CVPixelBufferLockBaseAddress(buffer, CVPixelBufferLockFlags(rawValue: CVOptionFlags(0)))

    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR)
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR)
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE)
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE)

    glTexImage2D(GLenum(GL_TEXTURE_2D), GLint(0), GLint(GL_RGBA), GLsizei(w), GLsizei(h), GLint(0), GLenum(GL_BGRA), GLenum(GL_UNSIGNED_BYTE), CVPixelBufferGetBaseAddress(buffer))
}

有两种不同的方式:

1)let w = bytesPerRow / 4

2)let w = bufferWidth

这两个选项在 iPhone 5s 上都能完美运行,但据我所知,由于 CVImageBufferRef 数据对齐,我在 iPhone 6 上出现了瑕疵。在 iPhone 6 上,bytesPerRow / 4 等于 752,但 bufferWidth 等于 750。在这两种情况下,我都有以下工件:

在第一种情况下: 图像右侧有一条 2 像素线。 (它是纹理的一部分,而不仅仅是黑色背景视图)

在第二种情况下: 纹理正在发生一些地狱。

【问题讨论】:

    标签: iphone swift opengl-es textures opengl-es-2.0


    【解决方案1】:

    正如您所发现的,您需要处理行填充,但要以 GL 完全忽略它的方式处理它。您当前的两种方法都将其视为实际纹理数据,这就是它不起作用的原因。

    您可以使用UNPACK_ROW_LENGTH 跳过整个像素,使用UNPACK_ALIGNMENT 处理散乱字节填充(在纹理上传之前通过glPixelStorei 设置)。

    我认为在您的情况下,您希望将 UNPACK_ROW_LENGTH 设置为 752,并将您的 glTexImage2D 宽度参数设置为 750。

    【讨论】:

      猜你喜欢
      • 2012-02-19
      • 2022-01-21
      • 2016-11-02
      • 2020-11-06
      • 1970-01-01
      • 2012-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多