Swift:使用 OpenGL (glReadPixels) 创建一个 UIImage
Swift: Create an UIImage with OpenGL (glReadPixels)
我正在根据 this tutorial 学习 OpenGL,并尝试编写绘制彩色矩形的简单函数。
输入参数:
size: CGSize,
scale: CGFloat,
这部分代码工作正常:
// Setup context
let api = EAGLRenderingAPI.OpenGLES3
let context = EAGLContext(API: api)
EAGLContext.setCurrentContext(context)
// Setup render buffer
var renderBuffer = GLuint()
glGenRenderbuffers(1, &renderBuffer)
glBindRenderbuffer(GLenum(GL_RENDERBUFFER), renderBuffer)
let bufferWidth = GLsizei(size.width * scale)
let bufferHeight = GLsizei(size.height * scale)
let bufferFormat = GLenum(GL_RGBA8)
glRenderbufferStorage(GLenum(GL_RENDERBUFFER), bufferFormat, bufferWidth, bufferHeight)
// Setup frame buffer
var frameBuffer = GLuint()
glGenFramebuffers(1, &frameBuffer)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer)
glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_RENDERBUFFER), renderBuffer)
// Draw
glClearColor(1, 0.5, 0.5, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
问题最多的部分是创建 UIImage:
// Get bytes
let byteLength = Int(bufferWidth * bufferHeight) * 4;
let bytes = malloc(byteLength)
glReadPixels(0, 0, bufferWidth, bufferHeight, bufferFormat, GLenum(GL_UNSIGNED_BYTE), bytes)
print( glGetError() ) // prints 1280 (GL_INVALID_ENUM) !!!
// Create a CGImage
let dataProvider = CGDataProviderCreateWithData(nil, bytes, byteLength, nil)
let colorspace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo: CGBitmapInfo = [.ByteOrder32Little, CGBitmapInfo(rawValue: CGImageAlphaInfo.Last.rawValue)]
let aCGImage = CGImageCreate(
Int(bufferWidth),
Int(bufferHeight),
8,
4,
4 * Int(bufferWidth),
colorspace,
bitmapInfo,
dataProvider,
nil,
false,
.RenderingIntentDefault
)!
let anUIImage = UIImage(CGImage: aCGImage, scale: scale, orientation: .Up)
虽然 glReadPixels
生成 GL_INVALID_ENUM 错误,但我什至不确定我创建 UIImage 的方法是否正确。
OpenGL ES 接受的格式非常有限。有一个包含 OpenGL 文档的优秀网站 http://docs.gl
您对 http://docs.gl/es2/glReadPixels or http://docs.gl/es3/glReadPixels 感兴趣。缓冲区格式应为 GL_RGBA
或 GL_BGRA
.
也许更好的方法是 。
我正在根据 this tutorial 学习 OpenGL,并尝试编写绘制彩色矩形的简单函数。
输入参数:
size: CGSize,
scale: CGFloat,
这部分代码工作正常:
// Setup context
let api = EAGLRenderingAPI.OpenGLES3
let context = EAGLContext(API: api)
EAGLContext.setCurrentContext(context)
// Setup render buffer
var renderBuffer = GLuint()
glGenRenderbuffers(1, &renderBuffer)
glBindRenderbuffer(GLenum(GL_RENDERBUFFER), renderBuffer)
let bufferWidth = GLsizei(size.width * scale)
let bufferHeight = GLsizei(size.height * scale)
let bufferFormat = GLenum(GL_RGBA8)
glRenderbufferStorage(GLenum(GL_RENDERBUFFER), bufferFormat, bufferWidth, bufferHeight)
// Setup frame buffer
var frameBuffer = GLuint()
glGenFramebuffers(1, &frameBuffer)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), frameBuffer)
glFramebufferRenderbuffer(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_RENDERBUFFER), renderBuffer)
// Draw
glClearColor(1, 0.5, 0.5, 1)
glClear(GLbitfield(GL_COLOR_BUFFER_BIT))
问题最多的部分是创建 UIImage:
// Get bytes
let byteLength = Int(bufferWidth * bufferHeight) * 4;
let bytes = malloc(byteLength)
glReadPixels(0, 0, bufferWidth, bufferHeight, bufferFormat, GLenum(GL_UNSIGNED_BYTE), bytes)
print( glGetError() ) // prints 1280 (GL_INVALID_ENUM) !!!
// Create a CGImage
let dataProvider = CGDataProviderCreateWithData(nil, bytes, byteLength, nil)
let colorspace = CGColorSpaceCreateDeviceRGB()
let bitmapInfo: CGBitmapInfo = [.ByteOrder32Little, CGBitmapInfo(rawValue: CGImageAlphaInfo.Last.rawValue)]
let aCGImage = CGImageCreate(
Int(bufferWidth),
Int(bufferHeight),
8,
4,
4 * Int(bufferWidth),
colorspace,
bitmapInfo,
dataProvider,
nil,
false,
.RenderingIntentDefault
)!
let anUIImage = UIImage(CGImage: aCGImage, scale: scale, orientation: .Up)
虽然 glReadPixels
生成 GL_INVALID_ENUM 错误,但我什至不确定我创建 UIImage 的方法是否正确。
OpenGL ES 接受的格式非常有限。有一个包含 OpenGL 文档的优秀网站 http://docs.gl
您对 http://docs.gl/es2/glReadPixels or http://docs.gl/es3/glReadPixels 感兴趣。缓冲区格式应为 GL_RGBA
或 GL_BGRA
.
也许更好的方法是 。