将基于IOSurface的纹理转换为GL_TEXTURE_2D

4

我希望可以使用mipmapping来渲染IOSurface纹理。

我正在从IOSurface生成一个OpenGL纹理,步骤如下:

let error = CGLTexImageIOSurface2D(context.cglContextObj!, 
GLenum(GL_TEXTURE_RECTANGLE_ARB),GLenum(GL_RGBA), GLsizei(width), GLsizei(height),
GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), surface!, 0)

并使用简单的片段着色器进行渲染:
#version 120
uniform sampler2DRect texture;
varying vec2 texCoord;
uniform vec2 size;

void main(){
    vec4 tex = texture2DRect(texture, texCoord*size);
    gl_FragColor = tex;
}

这个功能很好,但不幸的是,当缩小查看时,纹理没有被贴图处理,显得很粗糙/像素化。进一步研究后,发现不仅IOSurface支持的纹理目标只限于GL_TEXTURE_RECTANGLE_ARB,而且也不支持贴图处理。
好吧,我的最佳替代方案似乎是:
  1. GL_TEXTURE_RECTANGLE_ARB纹理复制到GL_TEXTURE_2D纹理中
  2. 为这个新纹理生成贴图处理
请注意,我正在Mac上开发,不支持OpenGL 4.3,因此我不能在这里使用方便的glCopyImageSubData。相反,我基于此答案来完成步骤1:How to copy texture1 to texture2 efficiently? 现在我的完整代码如下:
if !hasCreatedTexture {
    glGenTextures(1, &texture);
    glGenTextures(1, &arbTexture);
    glGenFramebuffers(1, &fbo)
    hasCreatedTexture = true
}
glEnable(GLenum(GL_TEXTURE_RECTANGLE_ARB))
glBindTexture(GLenum(GL_TEXTURE_RECTANGLE_ARB), arbTexture)

let error = CGLTexImageIOSurface2D(context.cglContextObj!, GLenum(GL_TEXTURE_RECTANGLE_ARB), GLenum(GL_RGBA), GLsizei(width), GLsizei(height), GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), surface!, 0)


glBindFramebuffer(GLenum(GL_FRAMEBUFFER), fbo);
glFramebufferTexture2D(GLenum(GL_READ_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0),
                           GLenum(GL_TEXTURE_RECTANGLE_ARB), arbTexture, 0);
glFramebufferTexture2D(GLenum(GL_DRAW_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT1),
                           GLenum(GL_TEXTURE_2D), texture, 0);
glDrawBuffer(GLenum(GL_COLOR_ATTACHMENT1));
glBlitFramebuffer(0, 0, GLint(width), GLint(height), 0, 0, GLint(width), GLint(height), GLbitfield(GL_COLOR_BUFFER_BIT), GLenum(GL_NEAREST));
glBindTexture(GLenum(GL_TEXTURE_2D), texture)

我将我的着色器更改为支持GL_TEXTURE_2D

#version 120
uniform sampler2D texture;
varying vec2 texCoord;

void main(){
    vec4 tex = texture2D(texture, texCoord);
    gl_FragColor = tex;
}

我现在遇到了困难。图片全部是黑色,我不知道为什么它不能正常显示。

我尝试查看像素数据,如下所示:

var pixelData = UnsafeMutablePointer<GLubyte>(allocatingCapacity: Int(width * height * 4))

glGetTexImage(GLenum(GL_TEXTURE_2D), 0, GLenum(GL_BGRA),
GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), pixelData)
print(NSData(bytes: pixelData, length: 50000).description)

这都是零。我的方法有问题吗?还是这个问题特别与处理基于IOSurface的纹理有关?

1个回答

4

最终我使用以下方法解决了这个问题:

func createMipTexture() {
    guard let surface = self.surface else { return }
    glBindTexture(GLenum(GL_TEXTURE_2D), texture);
    glEnable(GLenum(GL_TEXTURE_2D))

    guard let address = IOSurfaceGetBaseAddress(surface) as UnsafeMutableRawPointer? else { return }
    IOSurfaceLock(surface, .readOnly, nil)
    glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0,  GLenum(GL_BGRA), GLenum(GL_UNSIGNED_INT_8_8_8_8_REV), address)
    IOSurfaceUnlock(surface, .readOnly, nil);
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAX_LEVEL), 100)
    glHint(GLenum(GL_GENERATE_MIPMAP_HINT), GLenum(GL_NICEST));
    glGenerateMipmap(GLenum(GL_TEXTURE_2D))
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_REPEAT);
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_REPEAT);
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), GL_LINEAR);
    glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), GL_LINEAR_MIPMAP_LINEAR);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接