I am making use of Brad Larson's wonderful GPUImage library for image manipulation. Thank you Brad, great work.
I am trying to add a new filter that will allow for objects to be drawn over a live video source.
This is early stages. At this point, I am just trying to draw 3 triangles over the video source. Code follows.
It seems to be working but I get an intermittent change in aspect ratio while this effect is applied. and then it settles down. The filterView is stretched vertically. looks like a strobe.
HEADER:
// GPUImageParticles.h
#import <GLKit/GLKit.h>
#import "GPUImageFilter.h"
@interface GPUImageParticles : GPUImageFilter{
GLint triVertexBufferIDUniform;
GLuint triVertexBufferID;
}
- (void)update:(CMTime)frameTime;
- (void)setDrawColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
@end
IMPLEMENTATION:
// GPUImageParticles.m
#import "GPUImageParticles.h"
// SHADERS
NSString *const kParticleGenVSString = SHADER_STRING
(
attribute vec4 position;
void main()
{
gl_Position = position;
}
);
NSString *const kParticleGenFSString = SHADER_STRING
(
uniform lowp vec3 drawColor;
void main()
{
gl_FragColor = vec4(drawColor, 1.0);
}
);
// END SHADERS
@implementation GPUImageParticles
/////////////////////////////////////////////////////////////////
// This data type is used to store information for each vertex
typedef struct {
GPUVector3 positionCoords;
}
SceneVertex;
/////////////////////////////////////////////////////////////////
// Define vertex data for a triangle to use in example
static const SceneVertex triVertices[] =
{
{{0.0f, 0.0f, 0.0f}},
{{0.0f, 0.1f, 0.0f}},
{{0.1f, 0.1f, 0.0f}},
{{-0.3f, -0.7f, 0.0}}, // lower left corner
{{ 0.3f, -0.7f, 0.0}}, // lower right corner
{{ 0.01f, 0.5f, 0.0}}, // upper left corner
{{-0.5f, -0.5f, 0.0}}, // lower left corner
{{-0.25f, -0.25f, 0.0}}, // lower right corner
{{-0.5f, -0.25f, 0.0}} // upper left corner
};
- (id)init;
{
if (!(self = [super initWithVertexShaderFromString:kParticleGenVSString fragmentShaderFromString:kParticleGenFSString]))
{
return nil;
}
runSynchronouslyOnVideoProcessingQueue(^{
triVertexBufferIDUniform =[filterProgram uniformIndex:@"triVertexBuffer"];
drawColorUniform = [filterProgram uniformIndex:@"drawColor"];
[self setDrawColorRed:1.0 green:0.0 blue:1.0];
glGenBuffers(1, // STEP 1
&triVertexBufferID);
glBindBuffer(GL_ARRAY_BUFFER, // STEP 2
triVertexBufferID);
glBufferData( // STEP 3
GL_ARRAY_BUFFER, // Initialize buffer contents
sizeof(triVertices), // Number of bytes to copy
triVertices, // Address of bytes to copy
GL_STATIC_DRAW); // Hint: cache in GPU memory
glBindBuffer(GL_ARRAY_BUFFER, 0);
});
return self;
}
- (void) dealloc;
{
}
-(void)update:(CMTime)frameTime;
{
if (self.preventRendering)
{
return;
}
runSynchronouslyOnVideoProcessingQueue(^{
[GPUImageContext setActiveShaderProgram:filterProgram];
[self setFilterFBO];
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBlendEquation(GL_FUNC_ADD);
glBlendFunc(GL_ONE, GL_ONE);
glEnable(GL_BLEND);
glVertexAttribPointer(filterPositionAttribute, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), triVertices);
glDrawArrays(GL_TRIANGLES, 0, (unsigned int)9);
glDisable(GL_BLEND);
[self informTargetsAboutNewFrameAtTime:frameTime];
});
}
- (void)setDrawColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent;
{
GPUVector3 drawColor = {redComponent, greenComponent, blueComponent};
[self setVec3:drawColor forUniform:drawColorUniform program:filterProgram];
}
@end
Reference the GPUIMAGE_NOBLECORNERDETECTION example included in the FilterShowcase example provided by Brad Larson.
GPUImageCrosshairGenerator *crosshairGenerator = [[GPUImageCrosshairGenerator alloc] init];
crosshairGenerator.crosshairWidth = 15.0;
[crosshairGenerator forceProcessingAtSize:CGSizeMake(480.0, 640.0)];
[(GPUImageHarrisCornerDetectionFilter *)filter setCornersDetectedBlock:^(GLfloat* cornerArray, NSUInteger cornersDetected, CMTime frameTime) {
[crosshairGenerator renderCrosshairsFromArray:cornerArray count:cornersDetected frameTime:frameTime];
}];
GPUImageAlphaBlendFilter *blendFilter = [[GPUImageAlphaBlendFilter alloc] init];
[blendFilter forceProcessingAtSize:CGSizeMake(480.0, 640.0)];
GPUImageGammaFilter *gammaFilter = [[GPUImageGammaFilter alloc] init];
[videoCamera addTarget:gammaFilter];
[gammaFilter addTarget:blendFilter];
[crosshairGenerator addTarget:blendFilter];
[blendFilter addTarget:filterView];