GPUImageAPI文档之GPUImageContext类

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

GPUImageContext类,提供OpenGL ES基本环境,我们一般不会用到,所以讲的很简单。

属性

@PRoperty(readonly, nonatomic) dispatch_queue_t contextQueue

说明:创建一个context线程

描述:_contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL);

@property(readwrite, retain, nonatomic) GLProgram *currentShaderProgram

说明:当前着色器program

@property(readonly, retain, nonatomic) EAGLContext *context

说明:opengl es绘制环境,管理上下文

方法

+ (void *)contextKey

说明:设置当前context的线程标识符,全局静态变量。

+ (GPUImageContext *)sharedImageProcessingContext

说明:创建一个全局的GPUImageContext对象的单例。

+ (dispatch_queue_t)sharedContextQueue

说明:创建一个context queue单例

+ (GPUImageFramebufferCache *)sharedFramebufferCache

说明:创建一个GPUFramebufferCache单例

- (void)useAsCurrentContext

说明:使用当前context

+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;

- (void)setContextShaderProgram:(GLProgram *)shaderProgram;

+ (GLint)maximumTextureSizeForThisDevice;

+ (GLint)maximumTextureUnitsForThisDevice;

+ (GLint)maximumVaryingVectorsForThisDevice;

+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;

+ (BOOL)deviceSupportsRedTextures;

+ (BOOL)deviceSupportsFramebufferReads;

+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;

- (void)presentBufferForDisplay;

- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;

- (void)useSharegroup:(EAGLSharegroup *)sharegroup;

+ (BOOL)supportsFastTextureUpload;

完整代码

#import"GLProgram.h"#import"GPUImageFramebuffer.h"#import"GPUImageFramebufferCache.h"#defineGPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal)typedefenum{ kGPUImageNoRotation, kGPUImageRotateLeft, kGPUImageRotateRight, kGPUImageFlipVertical, kGPUImageFlipHorizonal, kGPUImageRotateRightFlipVertical, kGPUImageRotateRightFlipHorizontal, kGPUImageRotate180 } GPUImageRotationMode;

@interface GPUImageContext : NSObject

@property(readonly, nonatomic) dispatch_queue_t contextQueue;

@property(readwrite, retain, nonatomic) GLProgram*currentShaderProgram;

@property(readonly, retain, nonatomic) EAGLContext *context;

@property(readonly) CVOpenGLESTextureCacheRef coreVideoTextureCache;

@property(readonly) GPUImageFramebufferCache *framebufferCache;+ (void*)contextKey;+ (GPUImageContext *)sharedImageProcessingContext;+(dispatch_queue_t)sharedContextQueue;+ (GPUImageFramebufferCache *)sharedFramebufferCache;+ (void)useImageProcessingContext;- (void)useAsCurrentContext;+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;- (void)setContextShaderProgram:(GLProgram *)shaderProgram;+(GLint)maximumTextureSizeForThisDevice;+(GLint)maximumTextureUnitsForThisDevice;+(GLint)maximumVaryingVectorsForThisDevice;+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;+(BOOL)deviceSupportsRedTextures;+(BOOL)deviceSupportsFramebufferReads;+(CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;- (void)presentBufferForDisplay;- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;- (void)useSharegroup:(EAGLSharegroup *)sharegroup;//Manage fast texture upload+(BOOL)supportsFastTextureUpload;

@end

@protocol GPUImageInput<NSObject>

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;-(NSInteger)nextAvailableTextureIndex;- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;-(CGSize)maximumOutputSize;- (void)endProcessing;-(BOOL)shouldIgnoreUpdatesToThisTarget;-(BOOL)enabled;-(BOOL)wantsMonoChromeInput;- (void)setCurrentlyReceivingMonochromeInput:(BOOL)newValue;

@end

View Code

#import"GPUImageContext.h"#import<OpenGLES/EAGLDrawable.h>#import<AVFoundation/AVFoundation.h>#defineMAXSHADERPROGRAMSALLOWEDINCACHE 40@interface GPUImageContext()

{

NSMutableDictionary*shaderProgramCache;

NSMutableArray*shaderProgramUsageHistory;

EAGLSharegroup*_sharegroup;

}

@end

@implementation GPUImageContext

@synthesize context=_context;

@synthesize currentShaderProgram=_currentShaderProgram;

@synthesize contextQueue=_contextQueue;

@synthesize coreVideoTextureCache=_coreVideoTextureCache;

@synthesize framebufferCache=_framebufferCache;staticvoid*openGLESContextQueueKey;-(id)init;

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

{returnnil;

}

openGLESContextQueueKey= &openGLESContextQueueKey;

_contextQueue= dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL);#ifOS_OBJECT_USE_OBJCdispatch_queue_set_specific(_contextQueue, openGLESContextQueueKey, (__bridgevoid*)self, NULL);#endifshaderProgramCache=[[NSMutableDictionary alloc] init];

