forked from BradLarson/GPUImage
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4312b6b
commit 03122c4
Showing
7 changed files
with
219 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#import "GPUImageElement.h" | ||
#import "GPUImageProgram.h" | ||
#import "GPUImage.h" | ||
#import <UIKit/UIKit.h> | ||
|
||
// A GPUImageFilter is a GPUImage that uses an OpenGL program to transform | ||
// its input image. | ||
|
||
@interface GPUImageFilter : GPUImage | ||
{ | ||
NSMutableArray *programs; | ||
NSMutableArray *outputTextures; | ||
} | ||
|
||
// These property names are conventional. If there are multiple program stages, | ||
// these textures denote the first input and the very last output. | ||
// More complex filters may use additional input and output textures if | ||
// desired; they can also ignore the standard input and output textures | ||
// with no ill effects if they wish. | ||
|
||
@property (strong, nonatomic) GPUImage *inputTexture; | ||
@property (strong, nonatomic) GPUImage *outputTexture; | ||
|
||
// Override to automatically set up a framework for >1 program in series | ||
+ (int) numberOfFilterPrograms; | ||
|
||
// Convenience methods for subclasses | ||
@property (readonly, nonatomic) GPUImageProgram *program; | ||
@property (readonly, nonatomic) GPUImageProgram *programOne; | ||
@property (readonly, nonatomic) GPUImageProgram *programTwo; | ||
@property (readonly, nonatomic) GPUImageProgram *programThree; | ||
|
||
// If you are not using the standard inputTexture, you'll want to override | ||
// render in your subclass to set the proper size of the output texture. | ||
// Then call [super render]. The default implementation sets the size | ||
// from inputTexture if a size has not already been set. | ||
|
||
- (BOOL) render; | ||
|
||
// Called as part of render; override if you don't want std triangulation | ||
|
||
- (void) draw; | ||
|
||
// Still image processing convenience methods | ||
- (UIImage *) imageByFilteringImage:(UIImage *)imageToFilter; | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
#import "GPUImageFilter.h" | ||
#import "GPUImagePicture.h" | ||
|
||
@interface GPUImageFilter | ||
- (GPUImageProgram *) filterProgramAtIndex:(int)n; | ||
@end | ||
|
||
@implementation GPUImageFilter | ||
|
||
@dynamic inputTexture; | ||
|
||
#pragma mark - | ||
#pragma mark Basic setup and utility | ||
|
||
+ (int) numberOfFilterPrograms | ||
{ | ||
return 1; | ||
} | ||
|
||
- (id) init | ||
{ | ||
if (self = [super init]) { | ||
filterPrograms = [NSMutableArray array]; | ||
int nFilters = [[self class] numberOfFilterPrograms]; | ||
GPUImage *texture = nil; | ||
for (int i = 0; i < nFilters; i++) { | ||
GPUImageProgram *newProgram = [GPUImageProgram program]; | ||
if (texture) { | ||
[newProgram setValue:texture forKey:@"inputTexture"]; | ||
} | ||
[filterPrograms addObject:newProgram]; | ||
texture = [GPUImage texture]; | ||
[outputTextures addObject:texture]; | ||
} | ||
[[outputTextures lastObject] deriveFrom:self]; | ||
} | ||
return self; | ||
} | ||
|
||
- (GPUImageProgram *)filterProgram { | ||
return [self filterProgramAtIndex:0]; | ||
} | ||
|
||
- (GPUImageProgram *)filterProgramOne { | ||
return [self filterProgramAtIndex:0]; | ||
} | ||
|
||
- (GPUImageProgram *)filterProgramTwo { | ||
return [self filterProgramAtIndex:1]; | ||
} | ||
|
||
- (GPUImageProgram *)filterProgramThree { | ||
return [self filterProgramAtIndex:2]; | ||
} | ||
|
||
- (GPUImageProgram *)filterProgramAtIndex:(int)n { | ||
return [filterPrograms objectAtIndex:n]; | ||
} | ||
|
||
- (GPUImage *)outputTexture { | ||
return [outputTextures lastObject]; | ||
} | ||
|
||
- (void) setOutputTexture:(GPUImage *)texture | ||
{ | ||
GPUImage *oldOutput = [outputTextures lastObject]; | ||
[outputTextures removeLastObject]; | ||
[oldOutput undoDerivationFrom:self]; | ||
[outputTextures addObject:texture]; | ||
[texture deriveFrom:self]; | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark Rendering and drawing | ||
|
||
- (BOOL) render | ||
{ | ||
// This is called via the update method in GPUImageElement, and is | ||
// ultimately instigated by whoever downstream from us is pulling our | ||
// product textures. By this point, all of our parent objects have been | ||
// made current, so we just need to set up our rendering environment | ||
// and draw. | ||
|
||
for (int i = 0; i < [filterPrograms count]; i++) { | ||
GPUImageProgram *program = [filterPrograms objectAtIndex:i]; | ||
GPUImage *output = [outputTextures objectAtIndex:i]; | ||
if (program.inputTexture) { | ||
[output takeUnknownParametersFrom:program.inputTexture]; | ||
} | ||
if (![program use] || ![output bindAsFramebuffer]) { | ||
return NO; | ||
} | ||
[self draw]; | ||
} | ||
self.timeLastChanged = GPUImageGetCurrentTimestamp(); | ||
return YES; | ||
} | ||
|
||
- (void) draw | ||
{ | ||
static const GLfloat squareVertices[] = { | ||
-1.0, -1.0, | ||
1.0, -1.0, | ||
-1.0, 1.0, | ||
1.0, 1.0, | ||
}; | ||
|
||
static const GLfloat squareTextureCoordinates[] = { | ||
0.0, 0.0, | ||
1.0, 0.0, | ||
0.0, 1.0, | ||
1.0, 1.0, | ||
}; | ||
|
||
// TODO: Work out attrib management | ||
glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, squareVertices); | ||
glVertexAttribPointer(filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, squareTextureCoordinates); | ||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark Still image convenience methods | ||
|
||
- (UIImage *) imageByFilteringImage:(UIImage *)imageToFilter | ||
{ | ||
GPUImagePicture *stillImageSource = [[GPUImagePicture alloc] initWithImage:imageToFilter]; | ||
[self.inputTexture deriveFrom:stillImageSource.outputTexture]; | ||
[self.outputTexture update]; | ||
[self.inputTexture underiveFrom:stillImageSource.outputTexture]; | ||
return [self.outputTexture textureAsUIImage]; | ||
} | ||
|
||
#pragma mark - | ||
#pragma mark Attribute and uniform processing | ||
|
||
// TODO: Handle attribs and uniforms on behalf of program | ||
|
||
@end |