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"

#define STRINGIZE(x) #x
#define STRINGIZE2(x) STRINGIZE(x)
#define SHADER_STRING(text) @ STRINGIZE2(text) #define GPUImageHashIdentifier #
#define GPUImageWrappedLabel(x) x
#define GPUImageEscapedHashIdentifier(a) GPUImageWrappedLabel(GPUImageHashIdentifier)a extern NSString *const kGPUImageVertexShaderString;
extern NSString *const kGPUImagePassthroughFragmentShaderString; struct GPUVector4 {
GLfloat one;
GLfloat two;
GLfloat three;
GLfloat four;
};
typedef struct GPUVector4 GPUVector4; struct GPUVector3 {
GLfloat one;
GLfloat two;
GLfloat three;
};
typedef struct GPUVector3 GPUVector3; struct GPUMatrix4x4 {
GPUVector4 one;
GPUVector4 two;
GPUVector4 three;
GPUVector4 four;
};
typedef struct GPUMatrix4x4 GPUMatrix4x4; struct GPUMatrix3x3 {
GPUVector3 one;
GPUVector3 two;
GPUVector3 three;
};
typedef struct GPUMatrix3x3 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
+ (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode;
- (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)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 overridden
NSString *const kGPUImageVertexShaderString = SHADER_STRING
(
attribute vec4 position;
attribute vec4 inputTextureCoordinate; varying vec2 textureCoordinate; void main()
{
gl_Position = position;
textureCoordinate = inputTextureCoordinate.xy;
}
); #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
(
varying highp vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}
); #else NSString *const kGPUImagePassthroughFragmentShaderString = SHADER_STRING
(
varying vec2 textureCoordinate; uniform sampler2D inputImageTexture; void main()
{
gl_FragColor = texture2D(inputImageTexture, textureCoordinate);
}
);
#endif @implementation GPUImageFilter @synthesize preventRendering = _preventRendering;
@synthesize currentlyReceivingMonochromeInput; #pragma mark -
#pragma mark Initialization and teardown - (id)initWithVertexShaderFromString:(NSString *)vertexShaderString fragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [super init]))
{
return nil;
} uniformStateRestorationBlocks = [NSMutableDictionary dictionaryWithCapacity:];
_preventRendering = NO;
currentlyReceivingMonochromeInput = NO;
inputRotation = kGPUImageNoRotation;
backgroundColorRed = 0.0;
backgroundColorGreen = 0.0;
backgroundColorBlue = 0.0;
backgroundColorAlpha = 0.0;
imageCaptureSemaphore = dispatch_semaphore_create();
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);
}); return self;
} - (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString;
{
if (!(self = [self initWithVertexShaderFromString:kGPUImageVertexShaderString fragmentShaderFromString:fragmentShaderString]))
{
return nil;
} return self;
} - (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]))
{
return nil;
} return self;
} - (id)init;
{
if (!(self = [self initWithFragmentShaderFromString:kGPUImagePassthroughFragmentShaderString]))
{
return nil;
} return self;
} - (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_OBJC
if (imageCaptureSemaphore != NULL)
{
dispatch_release(imageCaptureSemaphore);
}
#endif } #pragma mark -
#pragma mark Still image processing - (void)useNextFrameForImageCapture;
{
usingNextFrameForImageCapture = YES; // Set the semaphore high, if it isn't already
if (dispatch_semaphore_wait(imageCaptureSemaphore, DISPATCH_TIME_NOW) != )
{
return;
}
} - (CGImageRef)newCGImageFromCurrentlyProcessedOutput
{
// Give it three seconds to process, then abort if they forgot to set up the image capture properly
double timeoutForImageCapture = 3.0;
dispatch_time_t convertedTimeout = dispatch_time(DISPATCH_TIME_NOW, timeoutForImageCapture * NSEC_PER_SEC); if (dispatch_semaphore_wait(imageCaptureSemaphore, convertedTimeout) != )
{
return NULL;
} GPUImageFramebuffer* framebuffer = [self framebufferForOutput]; usingNextFrameForImageCapture = NO;
dispatch_semaphore_signal(imageCaptureSemaphore); CGImageRef image = [framebuffer newCGImageFromFramebufferContents];
return image;
} #pragma mark -
#pragma mark Managing the display FBOs - (CGSize)sizeOfFBO;
{
CGSize outputSize = [self maximumOutputSize];
if ( (CGSizeEqualToSize(outputSize, CGSizeZero)) || (inputTextureSize.width < outputSize.width) )
{
return inputTextureSize;
}
else
{
return outputSize;
}
} #pragma mark -
#pragma mark Rendering + (const GLfloat *)textureCoordinatesForRotation:(GPUImageRotationMode)rotationMode;
{
static const GLfloat noRotationTextureCoordinates[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
}; static const GLfloat rotateLeftTextureCoordinates[] = {
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
}; static const GLfloat rotateRightTextureCoordinates[] = {
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
}; static const GLfloat verticalFlipTextureCoordinates[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
}; static const GLfloat horizontalFlipTextureCoordinates[] = {
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f,
}; static const GLfloat rotateRightVerticalFlipTextureCoordinates[] = {
0.0f, 0.0f,
0.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
}; static const GLfloat rotateRightHorizontalFlipTextureCoordinates[] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
}; static const GLfloat rotate180TextureCoordinates[] = {
1.0f, 1.0f,
0.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
}; switch(rotationMode)
{
case kGPUImageNoRotation: return noRotationTextureCoordinates;
case kGPUImageRotateLeft: return rotateLeftTextureCoordinates;
case kGPUImageRotateRight: return rotateRightTextureCoordinates;
case kGPUImageFlipVertical: return verticalFlipTextureCoordinates;
case kGPUImageFlipHorizonal: return horizontalFlipTextureCoordinates;
case kGPUImageRotateRightFlipVertical: return rotateRightVerticalFlipTextureCoordinates;
case kGPUImageRotateRightFlipHorizontal: return rotateRightHorizontalFlipTextureCoordinates;
case kGPUImageRotate180: return rotate180TextureCoordinates;
}
} - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)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)
{
[outputFramebuffer lock];
} [self setUniformsForProgramAtIndex:]; glClearColor(backgroundColorRed, backgroundColorGreen, backgroundColorBlue, backgroundColorAlpha);
glClear(GL_COLOR_BUFFER_BIT); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, [firstInputFramebuffer texture]); glUniform1i(filterInputTextureUniform, ); glVertexAttribPointer(filterPositionAttribute, , GL_FLOAT, , , vertices);
glVertexAttribPointer(filterTextureCoordinateAttribute, , GL_FLOAT, , , textureCoordinates); glDrawArrays(GL_TRIANGLE_STRIP, , ); [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 it
for (id<GPUImageInput> currentTarget in targets)
{
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 callback
for (id<GPUImageInput> currentTarget in targets)
{
if (currentTarget != self.targetToIgnoreForUpdates)
{
NSInteger indexOfObject = [targets indexOfObject:currentTarget];
NSInteger textureIndex = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];
[currentTarget newFrameReadyAtTime:frameTime atIndex:textureIndex];
}
}
} - (CGSize)outputFrameSize;
{
return inputTextureSize;
} #pragma mark -
#pragma mark 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, , 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, , 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[];
positionArray[] = pointValue.x;
positionArray[] = pointValue.y; glUniform2fv(uniform, , positionArray);
}];
});
} - (void)setSize:(CGSize)sizeValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;
{
runAsynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:shaderProgram]; [self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{
GLfloat sizeArray[];
sizeArray[] = sizeValue.width;
sizeArray[] = sizeValue.height; glUniform2fv(uniform, , sizeArray);
}];
});
} - (void)setVec3:(GPUVector3)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;
{
runAsynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:shaderProgram]; [self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{
glUniform3fv(uniform, , (GLfloat *)&vectorValue);
}];
});
} - (void)setVec4:(GPUVector4)vectorValue forUniform:(GLint)uniform program:(GLProgram *)shaderProgram;
{
runAsynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:shaderProgram]; [self setAndExecuteUniformStateCallbackAtIndex:uniform forProgram:shaderProgram toBlock:^{
glUniform4fv(uniform, , (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 executes
NSData* arrayData = [NSData dataWithBytes:arrayValue length:arrayLength * sizeof(arrayValue[])]; 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();
}];
} #pragma mark -
#pragma mark GPUImageInput - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
{
static const GLfloat imageVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
}; [self renderToTextureWithVertices:imageVertices textureCoordinates:[[self class] textureCoordinatesForRotation:inputRotation]]; [self informTargetsAboutNewFrameAtTime:frameTime];
} - (NSInteger)nextAvailableTextureIndex;
{
return ;
} - (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;
{
firstInputFramebuffer = newInputFramebuffer;
[firstInputFramebuffer lock];
} - (CGSize)rotatedSize:(CGSize)sizeToRotate forIndex:(NSInteger)textureIndex;
{
CGSize rotatedSize = sizeToRotate; if (GPUImageRotationSwapsWidthAndHeight(inputRotation))
{
rotatedSize.width = sizeToRotate.height;
rotatedSize.height = sizeToRotate.width;
} return rotatedSize;
} - (CGPoint)rotatedPoint:(CGPoint)pointToRotate forRotation:(GPUImageRotationMode)rotation;
{
CGPoint rotatedPoint;
switch(rotation)
{
case kGPUImageNoRotation: return pointToRotate; break;
case kGPUImageFlipHorizonal:
{
rotatedPoint.x = 1.0 - pointToRotate.x;
rotatedPoint.y = pointToRotate.y;
}; break;
case kGPUImageFlipVertical:
{
rotatedPoint.x = pointToRotate.x;
rotatedPoint.y = 1.0 - pointToRotate.y;
}; break;
case kGPUImageRotateLeft:
{
rotatedPoint.x = 1.0 - pointToRotate.y;
rotatedPoint.y = pointToRotate.x;
}; break;
case kGPUImageRotateRight:
{
rotatedPoint.x = pointToRotate.y;
rotatedPoint.y = 1.0 - pointToRotate.x;
}; break;
case kGPUImageRotateRightFlipVertical:
{
rotatedPoint.x = pointToRotate.y;
rotatedPoint.y = pointToRotate.x;
}; break;
case kGPUImageRotateRightFlipHorizontal:
{
rotatedPoint.x = 1.0 - pointToRotate.y;
rotatedPoint.y = 1.0 - pointToRotate.x;
}; break;
case kGPUImageRotate180:
{
rotatedPoint.x = 1.0 - pointToRotate.x;
rotatedPoint.y = 1.0 - pointToRotate.y;
}; break;
} return rotatedPoint;
} - (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;
}
else if (!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 better
return CGSizeZero; /*
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> currentTarget in targets)
{
[currentTarget endProcessing];
}
}
} - (BOOL)wantsMonochromeInput;
{
return NO;
} #pragma mark -
#pragma mark Accessors @end

GPUImage API 文档之GPUImageFilter类的更多相关文章

  1. GPUImage API 文档之GPUImageOutput类

    GPUImageOutput类将静态图像纹理上传到OpenGL ES中,然后使用这些纹理去处理进程链中的下一个对象.它的子类可以获得滤镜处理后的图片功能.[本文讲的很少,由于有许多地方不清楚,以后会更 ...

  2. GPUImage API文档之GPUImageContext类

    GPUImageContext类,提供OpenGL ES基本环境,我们一般不会用到,所以讲的很简单. 属性 @property(readonly, nonatomic) dispatch_queue_ ...

  3. GPUImage API文档之GPUImageFramebufferCache类

    GPUImageFramebufferCache类负责管理GPUImageFramebuffer对象,是一个GPUImageFramebuffer对象的缓存. 方法 - (GPUImageFrameb ...

  4. GPUImage API 文档之GPUImagePicture类

    GPUImagePicture类静态图像处理操作,它可以是需要处理的静态图像,也可以是一张作为纹理使用的图片,调用向它发送processImage消息,进行图像滤镜处理. 方法 - (id)initW ...

  5. GPUImage API文档之GPUImageFramebuffer类

    GPUImageFramebuffer类用于管理帧缓冲对象,负责帧缓冲对象的创建和销毁,读取帧缓冲内容 属性 @property(readonly) CGSize size 说明:只读属性,在实现中, ...

  6. GPUImage API文档之GLProgram类

    GLProgram是GPUImage中代表openGL ES 中的program,具有glprogram功能. 属性 @property(readwrite, nonatomic) BOOL init ...

  7. GPUImage API文档之GPUImageInput协议

    GPUImageInput协议主要包含一些输入需要渲染目标的操作. - (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)t ...

  8. 通过API文档查询Math类的方法,打印出近似圆,只要给定不同半径,圆的大小就会随之发生改变

    package question; import java.util.Scanner; import java.lang.Math; public class MathTest { /** * 未搞懂 ...

  9. Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源,BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 各种后台管理系统

    Java,面试题,简历,Linux,大数据,常用开发工具类,API文档,电子书,各种思维导图资源,百度网盘资源BBS论坛系统 ERP管理系统 OA办公自动化管理系统 车辆管理系统 家庭理财系统 各种后 ...

随机推荐

  1. securecrt中文乱码以及ubuntu设置locale

    参考文献 http://wiki.ubuntu.org.cn/%E4%BF%AE%E6%94%B9locale http://www.bootf.com/547.html 强烈建议 ubuntu下面不 ...

  2. InnoDB 与 MYISAM

    http://www.cnblogs.com/sopc-mc/archive/2011/11/01/2232212.html

  3. Linux虚拟主机管理系统---wdcp

    关于WDCP这款虚拟主机管理系统,是疯子使用的第二款Linux虚拟主机管理系统,使用是挺简单的,以前好像是因为编码问题而放弃这款面板. WDCP功能比较完善,基本上需要的功能都能满足,例如:在线下载. ...

  4. The .NET weak event pattern in C#

    Introduction As you may know event handlers are a common source of memory leaks caused by the persis ...

  5. HDU 1075 What Are You Talking About (strings)

    What Are You Talking About Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/204800 K ...

  6. CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视

    一.需求无论何时,当你在Explorer窗口中创建.删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图.有时候我们的程序中也需要这样的功能,以便当用 ...

  7. mysql 筛选重复项(单列或者多列同时重复)

    原文:https://blog.csdn.net/luyaran/article/details/80929026 -------------单列----------------------- SEL ...

  8. ubuntu下安装android sdk运行模拟器出现错误:

    ./emulator: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No ...

  9. QML与C++交互:在qml中使用QSqlQueryModel显示数据库数据

    QML与C++交互:在qml中使用QSqlQueryModel显示数据库数据 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 參考链接: http:// ...

  10. SVG.js 引用获取整理

    一.SVG.get() 根据id获取元素 var draw = SVG('svg1').size(300, 300); var circle = draw.circle(50); circle.fil ...