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:
- Copy the
texture to aGL_TEXTURE_RECTANGLE_ARB
textureGL_TEXTURE_2D
- 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-efficientlyMy 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?