shaderProgramUsageHistory=[[NSMutableArray alloc] init];returnself;

}+ (void*)contextKey {returnopenGLESContextQueueKey;

}//Based on Colin Wheeler's example here:http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html+ (GPUImageContext *)sharedImageProcessingContext;

{staticdispatch_once_t pred;staticGPUImageContext *sharedImageProcessingContext =nil;

dispatch_once(&pred, ^{

sharedImageProcessingContext= [[[selfclass] alloc] init];

});returnsharedImageProcessingContext;

}+(dispatch_queue_t)sharedContextQueue;

{return[[self sharedImageProcessingContext] contextQueue];

}+ (GPUImageFramebufferCache *)sharedFramebufferCache;

{return[[self sharedImageProcessingContext] framebufferCache];

}+ (void)useImageProcessingContext;

{

[[GPUImageContext sharedImageProcessingContext] useAsCurrentContext];

}- (void)useAsCurrentContext;

{

EAGLContext*imageProcessingContext =[self context];if([EAGLContext currentContext] !=imageProcessingContext)

{

[EAGLContext setCurrentContext:imageProcessingContext];

}

}+ (void)setActiveShaderProgram:(GLProgram *)shaderProgram;

{

GPUImageContext*sharedContext =[GPUImageContext sharedImageProcessingContext];

[sharedContext setContextShaderProgram:shaderProgram];

}- (void)setContextShaderProgram:(GLProgram *)shaderProgram;

{

EAGLContext*imageProcessingContext =[self context];if([EAGLContext currentContext] !=imageProcessingContext)

{

[EAGLContext setCurrentContext:imageProcessingContext];

}if(self.currentShaderProgram !=shaderProgram)

{

self.currentShaderProgram=shaderProgram;

[shaderProgram use];

}

}+(GLint)maximumTextureSizeForThisDevice;

{staticdispatch_once_t pred;staticGLint maxTextureSize =0;

dispatch_once(&pred, ^{

[self useImageProcessingContext];

glGetIntegerv(GL_MAX_TEXTURE_SIZE,&maxTextureSize);

});returnmaxTextureSize;

}+(GLint)maximumTextureUnitsForThisDevice;

{staticdispatch_once_t pred;staticGLint maxTextureUnits =0;

dispatch_once(&pred, ^{

[self useImageProcessingContext];

glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS,&maxTextureUnits);

});returnmaxTextureUnits;

}+(GLint)maximumVaryingVectorsForThisDevice;

{staticdispatch_once_t pred;staticGLint maxVaryingVectors =0;

dispatch_once(&pred, ^{

[self useImageProcessingContext];

glGetIntegerv(GL_MAX_VARYING_VECTORS,&maxVaryingVectors);

});returnmaxVaryingVectors;

}+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;

{staticdispatch_once_t pred;staticNSArray *extensionNames =nil;//Cache extensions for later quick reference, since this won't change for a given devicedispatch_once(&pred, ^{

[GPUImageContext useImageProcessingContext];

NSString*extensionsString = [NSString stringWithCString:(constchar*)glGetString(GL_EXTENSIONS) encoding:NSASCIIStringEncoding];

extensionNames= [extensionsString componentsSeparatedByString:@""];

});return[extensionNames containsObject:extension];

}//http://www.khronos.org/registry/gles/extensions/EXT/EXT_texture_rg.txt+(BOOL)deviceSupportsRedTextures;

