GPUImageAPI文档之GPUImageFilter类

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

GPUImageFilter类

方法

- (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString

说明:使用顶点和片段着色字符串来初始化GPUImageFilter

- (id)initWithFragmentShaderFromFile:(NSString *)fragmentShaderFilename

说明:使用片段着色文件来初始化GPUImageFilter

- (void)initializeAttributes

说明:向GLPRogram中添加position和inputTextureCoordinate属性

- (CGSize)rotatedSize:(CGSize)sizeToRotate forIndex:(NSInteger)textureIndex

- (CGPoint)rotatedPoint:(CGPoint)pointToRotate forRotation:(GPUImageRotationMode)rotation

- (CGSize)sizeOfFBO

说明:设置输出帧缓冲区的尺寸

+ (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode

说明:旋转时的纹理坐标

- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates

说明:使用顶点数据和纹理坐标进行图像渲染

- (void)informTargetsAboutNewFrameAtTime:(CMTime)frameTime

说明:通知target操作帧

- (void)setBackgroundColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent alpha:(GLfloat)alphaComponent

说明:使用设置RGBA背景色

- (void)setInteger:(GLint)newInteger forUniformName:(NSString *)uniformName

说明:使用整型数据初始化Uniform变量

- (void)setFloat:(GLfloat)newFloat forUniformName:(NSString *)uniformName

说明:使用浮点型数据初始化Uniform变量

- (void)setSize:(CGSize)newSize forUniformName:(NSString *)uniformName

说明:使用CGSize数据初始化Uniform变量

- (void)setPoint:(CGPoint)newPoint forUniformName:(NSString *)uniformName

说明:使用CGPoint数据初始化Uniform变量

- (void)setFloatVec3:(GPUVector3)newVec3 forUniformName:(NSString *)uniformName

说明:使用GPUVector3数据初始化Uniform变量

- (void)setFloatVec4:(GPUVector4)newVec4 forUniform:(NSString *)uniformName

说明:使用GPUVector4数据初始化Uniform变量

- (void)setFloatArray:(GLfloat *)array length:(GLsizei)count forUniform:(NSString*)uniformName

说明:使用GLfloat数组初始化Uniform变量,长度为count

- (void)setAndExecuteUniformStateCallbackAtIndex:(GLint)uniform forProgram:(GLProgram *)shaderProgram toBlock:(dispatch_block_t)uniformStateBlock

说明:设置并执行完Uniform时回调操作

- (void)setUniformsForProgramAtIndex:(NSUInteger)programIndex

说明:向GLProgram的programIndex处添加Uniform变量

完整代码

#import"GPUImageOutput.h"#defineSTRINGIZE(x) #x#defineSTRINGIZE2(x) STRINGIZE(x)#defineSHADER_STRING(text) @ STRINGIZE2(text)#defineGPUImageHashIdentifier ##defineGPUImageWrappedLabel(x) x#defineGPUImageEscapedHashIdentifier(a) GPUImageWrappedLabel(GPUImageHashIdentifier)aexternNSString *constkGPUImageVertexShaderString;externNSString *constkGPUImagePassthroughFragmentShaderString;structGPUVector4 {

GLfloat one;

GLfloat two;

GLfloat three;

GLfloat four;

};

typedefstructGPUVector4 GPUVector4;structGPUVector3 {

GLfloat one;

GLfloat two;

GLfloat three;

};

typedefstructGPUVector3 GPUVector3;structGPUMatrix4x4 {

GPUVector4 one;

GPUVector4 two;

GPUVector4 three;

GPUVector4 four;

};

typedefstructGPUMatrix4x4 GPUMatrix4x4;structGPUMatrix3x3 {

GPUVector3 one;

GPUVector3 two;

GPUVector3 three;

};

typedefstructGPUMatrix3x3 GPUMatrix3x3;/** GPUImage's base filter class

Filters and other subsequent elements in the chain conform to the GPUImageInput protocol, which lets them take in the supplied or processed texture from the previous link in the chain and do something with it. Objects one step further down the chain are considered targets, and processing can be branched by adding multiple targets to a single output or filter.*/@interface GPUImageFilter : GPUImageOutput<GPUImageInput>{

GPUImageFramebuffer*firstInputFramebuffer;

GLProgram*filterProgram;

GLint filterPositionAttribute, filterTextureCoordinateAttribute;

GLint filterInputTextureUniform;

GLfloat backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha;

BOOL isEndProcessing;

CGSize currentFilterSize;

GPUImageRotationMode inputRotation;

BOOL currentlyReceivingMonoChromeInput;

NSMutableDictionary*uniformStateRestorationBlocks;

dispatch_semaphore_t imageCaptureSemaphore;

}

@property(readonly) CVPixelBufferRef renderTarget;

@property(readwrite, nonatomic) BOOL preventRendering;

@property(readwrite, nonatomic) BOOL currentlyReceivingMonochromeInput;///@name Initialization and teardown/**

Initialize with vertex and fragment shaders

You make take advantage of the SHADER_STRING macro to write your shaders in-line.

@param vertexShaderString Source code of the vertex shader to use

@param fragmentShaderString Source code of the fragment shader to use*/- (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString;/**

Initialize with a fragment shader

You may take advantage of the SHADER_STRING macro to write your shader in-line.

@param fragmentShaderString Source code of fragment shader to use*/- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;/**

Initialize with a fragment shader

@param fragmentShaderFilename Filename of fragment shader to load*/- (id)initWithFragmentShaderFromFile:(NSString *)fragmentShaderFilename;- (void)initializeAttributes;- (void)setupFilterForSize:(CGSize)filterFrameSize;-(CGSize)rotatedSize:(CGSize)sizeToRotate forIndex:(NSInteger)textureIndex;-(CGPoint)rotatedPoint:(CGPoint)pointToRotate forRotation:(GPUImageRotationMode)rotation;///@name Managing the display FBOs/** Size of the frame buffer object*/-(CGSize)sizeOfFBO;///@name Rendering+ (constGLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode;- (void)renderToTextureWithVertices:(constGLfloat *)vertices textureCoordinates:(constGLfloat *)textureCoordinates;- (void)informTargetsAboutNewFrameAtTime:(CMTime)frameTime;-(CGSize)outputFrameSize;///@name Input parameters- (void)setBackgroundColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent alpha:(GLfloat)alphaComponent;- (void)setInteger:(GLint)newInteger forUniformName:(NSString *)uniformName;- (void)setFloat:(GLfloat)newFloat forUniformName:(NSString *)uniformName;- (void)setSize:(CGSize)newSize forUniformName:(NSString *)uniformName;- (void)setPoint:(CGPoint)newPoint forUniformName:(NSString *)uniformName;- (void)setFloatVec3:(GPUVector3)newVec3 forUniformName:(NSString *)uniformName;- (void)setFloatVec4:(GPUVector4)newVec4 forUniform:(NSString *)uniformName;- (void)setFloatArray:(GLfloat *)array length:(GLsizei)count forUniform:(NSString*)uniformName;- (void)setMatrix3f:(GPUMatrix3x3)matrix forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setMatrix4f:(GPUMatrix4x4)matrix forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setFloat:(GLfloat)floatValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setPoint:(CGPoint)pointValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setSize:(CGSize)sizeValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setVec3:(GPUVector3)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setVec4:(GPUVector4)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setFloatArray:(GLfloat *)arrayValue length:(GLsizei)arrayLength forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setInteger:(GLint)intValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;- (void)setAndExecuteUniformStateCallbackAtIndex:(GLint)uniform forProgram:(GLProgram *)shaderProgram toBlock:(dispatch_block_t)uniformStateBlock;- (void)setUniformsForProgramAtIndex:(NSUInteger)programIndex;

@end

#import"GPUImageFilter.h"#import"GPUImagePicture.h"#import<AVFoundation/AVFoundation.h>//Hardcode the vertex shader for standard filters, but this can be overriddenNSString *constkGPUImageVertexShaderString =SHADER_STRING

(

attribute vec4 position;

attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;voidmain()

{

gl_Position=position;

textureCoordinate=inputTextureCoordinate.xy;

}

);#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONENSString*constkGPUImagePassthroughFragmentShaderString =SHADER_STRING

(

varying highp vec2 textureCoordinate;

uniform sampler2D inputImageTexture;voidmain()

{

gl_FragColor=texture2D(inputImageTexture, textureCoordinate);

}

);#elseNSString*constkGPUImagePassthroughFragmentShaderString =SHADER_STRING

(

varying vec2 textureCoordinate;

uniform sampler2D inputImageTexture;voidmain()

{

gl_FragColor=texture2D(inputImageTexture, textureCoordinate);

}

);#endif@implementation GPUImageFilter

@synthesize preventRendering=_preventRendering;

@synthesize currentlyReceivingMonochromeInput;#pragmamark -#pragmamark Initialization and teardown

- (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString;

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

{returnnil;

}

uniformStateRestorationBlocks= [NSMutableDictionary dictionaryWithCapacity:10];

_preventRendering=NO;

currentlyReceivingMonochromeInput=NO;

inputRotation=kGPUImageNoRotation;

backgroundColorRed=0.0;

backgroundColorGreen=0.0;

backgroundColorBlue=0.0;

backgroundColorAlpha=0.0;

imageCaptureSemaphore= dispatch_semaphore_create(0);

dispatch_semaphore_signal(imageCaptureSemaphore);

runSynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext useImageProcessingContext];

filterProgram=[[GPUImageContext sharedImageProcessingContext] programForVertexShaderString:vertexShaderString fragmentShaderString:fragmentShaderString];if(!filterProgram.initialized)

{

[self initializeAttributes];if(![filterProgram link])

{

NSString*progLog =[filterProgram programLog];

NSLog(@"Program link log: %@", progLog);

NSString*fragLog =[filterProgram fragmentShaderLog];

NSLog(@"Fragment shader compile log: %@", fragLog);

NSString*vertLog =[filterProgram vertexShaderLog];

NSLog(@"Vertex shader compile log: %@", vertLog);

filterProgram=nil;

NSAssert(NO,@"Filter shader link failed");

}

}

filterPositionAttribute= [filterProgram attributeIndex:@"position"];

filterTextureCoordinateAttribute= [filterProgram attributeIndex:@"inputTextureCoordinate"];

filterInputTextureUniform= [filterProgram uniformIndex:@"inputImageTexture"];//This does assume a name of "inputImageTexture" for the fragment shader[GPUImageContext setActiveShaderProgram:filterProgram];

glEnableVertexAttribArray(filterPositionAttribute);

glEnableVertexAttribArray(filterTextureCoordinateAttribute);

});returnself;

}- (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;

{if(!(self =[self initWithVertexShaderFromString:kGPUImageVertexShaderString fragmentShaderFromString:fragmentShaderString]))

{returnnil;

}returnself;

}- (id)initWithFragmentShaderFromFile:(NSString *)fragmentShaderFilename;

{

NSString*fragmentShaderPathname = [[NSBundle mainBundle] pathForResource:fragmentShaderFilename ofType:@"fsh"];

NSString*fragmentShaderString =[NSString stringWithContentsOfFile:fragmentShaderPathname encoding:NSUTF8StringEncoding error:nil];if(!(self =[self initWithFragmentShaderFromString:fragmentShaderString]))

{returnnil;

}returnself;

}-(id)init;

{if(!(self =[self initWithFragmentShaderFromString:kGPUImagePassthroughFragmentShaderString]))

{returnnil;

}returnself;

}- (void)initializeAttributes;

{

[filterProgram addAttribute:@"position"];

[filterProgram addAttribute:@"inputTextureCoordinate"];//Override this, calling back to this super method, in order to add new attributes to your vertex shader}- (void)setupFilterForSize:(CGSize)filterFrameSize;

{//This is where you can override to provide some custom setup, if your filter has a size-dependent element}- (void)dealloc

{#if!OS_OBJECT_USE_OBJCif(imageCaptureSemaphore !=NULL)

{

dispatch_release(imageCaptureSemaphore);

}#endif}#pragmamark -#pragmamark Still image processing

- (void)useNextFrameForImageCapture;

{

usingNextFrameForImageCapture=YES;//Set the semaphore high, if it isn't alreadyif(dispatch_semaphore_wait(imageCaptureSemaphore, DISPATCH_TIME_NOW) !=0)

{return;

}

}-(CGImageRef)newCGImageFromCurrentlyProcessedOutput

{//Give it three seconds to process, then abort if they forgot to set up the image capture properlydoubletimeoutForImageCapture =3.0;

dispatch_time_t convertedTimeout= dispatch_time(DISPATCH_TIME_NOW, timeoutForImageCapture *NSEC_PER_SEC);if(dispatch_semaphore_wait(imageCaptureSemaphore, convertedTimeout) !=0)

{returnNULL;

}

GPUImageFramebuffer* framebuffer =[self framebufferForOutput];

usingNextFrameForImageCapture=NO;

dispatch_semaphore_signal(imageCaptureSemaphore);

CGImageRef image=[framebuffer newCGImageFromFramebufferContents];returnimage;

}#pragmamark -#pragmamark Managing the display FBOs

-(CGSize)sizeOfFBO;

{

CGSize outputSize=[self maximumOutputSize];if( (CGSizeEqualToSize(outputSize, CGSizeZero)) || (inputTextureSize.width <outputSize.width) )

{returninputTextureSize;

}else{returnoutputSize;

}

}#pragmamark -#pragmamark Rendering

+ (constGLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode;

{staticconstGLfloat noRotationTextureCoordinates[] ={0.0f,0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,1.0f,

};staticconstGLfloat rotateLeftTextureCoordinates[] ={1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,0.0f,1.0f,

};staticconstGLfloat rotateRightTextureCoordinates[] ={0.0f,1.0f,0.0f,0.0f,1.0f,1.0f,1.0f,0.0f,

};staticconstGLfloat verticalFlipTextureCoordinates[] ={0.0f,1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,

};staticconstGLfloat horizontalFlipTextureCoordinates[] ={1.0f,0.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,

};staticconstGLfloat rotateRightVerticalFlipTextureCoordinates[] ={0.0f,0.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,

};staticconstGLfloat rotateRightHorizontalFlipTextureCoordinates[] ={1.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,

};staticconstGLfloat rotate180TextureCoordinates[] ={1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,0.0f,

};switch(rotationMode)

{casekGPUImageNoRotation:returnnoRotationTextureCoordinates;casekGPUImageRotateLeft:returnrotateLeftTextureCoordinates;casekGPUImageRotateRight:returnrotateRightTextureCoordinates;casekGPUImageFlipVertical:returnverticalFlipTextureCoordinates;casekGPUImageFlipHorizonal:returnhorizontalFlipTextureCoordinates;casekGPUImageRotateRightFlipVertical:returnrotateRightVerticalFlipTextureCoordinates;casekGPUImageRotateRightFlipHorizontal:returnrotateRightHorizontalFlipTextureCoordinates;casekGPUImageRotate180:returnrotate180TextureCoordinates;

}

}- (void)renderToTextureWithVertices:(constGLfloat *)vertices textureCoordinates:(constGLfloat *)textureCoordinates;

{if(self.preventRendering)

{

[firstInputFramebuffer unlock];return;

}

[GPUImageContext setActiveShaderProgram:filterProgram];

outputFramebuffer=[[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO];

[outputFramebuffer activateFramebuffer];if(usingNextFrameForImageCapture)

{

[outputFramebufferlock];

}

[self setUniformsForProgramAtIndex:0];

glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);

glClear(GL_COLOR_BUFFER_BIT);

glActiveTexture(GL_TEXTURE2);

glBindTexture(GL_TEXTURE_2D, [firstInputFramebuffer texture]);

glUniform1i(filterInputTextureUniform,2);

glVertexAttribPointer(filterPositionAttribute,2, GL_FLOAT,0,0, vertices);

glVertexAttribPointer(filterTextureCoordinateAttribute,2, GL_FLOAT,0,0, textureCoordinates);

glDrawArrays(GL_TRIANGLE_STRIP,0,4);

[firstInputFramebuffer unlock];if(usingNextFrameForImageCapture)

{

dispatch_semaphore_signal(imageCaptureSemaphore);

}

}- (void)informTargetsAboutNewFrameAtTime:(CMTime)frameTime;

{if(self.frameProcessingCompletionBlock !=NULL)

{

self.frameProcessingCompletionBlock(self, frameTime);

}//Get all targets the framebuffer so they can grab a lock on itfor(id<GPUImageInput> currentTargetintargets)

{if(currentTarget !=self.targetToIgnoreForUpdates)

{

NSInteger indexOfObject=[targets indexOfObject:currentTarget];

NSInteger textureIndex=[[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

[self setInputFramebufferForTarget:currentTarget atIndex:textureIndex];

[currentTarget setInputSize:[self outputFrameSize] atIndex:textureIndex];

}

}//Release our hold so it can return to the cache immediately upon processing[[self framebufferForOutput] unlock];if(usingNextFrameForImageCapture)

{//usingNextFrameForImageCapture = NO;}else{

[self removeOutputFramebuffer];

}//Trigger processing last, so that our unlock comes first in serial execution, avoiding the need for a callbackfor(id<GPUImageInput> currentTargetintargets)

{if(currentTarget !=self.targetToIgnoreForUpdates)

{

NSInteger indexOfObject=[targets indexOfObject:currentTarget];

NSInteger textureIndex=[[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

[currentTarget newFrameReadyAtTime:frameTime atIndex:textureIndex];

}

}

}-(CGSize)outputFrameSize;

{returninputTextureSize;

}#pragmamark -#pragmamark Input parameters

- (void)setBackgroundColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent alpha:(GLfloat)alphaComponent;

{

backgroundColorRed=redComponent;

backgroundColorGreen=greenComponent;

backgroundColorBlue=blueComponent;

backgroundColorAlpha=alphaComponent;

}- (void)setInteger:(GLint)newInteger forUniformName:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setInteger:newInteger forUniform:uniformIndex program:filterProgram];

}- (void)setFloat:(GLfloat)newFloat forUniformName:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setFloat:newFloat forUniform:uniformIndex program:filterProgram];

}- (void)setSize:(CGSize)newSize forUniformName:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setSize:newSize forUniform:uniformIndex program:filterProgram];

}- (void)setPoint:(CGPoint)newPoint forUniformName:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setPoint:newPoint forUniform:uniformIndex program:filterProgram];

}- (void)setFloatVec3:(GPUVector3)newVec3 forUniformName:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setVec3:newVec3 forUniform:uniformIndex program:filterProgram];

}- (void)setFloatVec4:(GPUVector4)newVec4 forUniform:(NSString *)uniformName;

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setVec4:newVec4 forUniform:uniformIndex program:filterProgram];

}- (void)setFloatArray:(GLfloat *)array length:(GLsizei)count forUniform:(NSString*)uniformName

