Convert IOSurface-backed texture to GL_TEXTURE_2D

StackOverflow-question with bounty: http://stackoverflow.com/questions/38361376/convert-iosurface-backed-texture-to-gl-texture-2d


I want to render an IOSurface texture with mipmapping.

I am generating an OpenGL texture from an

IOSurface
like 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)


And rendering it with a simple fragment shader:


#version 120 uniform sampler2DRect texture;
varying vec2 texCoord; 
uniform vec2 size;
void main(){ 
     vec4 tex = texture2DRect(texture, texCoord*size);
     gl_FragColor = tex;
}


This works fine. But unfortunately, the texture is not mipmapped and is very grainy/pixellated when viewed at a smaller size. Upon further research, it appears that not only are

IOSurface
backed textures limited to a
GL_TEXTURE_RECTANGLE_ARB
target, they also do not support mipmapping.


Allright. So my best alternative here seems to be to:


  1. Copy the
    GL_TEXTURE_RECTANGLE_ARB
    texture to a
    GL_TEXTURE_2D
    texture
  2. Generate mipmaps for this new texture


I am developing on Mac, which does not support OpenGL 4.3, so I cannot use the convenient

glCopyImageSubData
here. Instead I am basing my approach for Step 1 here on this answer: http://stackoverflow.com/questions/16100308/how-to-copy-texture1-to-texture2-efficiently


My full code now looks like this:


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)


And I changed my shader to support

GL_TEXTURE_2D
:


#version 120 
uniform sampler2D texture;
varying vec2 texCoord;
     void main(){
     vec4 tex = texture2D(texture, texCoord);
     gl_FragColor = tex;
}


And here is where I'm stuck. The image is all black and I have no clue why it's not working.

I tried looking at the pixel data like so:


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)


And it's all zeroes. Is it something wrong with my approach or could the issue be specifically related to dealing with IOSurface backed textures?

Convert IOSurface-backed texture to GL_TEXTURE_2D
 
 
Q