{staticdispatch_once_t pred;staticBOOL supportsRedTextures =NO;

dispatch_once(&pred, ^{

supportsRedTextures= [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_texture_rg"];

});returnsupportsRedTextures;

}+(BOOL)deviceSupportsFramebufferReads;

{staticdispatch_once_t pred;staticBOOL supportsFramebufferReads =NO;

dispatch_once(&pred, ^{

supportsFramebufferReads= [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_shader_framebuffer_fetch"];

});returnsupportsFramebufferReads;

}+(CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;

{

GLint maxTextureSize=[self maximumTextureSizeForThisDevice];if( (inputSize.width < maxTextureSize) && (inputSize.height <maxTextureSize) )

{returninputSize;

}

CGSize adjustedSize;if(inputSize.width >inputSize.height)

{

adjustedSize.width=(CGFloat)maxTextureSize;

adjustedSize.height= ((CGFloat)maxTextureSize / inputSize.width) *inputSize.height;

}else{

adjustedSize.height=(CGFloat)maxTextureSize;

adjustedSize.width= ((CGFloat)maxTextureSize / inputSize.height) *inputSize.width;

}returnadjustedSize;

}- (void)presentBufferForDisplay;

{

[self.context presentRenderbuffer:GL_RENDERBUFFER];

}- (GLProgram *)programForVertexShaderString:(NSString *)vertexShaderString fragmentShaderString:(NSString *)fragmentShaderString;

{

NSString*lookupKeyForShaderProgram = [NSString stringWithFormat:@"V: %@ - F: %@", vertexShaderString, fragmentShaderString];

GLProgram*programFromCache =[shaderProgramCache objectForKey:lookupKeyForShaderProgram];if(programFromCache ==nil)

{

programFromCache=[[GLProgram alloc] initWithVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString];

[shaderProgramCache setObject:programFromCache forKey:lookupKeyForShaderProgram];//[shaderProgramUsageHistory addObject:lookupKeyForShaderProgram];//if ([shaderProgramUsageHistory count] >= MAXSHADERPROGRAMSALLOWEDINCACHE)//{//for (NSUInteger currentShaderProgramRemovedFromCache = 0; currentShaderProgramRemovedFromCache < 10; currentShaderProgramRemovedFromCache++)//{//NSString *shaderProgramToRemoveFromCache = [shaderProgramUsageHistory objectAtIndex:0];//[shaderProgramUsageHistory removeObjectAtIndex:0];//[shaderProgramCache removeObjectForKey:shaderProgramToRemoveFromCache];//}//}}returnprogramFromCache;

}- (void)useSharegroup:(EAGLSharegroup *)sharegroup;

{

NSAssert(_context== nil,@"Unable to use a share group when the context has already been created. Call this method before you use the context for the first time.");

_sharegroup=sharegroup;

}- (EAGLContext *)createContext;

{

EAGLContext*context =[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:_sharegroup];

NSAssert(context!= nil,@"Unable to create an OpenGL ES 2.0 context. The GPUImage framework requires OpenGL ES 2.0 support to work.");returncontext;

}#pragmamark -#pragmamark Manage fast texture upload

+(BOOL)supportsFastTextureUpload;

{#ifTARGET_IPHONE_SIMULATORreturnNO;#else#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wtautological-pointer-compare"return(CVOpenGLESTextureCacheCreate !=NULL);#pragmaclang diagnostic pop#endif}#pragmamark -#pragmamarkaccessors

- (EAGLContext *)context;

{if(_context ==nil)

{

_context=[self createContext];

[EAGLContext setCurrentContext:_context];//Set up a few global settings for the image processing pipelineglDisable(GL_DEPTH_TEST);

}return_context;

}-(CVOpenGLESTextureCacheRef)coreVideoTextureCache;

{if(_coreVideoTextureCache ==NULL)

{#ifdefined(__IPHONE_6_0)CVReturn err= CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [self context], NULL, &_coreVideoTextureCache);#elseCVReturn err= CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridgevoid*)[self context], NULL, &_coreVideoTextureCache);#endifif(err)

{

NSAssert(NO,@"Error at CVOpenGLESTextureCacheCreate %d", err);

}

}return_coreVideoTextureCache;

}- (GPUImageFramebufferCache *)framebufferCache;

{if(_framebufferCache ==nil)

{

_framebufferCache=[[GPUImageFramebufferCache alloc] init];

}return_framebufferCache;

}

@end

View Code

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