{

GLint uniformIndex=[filterProgram uniformIndex:uniformName];

[self setFloatArray:array length:count forUniform:uniformIndex program:filterProgram];

}- (void)setMatrix3f:(GPUMatrix3x3)matrix forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniformMatrix3fv(uniform,1, GL_FALSE, (GLfloat *)&matrix);

}];

});

}- (void)setMatrix4f:(GPUMatrix4x4)matrix forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniformMatrix4fv(uniform,1, GL_FALSE, (GLfloat *)&matrix);

}];

});

}- (void)setFloat:(GLfloat)floatValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniform1f(uniform, floatValue);

}];

});

}- (void)setPoint:(CGPoint)pointValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

GLfloat positionArray[2];

positionArray[0] =pointValue.x;

positionArray[1] =pointValue.y;

glUniform2fv(uniform,1, positionArray);

}];

});

}- (void)setSize:(CGSize)sizeValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

GLfloat sizeArray[2];

sizeArray[0] =sizeValue.width;

sizeArray[1] =sizeValue.height;

glUniform2fv(uniform,1, sizeArray);

}];

});

}- (void)setVec3:(GPUVector3)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniform3fv(uniform,1, (GLfloat *)&vectorValue);

}];

});

}- (void)setVec4:(GPUVector4)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniform4fv(uniform,1, (GLfloat *)&vectorValue);

}];

});

}- (void)setFloatArray:(GLfloat *)arrayValue length:(GLsizei)arrayLength forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{//Make a copy of the data, so it doesn't get overwritten before async call executesNSData* arrayData = [NSData dataWithBytes:arrayValue length:arrayLength *sizeof(arrayValue[0])];

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniform1fv(uniform, arrayLength, [arrayData bytes]);

}];

});

}- (void)setInteger:(GLint)intValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;

