首页 > 学院 > 开发设计 > 正文

GPUImageAPI文档之GPUImageContext类

2019-11-14 17:55:32
字体:
来源:转载
供稿:网友

  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"#define GPUImageRotationSwapsWidthAndHeight(rotation) ((rotation) == kGPUImageRotateLeft || (rotation) == kGPUImageRotateRight || (rotation) == kGPUImageRotateRightFlipVertical || (rotation) == kGPUImageRotateRightFlipHorizontal)typedef enum { 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>#define MAXSHADERPROGRAMSALLOWEDINCACHE 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;static void *openGLESContextQueueKey;- (id)init;{    if (!(self = [super init]))    {        return nil;    }    openGLESContextQueueKey = &openGLESContextQueueKey;    _contextQueue = dispatch_queue_create("com.sunsetlakesoftware.GPUImage.openGLESContextQueue", NULL);    #if OS_OBJECT_USE_OBJC    dispatch_queue_set_specific(_contextQueue, openGLESContextQueueKey, (__bridge void *)self, NULL);#endif    shaderProgramCache = [[NSMutableDictionary alloc] init];    shaderProgramUsageHistory = [[NSMutableArray alloc] init];        return self;}+ (void *)contextKey {    return openGLESContextQueueKey;}// Based on Colin Wheeler's example here: http://cocoasamurai.blogspot.com/2011/04/singletons-your-doing-them-wrong.html+ (GPUImageContext *)sharedImageProcessingContext;{    static dispatch_once_t pred;    static GPUImageContext *sharedImageProcessingContext = nil;        dispatch_once(&pred, ^{        sharedImageProcessingContext = [[[self class] alloc] init];    });    return sharedImageProcessingContext;}+ (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;{    static dispatch_once_t pred;    static GLint maxTextureSize = 0;        dispatch_once(&pred, ^{        [self useImageProcessingContext];        glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);    });    return maxTextureSize;}+ (GLint)maximumTextureUnitsForThisDevice;{    static dispatch_once_t pred;    static GLint maxTextureUnits = 0;    dispatch_once(&pred, ^{        [self useImageProcessingContext];        glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureUnits);    });        return maxTextureUnits;}+ (GLint)maximumVaryingVectorsForThisDevice;{    static dispatch_once_t pred;    static GLint maxVaryingVectors = 0;    dispatch_once(&pred, ^{        [self useImageProcessingContext];        glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryingVectors);    });    return maxVaryingVectors;}+ (BOOL)deviceSupportsOpenGLESExtension:(NSString *)extension;{    static dispatch_once_t pred;    static NSArray *extensionNames = nil;    // Cache extensions for later quick reference, since this won't change for a given device    dispatch_once(&pred, ^{        [GPUImageContext useImageProcessingContext];        NSString *extensionsString = [NSString stringWithCString:(const char *)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;{    static dispatch_once_t pred;    static BOOL supportsRedTextures = NO;        dispatch_once(&pred, ^{        supportsRedTextures = [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_texture_rg"];    });        return supportsRedTextures;}+ (BOOL)deviceSupportsFramebufferReads;{    static dispatch_once_t pred;    static BOOL supportsFramebufferReads = NO;        dispatch_once(&pred, ^{        supportsFramebufferReads = [GPUImageContext deviceSupportsOpenGLESExtension:@"GL_EXT_shader_framebuffer_fetch"];    });        return supportsFramebufferReads;}+ (CGSize)sizeThatFitsWithinATextureForSize:(CGSize)inputSize;{    GLint maxTextureSize = [self maximumTextureSizeForThisDevice];     if ( (inputSize.width < maxTextureSize) && (inputSize.height < maxTextureSize) )    {        return inputSize;    }        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;    }    return adjustedSize;}- (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];//            }//        }    }        return programFromCache;}- (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.");    return context;}#pragma mark -#pragma mark Manage fast texture upload+ (BOOL)supportsFastTextureUpload;{#if TARGET_IPHONE_SIMULATOR    return NO;#else    #pragma clang diagnostic push#pragma clang diagnostic ignored "-Wtautological-pointer-compare"    return (CVOpenGLESTextureCacheCreate != NULL);#pragma clang diagnostic pop#endif}#pragma mark -#pragma mark accessors- (EAGLContext *)context;{    if (_context == nil)    {        _context = [self createContext];        [EAGLContext setCurrentContext:_context];                // Set up a few global settings for the image processing pipeline        glDisable(GL_DEPTH_TEST);    }        return _context;}- (CVOpenGLESTextureCacheRef)coreVideoTextureCache;{    if (_coreVideoTextureCache == NULL)    {#if defined(__IPHONE_6_0)        CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, [self context], NULL, &_coreVideoTextureCache);#else        CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, (__bridge void *)[self context], NULL, &_coreVideoTextureCache);#endif                if (err)        {            NSAssert(NO, @"Error at CVOpenGLESTextureCacheCreate %d", err);        }    }        return _coreVideoTextureCache;}- (GPUImageFramebufferCache *)framebufferCache;{    if (_framebufferCache == nil)    {        _framebufferCache = [[GPUImageFramebufferCache alloc] init];    }        return _framebufferCache;}@end
View Code

 


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表