Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

iphone - Render contents of UIView as an OpenGL texture

Is there a way to render the contents of a UIView as a texture with OpenGL in iOS? Or the contents of a CGLayer?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use the view's layer property to get the CALayer and use renderInContext: on that to draw into a CoreGraphics context. You can set up a CoreGraphics context with memory you allocate yourself in order to receive a pixel buffer. You can then upload that to OpenGL by the normal method.

So: there's a means to get the pixel contents of a UIView and OpenGL will accept pixel buffers. There's no specific link between the two.

Coding extemporaneously, the process would be something like:

UIView *view = ... something ...;

// make space for an RGBA image of the view
GLubyte *pixelBuffer = (GLubyte *)malloc(
                               4 * 
                               view.bounds.size.width * 
                               view.bounds.size.height);

// create a suitable CoreGraphics context
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context =
    CGBitmapContextCreate(pixelBuffer, 
                          view.bounds.size.width, view.bounds.size.height, 
                          8, 4*view.bounds.size.width, 
                          colourSpace, 
                          kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colourSpace);

// draw the view to the buffer
[view.layer renderInContext:context];

// upload to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, 
             GL_RGBA,
             view.bounds.size.width, view.bounds.size.height, 0,
             GL_RGBA, GL_UNSIGNED_BYTE, pixelBuffer);

// clean up
CGContextRelease(context);
free(pixelBuffer);

That doesn't deal with issues surrounding non-power-of-two sized views on hardware without the non-power-of-two texture extension and assumes a suitable GL texture name has already been generated and bound. Check for yourself, but I think non-power-of-two is supported on SGX hardware (ie, iPhone 3GS onwards, the iPad and all but the 8gb third generation iPod Touch onwards) but not on MBX.

The easiest way to deal with non-power-of-two textures here is probably to create a large enough power of two texture and to use glTexSubImage2D to upload just the portion from your source UIView.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...