{

runAsynchronouslyOnVideoProcessingQueue(^{

[GPUImageContext setActiveShaderProgram:shaderProgram];

[self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{

glUniform1i(uniform, intValue);

}];

});

}- (void)setAndExecuteUniformStateCallbackAtIndex:(GLint)uniform forProgram:(GLProgram *)shaderProgram toBlock:(dispatch_block_t)uniformStateBlock;

{

[uniformStateRestorationBlocks setObject:[uniformStateBlock copy] forKey:[NSNumber numberWithInt:uniform]];

uniformStateBlock();

}- (void)setUniformsForProgramAtIndex:(NSUInteger)programIndex;

{

[uniformStateRestorationBlocks enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop){

dispatch_block_t currentBlock=obj;

currentBlock();

}];

}#pragmamark -#pragmamark GPUImageInput

- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;

{staticconstGLfloat imageVertices[] ={-1.0f, -1.0f,1.0f, -1.0f,-1.0f,1.0f,1.0f,1.0f,

};

[self renderToTextureWithVertices:imageVertices textureCoordinates:[[selfclass] textureCoordinatesForRotation:inputRotation]];

[self informTargetsAboutNewFrameAtTime:frameTime];

}-(NSInteger)nextAvailableTextureIndex;

{return0;

}- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;

