#import "GPUImageCrosshairGenerator.h" NSString *const kGPUImageCrosshairVertexShaderString = SHADER_STRING ( attribute vec4 position; uniform float crosshairWidth; varying vec2 centerLocation; varying float pointSpacing; void main() { gl_Position = vec4(((position.xy * 2.0) - 1.0), 0.0, 1.0); gl_PointSize = crosshairWidth + 1.0; pointSpacing = 1.0 / crosshairWidth; centerLocation = vec2(pointSpacing * ceil(crosshairWidth / 2.0), pointSpacing * ceil(crosshairWidth / 2.0)); } ); #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE NSString *const kGPUImageCrosshairFragmentShaderString = SHADER_STRING ( uniform lowp vec3 crosshairColor; varying highp vec2 centerLocation; varying highp float pointSpacing; void main() { lowp vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy); lowp float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09); gl_FragColor = vec4(crosshairColor * axisTest, axisTest); // gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0); } ); #else NSString *const kGPUImageCrosshairFragmentShaderString = SHADER_STRING ( GPUImageEscapedHashIdentifier(version 120)\n uniform vec3 crosshairColor; varying vec2 centerLocation; varying float pointSpacing; void main() { vec2 distanceFromCenter = abs(centerLocation - gl_PointCoord.xy); float axisTest = step(pointSpacing, gl_PointCoord.y) * step(distanceFromCenter.x, 0.09) + step(pointSpacing, gl_PointCoord.x) * step(distanceFromCenter.y, 0.09); gl_FragColor = vec4(crosshairColor * axisTest, axisTest); // gl_FragColor = vec4(distanceFromCenterInX, distanceFromCenterInY, 0.0, 1.0); } ); #endif @implementation GPUImageCrosshairGenerator @synthesize crosshairWidth = _crosshairWidth; #pragma mark - #pragma mark Initialization and teardown - (id)init; { if (!(self = [super initWithVertexShaderFromString:kGPUImageCrosshairVertexShaderString fragmentShaderFromString:kGPUImageCrosshairFragmentShaderString])) { return nil; } runSynchronouslyOnVideoProcessingQueue(^{ crosshairWidthUniform = [filterProgram uniformIndex:@"crosshairWidth"]; crosshairColorUniform = [filterProgram uniformIndex:@"crosshairColor"]; self.crosshairWidth = 5.0; [self setCrosshairColorRed:0.0 green:1.0 blue:0.0]; }); return self; } #pragma mark - #pragma mark Rendering - (void)renderCrosshairsFromArray:(GLfloat *)crosshairCoordinates count:(NSUInteger)numberOfCrosshairs frameTime:(CMTime)frameTime; { if (self.preventRendering) { return; } runSynchronouslyOnVideoProcessingQueue(^{ [GPUImageContext setActiveShaderProgram:filterProgram]; #if TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE #else glEnable(GL_POINT_SPRITE); glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); #endif outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:[self sizeOfFBO] textureOptions:self.outputTextureOptions onlyTexture:NO]; [outputFramebuffer activateFramebuffer]; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, crosshairCoordinates); glDrawArrays(GL_POINTS, 0, (GLsizei)numberOfCrosshairs); [self informTargetsAboutNewFrameAtTime:frameTime]; }); } - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates; { // Prevent rendering of the frame by normal means } #pragma mark - #pragma mark Accessors - (void)setCrosshairWidth:(CGFloat)newValue; { _crosshairWidth = newValue; [self setFloat:_crosshairWidth forUniform:crosshairWidthUniform program:filterProgram]; } - (void)setCrosshairColorRed:(GLfloat)redComponent green:(GLfloat)greenComponent blue:(GLfloat)blueComponent; { GPUVector3 crosshairColor = {redComponent, greenComponent, blueComponent}; [self setVec3:crosshairColor forUniform:crosshairColorUniform program:filterProgram]; } @end