国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

GPUImageAPI文檔之GPUImageFramebuffer類

2019-11-14 17:55:55
字體:
來源:轉載
供稿:網友

  GPUImageFramebuffer類用于管理幀緩沖對象,負責幀緩沖對象的創建和銷毀,讀取幀緩沖內容

  屬性

  @PRoperty(readonly) CGSize size

  說明:只讀屬性,在實現中,設置緩沖區的size

 

  @property(readonly) GPUTextureOptions textureOptions

  說明:紋理的選項

 

  @property(readonly) GLuint texture

  說明:管理紋理

 

  @property(readonly) BOOL missingFramebuffer

  說明:指示是否丟失幀緩沖對象

  

  方法

   - (id)initWithSize:(CGSize)framebufferSize

    說明:創建一個size為framebufferSize大小的幀緩沖對象

    參數:framebuffer的size。

    返回:創建成功的幀緩沖對象。

    實現

- (id)initWithSize:(CGSize)framebufferSize;{    GPUTextureOptions defaultTextureOptions;    defaultTextureOptions.minFilter = GL_LINEAR;    defaultTextureOptions.magFilter = GL_LINEAR;    defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;    defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;    defaultTextureOptions.internalFormat = GL_RGBA;    defaultTextureOptions.format = GL_BGRA;    defaultTextureOptions.type = GL_UNSIGNED_BYTE;    if (!(self = [self initWithSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:NO]))    {        return nil;    }    return self;}

 

     - (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fboTextureOptions onlyTexture:(BOOL)onlyGenerateTexture

    說明:創建一個size為framebufferSize大小的幀緩沖對象

    參數:framebufferSize為framebuffer的size。fboTextureOptions是紋理的詳細配置。onlyGenerateTexture說明是否只創建紋理而不創建陳幀緩沖對象。

    返回:創建成功的幀緩沖對象。

    實現

- (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fboTextureOptions onlyTexture:(BOOL)onlyGenerateTexture;{    if (!(self = [super init]))    {        return nil;    }        _textureOptions = fboTextureOptions;    _size = framebufferSize;    framebufferReferenceCount = 0;    referenceCountingDisabled = NO;    _missingFramebuffer = onlyGenerateTexture;    if (_missingFramebuffer)    {        runSynchronouslyOnVideoProcessingQueue(^{            [GPUImageContext useImageProcessingContext];            [self generateTexture];            framebuffer = 0;        });    }    else    {        [self generateFramebuffer];    }    return self;}

 

   - (id)initWithSize:(CGSize)framebufferSize overriddenTexture:(GLuint)inputTexture

    說明:創建一個size為framebufferSize大小的幀緩沖對象

    參數:inputTexture為輸入的紋理,用于渲染圖片。

    返回:創建成功的幀緩沖對象。

    實現

- (id)initWithSize:(CGSize)framebufferSize overriddenTexture:(GLuint)inputTexture;{    if (!(self = [super init]))    {        return nil;    }    GPUTextureOptions defaultTextureOptions;    defaultTextureOptions.minFilter = GL_LINEAR;    defaultTextureOptions.magFilter = GL_LINEAR;    defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;    defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;    defaultTextureOptions.internalFormat = GL_RGBA;    defaultTextureOptions.format = GL_BGRA;    defaultTextureOptions.type = GL_UNSIGNED_BYTE;    _textureOptions = defaultTextureOptions;    _size = framebufferSize;    framebufferReferenceCount = 0;    referenceCountingDisabled = YES;        _texture = inputTexture;        return self;}

 

   - (void)activateFramebuffer

    說明:激活剛創建的framebuffer對象。只有調用它后,才會起作用。

    實現 

- (void)activateFramebuffer;{    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);    glViewport(0, 0, (int)_size.width, (int)_size.height);}

 

   - (void)lock

    說明:引用計數管理 +1

    實現

- (void)lock;{    if (referenceCountingDisabled)    {        return;    }        framebufferReferenceCount++;}

 

   - (void)unlock

    說明:引用計數管理 -1

    實現

- (void)unlock;{    if (referenceCountingDisabled)    {        return;    }    NSAssert(framebufferReferenceCount > 0, @"Tried to overrelease a framebuffer, did you forget to call -useNextFrameForImageCapture before using -imageFromCurrentFramebuffer?");    framebufferReferenceCount--;    if (framebufferReferenceCount < 1)    {        [[GPUImageContext sharedFramebufferCache] returnFramebufferToCache:self];    }}

 

   - (void)clearAllLocks

    說明:引用計數管理 設置為0

    實現

- (void)clearAllLocks;{    framebufferReferenceCount = 0;}

 

   - (void)disableReferenceCounting

    說明:引用計數管理 禁用引用計數

    實現

- (void)disableReferenceCounting;{    referenceCountingDisabled = YES;}

 

   - (void)enableReferenceCounting

    說明:引用計數管理 啟用引用計數

    實現

- (void)enableReferenceCounting;{    referenceCountingDisabled = NO;}

 

   - (CGImageRef)newCGImageFromFramebufferContents

    說明:輸出幀緩沖內容。【說明待更新......】

    實現

- (CGImageRef)newCGImageFromFramebufferContents;{    // a CGImage can only be created from a 'normal' color texture    NSAssert(self.textureOptions.internalFormat == GL_RGBA, @"For conversion to a CGImage the output texture format for this filter must be GL_RGBA.");    NSAssert(self.textureOptions.type == GL_UNSIGNED_BYTE, @"For conversion to a CGImage the type of the output texture of this filter must be GL_UNSIGNED_BYTE.");        __block CGImageRef cgImageFromBytes;        runSynchronouslyOnVideoProcessingQueue(^{        [GPUImageContext useImageProcessingContext];                NSUInteger totalBytesForImage = (int)_size.width * (int)_size.height * 4;        // It appears that the width of a texture must be padded out to be a multiple of 8 (32 bytes) if reading from it using a texture cache                GLubyte *rawImagePixels;                CGDataProviderRef dataProvider = NULL;        if ([GPUImageContext supportsFastTextureUpload])        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(renderTarget) / 4.0;            NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)_size.height * 4;                        glFinish();            CFRetain(renderTarget); // I need to retain the pixel buffer here and release in the data source callback to prevent its bytes from being prematurely deallocated during a photo write Operation            [self lockForReading];            rawImagePixels = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);            dataProvider = CGDataProviderCreateWithData((__bridge_retained void*)self, rawImagePixels, paddedBytesForImage, dataProviderUnlockCallback);            [[GPUImageContext sharedFramebufferCache] addFramebufferToActiveImageCaptureList:self]; // In case the framebuffer is swapped out on the filter, need to have a strong reference to it somewhere for it to hang on while the image is in existence#else#endif        }        else        {            [self activateFramebuffer];            rawImagePixels = (GLubyte *)malloc(totalBytesForImage);            glReadPixels(0, 0, (int)_size.width, (int)_size.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels);            dataProvider = CGDataProviderCreateWithData(NULL, rawImagePixels, totalBytesForImage, dataProviderReleaseCallback);            [self unlock]; // Don't need to keep this around anymore        }                CGColorSpaceRef defaultRGBColorSpace = CGColorSpaceCreateDeviceRGB();                if ([GPUImageContext supportsFastTextureUpload])        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, CVPixelBufferGetBytesPerRow(renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault);#else#endif        }        else        {            cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, 4 * (int)_size.width, defaultRGBColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, dataProvider, NULL, NO, kCGRenderingIntentDefault);        }                // Capture image with current device orientation        CGDataProviderRelease(dataProvider);        CGColorSpaceRelease(defaultRGBColorSpace);            });        return cgImageFromBytes;}

 

   - (void)restoreRenderTarget

    說明:還原渲染目標對象

    實現

- (void)restoreRenderTarget;{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    [self unlockAfterReading];    CFRelease(renderTarget);#else#endif}

 

   - (void)lockForReading

    說明:鎖定PixelBuffer

    實現:

- (void)lockForReading{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    if ([GPUImageContext supportsFastTextureUpload])    {        if (readLockCount == 0)        {            CVPixelBufferLockBaseAddress(renderTarget, 0);        }        readLockCount++;    }#endif}

 

 

   - (void)unlockAfterReading

    說明:解鎖PixelBuffer

- (void)unlockAfterReading{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    if ([GPUImageContext supportsFastTextureUpload])    {        NSAssert(readLockCount > 0, @"Unbalanced call to -[GPUImageFramebuffer unlockAfterReading]");        readLockCount--;        if (readLockCount == 0)        {            CVPixelBufferUnlockBaseAddress(renderTarget, 0);        }    }#endif}

 

   - (NSUInteger)bytesPerRow

    說明:獲取pixel buffer的行字節數

    實現

- (NSUInteger)bytesPerRow;{    if ([GPUImageContext supportsFastTextureUpload])    {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE        return CVPixelBufferGetBytesPerRow(renderTarget);#else        return _size.width * 4; // TODO: do more with this on the non-texture-cache side#endif    }    else    {        return _size.width * 4;    }}

 

   - (GLubyte *)byteBuffer

    說明:獲取pixel buffer的基地址

    實現

- (GLubyte *)byteBuffer;{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    [self lockForReading];    GLubyte * bufferBytes = CVPixelBufferGetBaseAddress(renderTarget);    [self unlockAfterReading];    return bufferBytes;#else    return NULL; // TODO: do more with this on the non-texture-cache side#endif}

 

完整代碼

#import <Foundation/Foundation.h>#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE#import <OpenGLES/EAGL.h>#import <OpenGLES/ES2/gl.h>#import <OpenGLES/ES2/glext.h>#else#import <OpenGL/OpenGL.h>#import <OpenGL/gl.h>#endif#import <QuartzCore/QuartzCore.h>#import <CoreMedia/CoreMedia.h>typedef struct GPUTextureOptions {    GLenum minFilter;    GLenum magFilter;    GLenum wrapS;    GLenum wrapT;    GLenum internalFormat;    GLenum format;    GLenum type;} GPUTextureOptions;@interface GPUImageFramebuffer : NSObject@property(readonly) CGSize size;@property(readonly) GPUTextureOptions textureOptions;@property(readonly) GLuint texture;@property(readonly) BOOL missingFramebuffer;// Initialization and teardown- (id)initWithSize:(CGSize)framebufferSize;- (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fboTextureOptions onlyTexture:(BOOL)onlyGenerateTexture;- (id)initWithSize:(CGSize)framebufferSize overriddenTexture:(GLuint)inputTexture;// Usage- (void)activateFramebuffer;// Reference counting- (void)lock;- (void)unlock;- (void)clearAllLocks;- (void)disableReferenceCounting;- (void)enableReferenceCounting;// Image capture- (CGImageRef)newCGImageFromFramebufferContents;- (void)restoreRenderTarget;// Raw data bytes- (void)lockForReading;- (void)unlockAfterReading;- (NSUInteger)bytesPerRow;- (GLubyte *)byteBuffer;@end
View Code

 

 

#import "GPUImageFramebuffer.h"#import "GPUImageOutput.h"@interface GPUImageFramebuffer(){    GLuint framebuffer;#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    CVPixelBufferRef renderTarget;    CVOpenGLESTextureRef renderTexture;    NSUInteger readLockCount;#else#endif    NSUInteger framebufferReferenceCount;    BOOL referenceCountingDisabled;}- (void)generateFramebuffer;- (void)generateTexture;- (void)destroyFramebuffer;@endvoid dataProviderReleaseCallback (void *info, const void *data, size_t size);void dataProviderUnlockCallback (void *info, const void *data, size_t size);@implementation GPUImageFramebuffer@synthesize size = _size;@synthesize textureOptions = _textureOptions;@synthesize texture = _texture;@synthesize missingFramebuffer = _missingFramebuffer;#pragma mark -#pragma mark Initialization and teardown- (id)initWithSize:(CGSize)framebufferSize textureOptions:(GPUTextureOptions)fboTextureOptions onlyTexture:(BOOL)onlyGenerateTexture;{    if (!(self = [super init]))    {        return nil;    }        _textureOptions = fboTextureOptions;    _size = framebufferSize;    framebufferReferenceCount = 0;    referenceCountingDisabled = NO;    _missingFramebuffer = onlyGenerateTexture;    if (_missingFramebuffer)    {        runSynchronouslyOnVideoProcessingQueue(^{            [GPUImageContext useImageProcessingContext];            [self generateTexture];            framebuffer = 0;        });    }    else    {        [self generateFramebuffer];    }    return self;}- (id)initWithSize:(CGSize)framebufferSize overriddenTexture:(GLuint)inputTexture;{    if (!(self = [super init]))    {        return nil;    }    GPUTextureOptions defaultTextureOptions;    defaultTextureOptions.minFilter = GL_LINEAR;    defaultTextureOptions.magFilter = GL_LINEAR;    defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;    defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;    defaultTextureOptions.internalFormat = GL_RGBA;    defaultTextureOptions.format = GL_BGRA;    defaultTextureOptions.type = GL_UNSIGNED_BYTE;    _textureOptions = defaultTextureOptions;    _size = framebufferSize;    framebufferReferenceCount = 0;    referenceCountingDisabled = YES;        _texture = inputTexture;        return self;}- (id)initWithSize:(CGSize)framebufferSize;{    GPUTextureOptions defaultTextureOptions;    defaultTextureOptions.minFilter = GL_LINEAR;    defaultTextureOptions.magFilter = GL_LINEAR;    defaultTextureOptions.wrapS = GL_CLAMP_TO_EDGE;    defaultTextureOptions.wrapT = GL_CLAMP_TO_EDGE;    defaultTextureOptions.internalFormat = GL_RGBA;    defaultTextureOptions.format = GL_BGRA;    defaultTextureOptions.type = GL_UNSIGNED_BYTE;    if (!(self = [self initWithSize:framebufferSize textureOptions:defaultTextureOptions onlyTexture:NO]))    {        return nil;    }    return self;}- (void)dealloc{    [self destroyFramebuffer];}#pragma mark -#pragma mark Internal- (void)generateTexture;{    glActiveTexture(GL_TEXTURE1);    glGenTextures(1, &_texture);    glBindTexture(GL_TEXTURE_2D, _texture);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _textureOptions.minFilter);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _textureOptions.magFilter);    // This is necessary for non-power-of-two textures    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureOptions.wrapS);    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _textureOptions.wrapT);        // TODO: Handle mipmaps}- (void)generateFramebuffer;{    runSynchronouslyOnVideoProcessingQueue(^{        [GPUImageContext useImageProcessingContext];            glGenFramebuffers(1, &framebuffer);        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);                // By default, all framebuffers on iOS 5.0+ devices are backed by texture caches, using one shared cache        if ([GPUImageContext supportsFastTextureUpload])        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            CVOpenGLESTextureCacheRef coreVideoTextureCache = [[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache];            // Code originally sourced from http://allmybrain.com/2011/12/08/rendering-to-a-texture-with-ios-5-texture-cache-api/                        CFDictionaryRef empty; // empty value for attr value.            CFMutableDictionaryRef attrs;            empty = CFDictionaryCreate(kCFAllocatorDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); // our empty IOSurface properties dictionary            attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);            CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty);                        CVReturn err = CVPixelBufferCreate(kCFAllocatorDefault, (int)_size.width, (int)_size.height, kCVPixelFormatType_32BGRA, attrs, &renderTarget);            if (err)            {                NSLog(@"FBO size: %f, %f", _size.width, _size.height);                NSAssert(NO, @"Error at CVPixelBufferCreate %d", err);            }                        err = CVOpenGLESTextureCacheCreateTextureFromImage (kCFAllocatorDefault, coreVideoTextureCache, renderTarget,                                                                NULL, // texture attributes                                                                GL_TEXTURE_2D,                                                                _textureOptions.internalFormat, // opengl format                                                                (int)_size.width,                                                                (int)_size.height,                                                                _textureOptions.format, // native iOS format                                                                _textureOptions.type,                                                                0,                                                                &renderTexture);            if (err)            {                NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreateTextureFromImage %d", err);            }                        CFRelease(attrs);            CFRelease(empty);                        glBindTexture(CVOpenGLESTextureGetTarget(renderTexture), CVOpenGLESTextureGetName(renderTexture));            _texture = CVOpenGLESTextureGetName(renderTexture);            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _textureOptions.wrapS);            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _textureOptions.wrapT);                        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(renderTexture), 0);#endif        }        else        {            [self generateTexture];            glBindTexture(GL_TEXTURE_2D, _texture);                        glTexImage2D(GL_TEXTURE_2D, 0, _textureOptions.internalFormat, (int)_size.width, (int)_size.height, 0, _textureOptions.format, _textureOptions.type, 0);            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture, 0);        }                #ifndef NS_BLOCK_ASSERTIONS        GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);        NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status);        #endif                glBindTexture(GL_TEXTURE_2D, 0);    });}- (void)destroyFramebuffer;{    runSynchronouslyOnVideoProcessingQueue(^{        [GPUImageContext useImageProcessingContext];                if (framebuffer)        {            glDeleteFramebuffers(1, &framebuffer);            framebuffer = 0;        }                if ([GPUImageContext supportsFastTextureUpload] && (!_missingFramebuffer))        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            if (renderTarget)            {                CFRelease(renderTarget);                renderTarget = NULL;            }                        if (renderTexture)            {                CFRelease(renderTexture);                renderTexture = NULL;            }#endif        }        else        {            glDeleteTextures(1, &_texture);        }    });}#pragma mark -#pragma mark Usage- (void)activateFramebuffer;{    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);    glViewport(0, 0, (int)_size.width, (int)_size.height);}#pragma mark -#pragma mark Reference counting- (void)lock;{    if (referenceCountingDisabled)    {        return;    }        framebufferReferenceCount++;}- (void)unlock;{    if (referenceCountingDisabled)    {        return;    }    NSAssert(framebufferReferenceCount > 0, @"Tried to overrelease a framebuffer, did you forget to call -useNextFrameForImageCapture before using -imageFromCurrentFramebuffer?");    framebufferReferenceCount--;    if (framebufferReferenceCount < 1)    {        [[GPUImageContext sharedFramebufferCache] returnFramebufferToCache:self];    }}- (void)clearAllLocks;{    framebufferReferenceCount = 0;}- (void)disableReferenceCounting;{    referenceCountingDisabled = YES;}- (void)enableReferenceCounting;{    referenceCountingDisabled = NO;}#pragma mark -#pragma mark Image capturevoid dataProviderReleaseCallback (void *info, const void *data, size_t size){    free((void *)data);}void dataProviderUnlockCallback (void *info, const void *data, size_t size){    GPUImageFramebuffer *framebuffer = (__bridge_transfer GPUImageFramebuffer*)info;        [framebuffer restoreRenderTarget];    [framebuffer unlock];    [[GPUImageContext sharedFramebufferCache] removeFramebufferFromActiveImageCaptureList:framebuffer];}- (CGImageRef)newCGImageFromFramebufferContents;{    // a CGImage can only be created from a 'normal' color texture    NSAssert(self.textureOptions.internalFormat == GL_RGBA, @"For conversion to a CGImage the output texture format for this filter must be GL_RGBA.");    NSAssert(self.textureOptions.type == GL_UNSIGNED_BYTE, @"For conversion to a CGImage the type of the output texture of this filter must be GL_UNSIGNED_BYTE.");        __block CGImageRef cgImageFromBytes;        runSynchronouslyOnVideoProcessingQueue(^{        [GPUImageContext useImageProcessingContext];                NSUInteger totalBytesForImage = (int)_size.width * (int)_size.height * 4;        // It appears that the width of a texture must be padded out to be a multiple of 8 (32 bytes) if reading from it using a texture cache                GLubyte *rawImagePixels;                CGDataProviderRef dataProvider = NULL;        if ([GPUImageContext supportsFastTextureUpload])        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            NSUInteger paddedWidthOfImage = CVPixelBufferGetBytesPerRow(renderTarget) / 4.0;            NSUInteger paddedBytesForImage = paddedWidthOfImage * (int)_size.height * 4;                        glFinish();            CFRetain(renderTarget); // I need to retain the pixel buffer here and release in the data source callback to prevent its bytes from being prematurely deallocated during a photo write operation            [self lockForReading];            rawImagePixels = (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);            dataProvider = CGDataProviderCreateWithData((__bridge_retained void*)self, rawImagePixels, paddedBytesForImage, dataProviderUnlockCallback);            [[GPUImageContext sharedFramebufferCache] addFramebufferToActiveImageCaptureList:self]; // In case the framebuffer is swapped out on the filter, need to have a strong reference to it somewhere for it to hang on while the image is in existence#else#endif        }        else        {            [self activateFramebuffer];            rawImagePixels = (GLubyte *)malloc(totalBytesForImage);            glReadPixels(0, 0, (int)_size.width, (int)_size.height, GL_RGBA, GL_UNSIGNED_BYTE, rawImagePixels);            dataProvider = CGDataProviderCreateWithData(NULL, rawImagePixels, totalBytesForImage, dataProviderReleaseCallback);            [self unlock]; // Don't need to keep this around anymore        }                CGColorSpaceRef defaultRGBColorSpace = CGColorSpaceCreateDeviceRGB();                if ([GPUImageContext supportsFastTextureUpload])        {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE            cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, CVPixelBufferGetBytesPerRow(renderTarget), defaultRGBColorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst, dataProvider, NULL, NO, kCGRenderingIntentDefault);#else#endif        }        else        {            cgImageFromBytes = CGImageCreate((int)_size.width, (int)_size.height, 8, 32, 4 * (int)_size.width, defaultRGBColorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaLast, dataProvider, NULL, NO, kCGRenderingIntentDefault);        }                // Capture image with current device orientation        CGDataProviderRelease(dataProvider);        CGColorSpaceRelease(defaultRGBColorSpace);            });        return cgImageFromBytes;}- (void)restoreRenderTarget;{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    [self unlockAfterReading];    CFRelease(renderTarget);#else#endif}#pragma mark -#pragma mark Raw data bytes- (void)lockForReading{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    if ([GPUImageContext supportsFastTextureUpload])    {        if (readLockCount == 0)        {            CVPixelBufferLockBaseAddress(renderTarget, 0);        }        readLockCount++;    }#endif}- (void)unlockAfterReading{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    if ([GPUImageContext supportsFastTextureUpload])    {        NSAssert(readLockCount > 0, @"Unbalanced call to -[GPUImageFramebuffer unlockAfterReading]");        readLockCount--;        if (readLockCount == 0)        {            CVPixelBufferUnlockBaseAddress(renderTarget, 0);        }    }#endif}- (NSUInteger)bytesPerRow;{    if ([GPUImageContext supportsFastTextureUpload])    {#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE        return CVPixelBufferGetBytesPerRow(renderTarget);#else        return _size.width * 4; // TODO: do more with this on the non-texture-cache side#endif    }    else    {        return _size.width * 4;    }}- (GLubyte *)byteBuffer;{#if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE    [self lockForReading];    GLubyte * bufferBytes = CVPixelBufferGetBaseAddress(renderTarget);    [self unlockAfterReading];    return bufferBytes;#else    return NULL; // TODO: do more with this on the non-texture-cache side#endif}- (GLuint)texture;{//    NSLog(@"accessing texture: %d from FB: %@", _texture, self);    return _texture;}@end
View Code

 

  


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 靖边县| 宜黄县| 蛟河市| 天祝| 阿坝县| 宜宾县| 宣化县| 天柱县| 丹巴县| 喀喇| 芦山县| 怀来县| 衡阳市| 滦平县| 苏尼特右旗| 日照市| 涪陵区| 九寨沟县| 吴江市| 南皮县| 平阴县| 丰城市| 嘉善县| 永年县| 咸阳市| 娄底市| 呼伦贝尔市| 古丈县| 江川县| 茌平县| 太原市| 天峻县| 江山市| 金华市| 黑河市| 海安县| 汝城县| 绍兴市| 上犹县| 三原县| 呼图壁县|