{

firstInputFramebuffer=newInputFramebuffer;

[firstInputFramebufferlock];

}-(CGSize)rotatedSize:(CGSize)sizeToRotate forIndex:(NSInteger)textureIndex;

{

CGSize rotatedSize=sizeToRotate;if(GPUImageRotationSwapsWidthAndHeight(inputRotation))

{

rotatedSize.width=sizeToRotate.height;

rotatedSize.height=sizeToRotate.width;

}returnrotatedSize;

}-(CGPoint)rotatedPoint:(CGPoint)pointToRotate forRotation:(GPUImageRotationMode)rotation;

{

CGPoint rotatedPoint;switch(rotation)

{casekGPUImageNoRotation:returnpointToRotate;

break;casekGPUImageFlipHorizonal:

{

rotatedPoint.x=1.0-pointToRotate.x;

rotatedPoint.y=pointToRotate.y;

};

break;casekGPUImageFlipVertical:

{

rotatedPoint.x=pointToRotate.x;

rotatedPoint.y=1.0-pointToRotate.y;

};

break;casekGPUImageRotateLeft:

{

rotatedPoint.x=1.0-pointToRotate.y;

rotatedPoint.y=pointToRotate.x;

};

break;casekGPUImageRotateRight:

{

rotatedPoint.x=pointToRotate.y;

rotatedPoint.y=1.0-pointToRotate.x;

};

break;casekGPUImageRotateRightFlipVertical:

{

rotatedPoint.x=pointToRotate.y;

rotatedPoint.y=pointToRotate.x;

};

break;casekGPUImageRotateRightFlipHorizontal:

{

rotatedPoint.x=1.0-pointToRotate.y;

rotatedPoint.y=1.0-pointToRotate.x;

};

break;casekGPUImageRotate180:

{

rotatedPoint.x=1.0-pointToRotate.x;

rotatedPoint.y=1.0-pointToRotate.y;

};

break;

}returnrotatedPoint;

}- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;

