GPUImageAPI文档之GPUImageFramebuffer类

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

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]))

{returnnil;

}returnself;

}

- (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]))

{returnnil;

}

_textureOptions=fboTextureOptions;

_size=framebufferSize;

framebufferReferenceCount=0;

referenceCountingDisabled=NO;

_missingFramebuffer=onlyGenerateTexture;if(_missingFramebuffer)

{

runSynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext useImageProcessingContext];

[self generateTexture];

framebuffer=0;

});

}else{

[self generateFramebuffer];

}returnself;

}

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

说明:创建一个size为framebufferSize大小的帧缓冲对象

参数:inputTexture为输入的纹理,用于渲染图片。

返回:创建成功的帧缓冲对象。

实现

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

{if(!(self =[super init]))

{returnnil;

}

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;returnself;

}

- (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 textureNSAssert(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 cacheGLubyte*rawImagePixels;

CGDataProviderRef dataProvider=NULL;if([GPUImageContext supportsFastTextureUpload])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONENSUInteger 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 writeOperation[self lockForReading];

rawImagePixels= (GLubyte *)CVPixelBufferGetBaseAddress(renderTarget);

dataProvider= CGDataProviderCreateWithData((__bridge_retainedvoid*)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])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEcgImageFromBytes= 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 orientationCGDataProviderRelease(dataProvider);

CGColorSpaceRelease(defaultRGBColorSpace);

});returncgImageFromBytes;

}

- (void)restoreRenderTarget

说明:还原渲染目标对象

实现

- (void)restoreRenderTarget;

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE[self unlockAfterReading];

CFRelease(renderTarget);#else#endif}

- (void)lockForReading

说明:锁定PixelBuffer

实现:

- (void)lockForReading

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEif([GPUImageContext supportsFastTextureUpload])

{if(readLockCount ==0)

{

CVPixelBufferLockBaseAddress(renderTarget,0);

}

readLockCount++;

}#endif}

- (void)unlockAfterReading

说明:解锁PixelBuffer

- (void)unlockAfterReading

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEif([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])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEreturnCVPixelBufferGetBytesPerRow(renderTarget);#elsereturn_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;

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE[self lockForReading];

GLubyte* bufferBytes =CVPixelBufferGetBaseAddress(renderTarget);

[self unlockAfterReading];returnbufferBytes;#elsereturnNULL;//TODO: do more with this on the non-texture-cache side#endif}

完整代码

#import <Foundation/Foundation.h>#ifTARGET_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>typedefstructGPUTextureOptions {

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;#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONECVPixelBufferRef renderTarget;

CVOpenGLESTextureRef renderTexture;

NSUInteger readLockCount;#else#endifNSUInteger framebufferReferenceCount;

BOOL referenceCountingDisabled;

}- (void)generateFramebuffer;- (void)generateTexture;- (void)destroyFramebuffer;

@endvoiddataProviderReleaseCallback (void*info,constvoid*data, size_t size);voiddataProviderUnlockCallback (void*info,constvoid*data, size_t size);

@implementation GPUImageFramebuffer

@synthesize size=_size;

@synthesize textureOptions=_textureOptions;

@synthesize texture=_texture;

@synthesize missingFramebuffer=_missingFramebuffer;#pragmamark -#pragmamark Initialization and teardown

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

{if(!(self =[super init]))

{returnnil;

}

_textureOptions=fboTextureOptions;

_size=framebufferSize;

framebufferReferenceCount=0;

referenceCountingDisabled=NO;

_missingFramebuffer=onlyGenerateTexture;if(_missingFramebuffer)

{

runSynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext useImageProcessingContext];

[self generateTexture];

framebuffer=0;

});

}else{

[self generateFramebuffer];

}returnself;

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

{if(!(self =[super init]))

{returnnil;

}

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;returnself;

}-(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]))

{returnnil;

}returnself;

}- (void)dealloc

{

[self destroyFramebuffer];

}#pragmamark -#pragmamark 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 texturesglTexParameteri(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 cacheif([GPUImageContext supportsFastTextureUpload])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONECVOpenGLESTextureCacheRef coreVideoTextureCache=[[GPUImageContext sharedImageProcessingContext] coreVideoTextureCache];//Code originally sourced fromhttp://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 dictionaryattrs = 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 attributesGL_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);#endifglBindTexture(GL_TEXTURE_2D,0);

});

}- (void)destroyFramebuffer;

{

runSynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext useImageProcessingContext];if(framebuffer)

{

glDeleteFramebuffers(1, &framebuffer);

framebuffer=0;

}if([GPUImageContext supportsFastTextureUpload] && (!_missingFramebuffer))

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEif(renderTarget)

{

CFRelease(renderTarget);

renderTarget=NULL;

}if(renderTexture)

{

CFRelease(renderTexture);

renderTexture=NULL;

}#endif}else{

glDeleteTextures(1, &_texture);

}

});

}#pragmamark -#pragmamark Usage

- (void)activateFramebuffer;

{

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

glViewport(0,0, (int)_size.width, (int)_size.height);

}#pragmamark -#pragmamark 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;

}#pragmamark -#pragmamark Image capturevoiddataProviderReleaseCallback (void*info,constvoid*data, size_t size)

{free((void*)data);

}voiddataProviderUnlockCallback (void*info,constvoid*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 textureNSAssert(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 cacheGLubyte*rawImagePixels;

CGDataProviderRef dataProvider=NULL;if([GPUImageContext supportsFastTextureUpload])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONENSUInteger 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_retainedvoid*)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])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEcgImageFromBytes= 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 orientationCGDataProviderRelease(dataProvider);

CGColorSpaceRelease(defaultRGBColorSpace);

});returncgImageFromBytes;

}- (void)restoreRenderTarget;

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE[self unlockAfterReading];

CFRelease(renderTarget);#else#endif}#pragmamark -#pragmamark Raw data bytes

- (void)lockForReading

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEif([GPUImageContext supportsFastTextureUpload])

{if(readLockCount ==0)

{

CVPixelBufferLockBaseAddress(renderTarget,0);

}

readLockCount++;

}#endif}- (void)unlockAfterReading

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEif([GPUImageContext supportsFastTextureUpload])

{

NSAssert(readLockCount>0,@"Unbalanced call to -[GPUImageFramebuffer unlockAfterReading]");

readLockCount--;if(readLockCount ==0)

{

CVPixelBufferUnlockBaseAddress(renderTarget,0);

}

}#endif}-(NSUInteger)bytesPerRow;

{if([GPUImageContext supportsFastTextureUpload])

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONEreturnCVPixelBufferGetBytesPerRow(renderTarget);#elsereturn_size.width *4;//TODO: do more with this on the non-texture-cache side#endif}else{return_size.width *4;

}

}- (GLubyte *)byteBuffer;

{#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE[self lockForReading];

GLubyte* bufferBytes =CVPixelBufferGetBaseAddress(renderTarget);

[self unlockAfterReading];returnbufferBytes;#elsereturnNULL;//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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航