好不容易找到的Insta的经典滤镜源码,贴出来帮大家学习。
// // IFImageFilter.m // InstaFilters // // Created by Di Wu on 2/28/12. // Copyright (c) 2012 twitter:@diwup. All rights reserved. // #import "IFImageFilter.h" @interface IFImageFilter () { GLint filterPositionAttribute, filterTextureCoordinateAttribute; GLint filterInputTextureUniform, filterInputTextureUniform2, filterInputTextureUniform3, filterInputTextureUniform4, filterInputTextureUniform5, filterInputTextureUniform6; GLuint filterFramebuffer; } @end @implementation IFImageFilter - (id)initWithFragmentShaderFromString:(NSString *)fragmentShaderString; { if (!(self = [super init])) { return nil; } [GPUImageOpenGLESContext useImageProcessingContext]; filterProgram = [[GLProgram alloc] initWithVertexShaderString:kGPUImageVertexShaderString fragmentShaderString:fragmentShaderString]; [filterProgram addAttribute:@"position"]; [filterProgram addAttribute:@"inputTextureCoordinate"]; 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 filterInputTextureUniform2 = [filterProgram uniformIndex:@"inputImageTexture2"]; // This does assume a name of "inputImageTexture2" for second input texture in the fragment shader filterInputTextureUniform3 = [filterProgram uniformIndex:@"inputImageTexture3"]; // This does assume a name of "inputImageTexture3" for second input texture in the fragment shader filterInputTextureUniform4 = [filterProgram uniformIndex:@"inputImageTexture4"]; // This does assume a name of "inputImageTexture4" for second input texture in the fragment shader filterInputTextureUniform5 = [filterProgram uniformIndex:@"inputImageTexture5"]; // This does assume a name of "inputImageTexture5" for second input texture in the fragment shader filterInputTextureUniform6 = [filterProgram uniformIndex:@"inputImageTexture6"]; // This does assume a name of "inputImageTexture6" for second input texture in the fragment shader [filterProgram use]; glEnableVertexAttribArray(filterPositionAttribute); glEnableVertexAttribArray(filterTextureCoordinateAttribute); NSLog(@".0.0.0%@",NSStringFromCGSize(inputTextureSize)); return self; } - (void)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates; { NSLog(@".0.0.0%@",NSStringFromCGSize(inputTextureSize)); [GPUImageOpenGLESContext useImageProcessingContext]; [self setFilterFBO]; [filterProgram use]; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, filterSourceTexture); glUniform1i(filterInputTextureUniform, 2); if (filterSourceTexture2 != 0) { glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, filterSourceTexture2); glUniform1i(filterInputTextureUniform2, 3); } if (filterSourceTexture3 != 0) { glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D, filterSourceTexture3); glUniform1i(filterInputTextureUniform3, 4); } if (filterSourceTexture4 != 0) { glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D, filterSourceTexture4); glUniform1i(filterInputTextureUniform4, 5); } if (filterSourceTexture5 != 0) { glActiveTexture(GL_TEXTURE6); glBindTexture(GL_TEXTURE_2D, filterSourceTexture5); glUniform1i(filterInputTextureUniform5, 6); } if (filterSourceTexture6 != 0) { glActiveTexture(GL_TEXTURE7); glBindTexture(GL_TEXTURE_2D, filterSourceTexture6); glUniform1i(filterInputTextureUniform6, 7); } glVertexAttribPointer(filterPositionAttribute, 2, GL_FLOAT, 0, 0, vertices); glVertexAttribPointer(filterTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, textureCoordinates); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); for (id<GPUImageInput> currentTarget in targets) { [currentTarget setInputSize:inputTextureSize]; [currentTarget newFrameReady]; } } - (void)setFilterFBO; { if (!filterFramebuffer) { [self createFilterFBO]; } glBindFramebuffer(GL_FRAMEBUFFER, filterFramebuffer); CGSize currentFBOSize = [self sizeOfFBO]; glViewport(0, 0, (int)currentFBOSize.width, (int)currentFBOSize.height); } - (void)createFilterFBO; { glActiveTexture(GL_TEXTURE1); glGenFramebuffers(1, &filterFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, filterFramebuffer); NSLog(@".0.0.0%@",NSStringFromCGSize(inputTextureSize)); CGSize currentFBOSize = [self sizeOfFBO]; // NSLog(@"Filter size: %f, %f", currentFBOSize.width, currentFBOSize.height); glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, (int)currentFBOSize.width, (int)currentFBOSize.height); glBindTexture(GL_TEXTURE_2D, outputTexture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)currentFBOSize.width, (int)currentFBOSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, outputTexture, 0); GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); NSAssert(status == GL_FRAMEBUFFER_COMPLETE, @"Incomplete filter FBO: %d", status); } - (CGSize)sizeOfFBO; { CGSize outputSize = [self maximumOutputSize]; if ( (CGSizeEqualToSize(outputSize, CGSizeZero)) || (inputTextureSize.width < outputSize.width) ) { return inputTextureSize; } else { return outputSize; } } - (void)setInputTexture:(GLuint)newInputTexture atIndex:(NSInteger)textureIndex; { if (textureIndex == 0) { filterSourceTexture = newInputTexture; } else if (filterSourceTexture2 == 0) { filterSourceTexture2 = newInputTexture; } else if (filterSourceTexture3 == 0) { filterSourceTexture3 = newInputTexture; } else if (filterSourceTexture4 == 0) { filterSourceTexture4 = newInputTexture; } else if (filterSourceTexture5 == 0) { filterSourceTexture5 = newInputTexture; } else if (filterSourceTexture6 == 0) { filterSourceTexture6 = newInputTexture; } } @end
效果图
百度网盘下载http://pan.baidu.com/s/1c04sFTY
原文:http://www.cnblogs.com/salam/p/4986832.html