2016-07-13 15 views
0

Ich möchte eine IOSurface Textur mit Mipmapping rendern.IOSurface-backed Textur zu GL_TEXTURE_2D konvertieren

Ich erzeuge eine OpenGL Textur von einem IOSurface etwa so:

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) 

Und es mit einem einfachen Fragment-Shader-Rendering:

#version 120 
uniform sampler2DRect texture; 
varying vec2 texCoord; 
uniform vec2 size; 

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

Dies funktioniert gut. Aber leider ist die Textur nicht mipmapped und ist sehr körnig/pixelig, wenn man sie kleiner betrachtet. Nach weiteren Untersuchungen scheint es, dass nicht nur IOSurface unterstützte Texturen auf ein GL_TEXTURE_RECTANGLE_ARB Ziel beschränkt sind, sie unterstützen auch kein Mipmapping.

Allright. Also hier meine beste Alternative scheint zu sein:

  1. Kopieren Sie die GL_TEXTURE_RECTANGLE_ARB Textur auf eine GL_TEXTURE_2D Textur
  2. generieren Mipmaps für diese neue Textur

Sie beachten Sie, dass ich auf Mac entwickle, was tut nicht unterstützt OpenGL 4.3, so kann ich hier nicht bequem glCopyImageSubData verwenden. Stattdessen mein Ansatz für Schritt 1 auf dieser Antwort, die ich bin zu stützen: How to copy texture1 to texture2 efficiently?

Mein vollständige Code sieht nun wie folgt aus:

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) 

Und änderte ich meine Shader GL_TEXTURE_2D zu unterstützen:

#version 120 
uniform sampler2D texture; 
varying vec2 texCoord; 

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

Und hier stecke ich fest. Das Bild ist ganz schwarz und ich habe keine Ahnung, warum es nicht funktioniert.

Ich habe versucht, Blick auf die Pixeldaten wie folgt:

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) 

Und es ist nur Nullen. Ist es etwas falsch mit meinem Ansatz oder könnte das Problem speziell im Zusammenhang mit IOSurface gesicherten Texturen bezogen werden?

Antwort

0

bekam schließlich diese Arbeit mit dem folgenden:

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); 
}