Render contents of UIView as an OpenGL texture

后端 未结 2 1440
既然无缘
既然无缘 2020-12-07 23:27

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

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-08 00:23

    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.

提交回复
热议问题