{if(self.preventRendering)

{return;

}if(overrideInputSize)

{if(CGSizeEqualToSize(forcedMaximumSize, CGSizeZero))

{

}else{

CGRect insetRect= AVMakeRectWithaspectRatioInsideRect(newSize, CGRectMake(0.0,0.0, forcedMaximumSize.width, forcedMaximumSize.height));

inputTextureSize=insetRect.size;

}

}else{

CGSize rotatedSize=[self rotatedSize:newSize forIndex:textureIndex];if(CGSizeEqualToSize(rotatedSize, CGSizeZero))

{

inputTextureSize=rotatedSize;

}elseif(!CGSizeEqualToSize(inputTextureSize, rotatedSize))

{

inputTextureSize=rotatedSize;

}

}

[self setupFilterForSize:[self sizeOfFBO]];

}- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;

{

inputRotation=newInputRotation;

}- (void)forceProcessingAtSize:(CGSize)frameSize;

{if(CGSizeEqualToSize(frameSize, CGSizeZero))

{

overrideInputSize=NO;

}else{

overrideInputSize=YES;

inputTextureSize=frameSize;

forcedMaximumSize=CGSizeZero;

}

}- (void)forceProcessingAtSizeRespectingAspectRatio:(CGSize)frameSize;

{if(CGSizeEqualToSize(frameSize, CGSizeZero))

{

overrideInputSize=NO;

inputTextureSize=CGSizeZero;

forcedMaximumSize=CGSizeZero;

}else{

overrideInputSize=YES;

forcedMaximumSize=frameSize;

}

}-(CGSize)maximumOutputSize;

{//I'm temporarily disabling adjustments for smaller output sizes until I figure out how to make this work betterreturnCGSizeZero;/*if (CGSizeEqualToSize(cachedMaximumOutputSize, CGSizeZero))

{

for (id<GPUImageInput> currentTarget in targets)

{

if ([currentTarget maximumOutputSize].width > cachedMaximumOutputSize.width)

{

cachedMaximumOutputSize = [currentTarget maximumOutputSize];

}

}

}

return cachedMaximumOutputSize;*/}- (void)endProcessing

{if(!isEndProcessing)

{

isEndProcessing=YES;for(id<GPUImageInput> currentTargetintargets)

{

[currentTarget endProcessing];

}

}

}-(BOOL)wantsMonochromeInput;

{returnNO;

}#pragmamark -#pragmamarkaccessors@end

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