这是我的代码.一个名为IFFourinputFilter的基类,很可能是GPUImageTwoinputFilter.
#import "IFFourinputFilter.h"Nsstring *const kIFFourinputTextureVertexShaderString = SHADER_STRING( attribute vec4 position; attribute vec4 inputTextureCoordinate; attribute vec4 inputTextureCoordinate2; attribute vec4 inputTextureCoordinate3; attribute vec4 inputTextureCoordinate4; varying vec2 textureCoordinate; varying vec2 textureCoordinate2; varying vec2 textureCoordinate3; varying vec2 textureCoordinate4; voID main() { gl_position = position; textureCoordinate = inputTextureCoordinate.xy; textureCoordinate2 = inputTextureCoordinate2.xy; textureCoordinate3 = inputTextureCoordinate3.xy; textureCoordinate4 = inputTextureCoordinate4.xy; });@implementation IFFourinputFilter#pragma mark -#pragma mark Initialization and teardown- (ID)initWithFragmentShaderFromString:(Nsstring *)fragmentShaderString;{ if (!(self = [self initWithVertexShaderFromString:kIFFourinputTextureVertexShaderString fragmentShaderFromString:fragmentShaderString])) { return nil; } return self;}- (ID)initWithVertexShaderFromString:(Nsstring *)vertexShaderString fragmentShaderFromString:(Nsstring *)fragmentShaderString;{ if (!(self = [super initWithVertexShaderFromString:vertexShaderString fragmentShaderFromString:fragmentShaderString])) { return nil; } inputRotation2 = kGPUImagenorotation; inputRotation3 = kGPUImagenorotation; inputRotation4 = kGPUImagenorotation; hasSetTexture1 = NO; hasSetTexture2 = NO; hasSetTexture3 = NO; hasReceivedFrame1 = NO; hasReceivedFrame2 = NO; hasReceivedFrame3 = NO; hasReceivedFrame4 = NO; frameWasVIDeo1 = NO; frameWasVIDeo2 = NO; frameWasVIDeo3 = NO; frameWasVIDeo4 = NO; frameCheckDisabled1 = NO; frameCheckDisabled2 = NO; frameCheckDisabled3 = NO; frameCheckDisabled4 = NO; frameTime1 = kCMTimeInvalID; frameTime2 = kCMTimeInvalID; frameTime3 = kCMTimeInvalID; frameTime4 = kCMTimeInvalID; runSynchronouslyOnVIDeoProcessingQueue(^{ [GPUImageOpenGLESContext useImageProcessingContext]; filterTextureCoordinateAttribute2 = [filterProgram attributeIndex:@"inputTextureCoordinate2"]; filterinputTextureUniform2 = [filterProgram uniformIndex:@"inputimageTexture2"]; // This does assume a name of "inputimageTexture2" for second input texture in the fragment shader glEnabLevertexAttribarray(filterTextureCoordinateAttribute2); filterTextureCoordinateAttribute3 = [filterProgram attributeIndex:@"inputTextureCoordinate3"]; filterinputTextureUniform3 = [filterProgram uniformIndex:@"inputimageTexture3"]; // This does assume a name of "inputimageTexture2" for second input texture in the fragment shader glEnabLevertexAttribarray(filterTextureCoordinateAttribute3); filterTextureCoordinateAttribute4 = [filterProgram attributeIndex:@"inputTextureCoordinate4"]; filterinputTextureUniform4 = [filterProgram uniformIndex:@"inputimageTexture4"]; // This does assume a name of "inputimageTexture2" for second input texture in the fragment shader glEnabLevertexAttribarray(filterTextureCoordinateAttribute4); }); return self;}- (voID)initializeAttributes;{ [super initializeAttributes]; [filterProgram addAttribute:@"inputTextureCoordinate2"]; [filterProgram addAttribute:@"inputTextureCoordinate3"]; [filterProgram addAttribute:@"inputTextureCoordinate4"];}- (voID)disableFrameCheck1;{ frameCheckDisabled1 = YES;}- (voID)disableFrameCheck2;{ frameCheckDisabled2 = YES;}- (voID)disableFrameCheck3;{ frameCheckDisabled3 = YES;}- (voID)disableFrameCheck4;{ frameCheckDisabled4 = YES;}#pragma mark -#pragma mark Rendering- (voID)renderToTextureWithVertices:(const GLfloat *)vertices textureCoordinates:(const GLfloat *)textureCoordinates sourceTexture:(gluint)sourceTexture;{ if (self.preventRendering) { return; } [GPUImageOpenGLESContext setActiveShaderProgram:filterProgram]; [self setUniformsForProgramAtIndex:0]; [self setFilterFBO]; glClearcolor(backgroundcolorRed,backgroundcolorGreen,backgroundcolorBlue,backgroundcolorAlpha); glClear(GL_color_BUFFER_BIT); glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D,sourceTexture); gluniform1i(filterinputTextureUniform,2); glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D,filterSourceTexture2); gluniform1i(filterinputTextureUniform2,3); glActiveTexture(GL_TEXTURE4); glBindTexture(GL_TEXTURE_2D,filterSourceTexture3); gluniform1i(filterinputTextureUniform3,4); glActiveTexture(GL_TEXTURE5); glBindTexture(GL_TEXTURE_2D,filterSourceTexture4); gluniform1i(filterinputTextureUniform4,5); glVertexAttribPointer(filterpositionAttribute,2,GL_float,vertices); glVertexAttribPointer(filterTextureCoordinateAttribute,textureCoordinates); glVertexAttribPointer(filterTextureCoordinateAttribute2,[[self class] textureCoordinatesForRotation:inputRotation2]); glVertexAttribPointer(filterTextureCoordinateAttribute3,[[self class] textureCoordinatesForRotation:inputRotation3]); glVertexAttribPointer(filterTextureCoordinateAttribute4,[[self class] textureCoordinatesForRotation:inputRotation4]); glDrawArrays(GL_TRIANGLE_STRIP,4);}- (voID)releaseinputTexturesIfNeeded;{ if (shouldConserveMemoryForNextFrame) { [firstTextureDelegate textureNolongerNeededForTarget:self]; [textureDelegate2 textureNolongerNeededForTarget:self]; [textureDelegate3 textureNolongerNeededForTarget:self]; [textureDelegate4 textureNolongerNeededForTarget:self]; shouldConserveMemoryForNextFrame = NO; }}#pragma mark -#pragma mark GPUImageinput- (NSInteger)nextAvailableTextureIndex;{ if (!hasSetTexture1){ return 0; }else if (!hasSetTexture2) { return 1; }else if (!hasSetTexture3) { return 2; }else{ return 3; }}- (voID)setinputTexture:(gluint)newinputTexture atIndex:(NSInteger)textureIndex;{ switch (textureIndex) { case 0: filterSourceTexture = newinputTexture; hasSetTexture1 = YES; break; case 1: filterSourceTexture2 = newinputTexture; hasSetTexture2 = YES; break; case 2: filterSourceTexture3 = newinputTexture; hasSetTexture3 = YES; break; case 3: filterSourceTexture4 = newinputTexture; break; default: break; }}- (voID)setinputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;{ if (textureIndex == 0) { [super setinputSize:newSize atIndex:textureIndex]; if (CGSizeEqualToSize(newSize,CGSizeZero)) { hasSetTexture1 = NO; } }}- (voID)setinputRotation:(GPUImageRotationMode)newinputRotation atIndex:(NSInteger)textureIndex;{ switch (textureIndex) { case 0: inputRotation = newinputRotation; break; case 1: inputRotation2 = newinputRotation; break; case 2: inputRotation3 = newinputRotation; break; case 3: inputRotation4 = newinputRotation; break; default: break; }}- (CGSize)rotatedSize:(CGSize)sizetoRotate forIndex:(NSInteger)textureIndex;{ CGSize rotatedSize = sizetoRotate; GPUImageRotationMode rotationtocheck; switch (textureIndex) { case 0: rotationtocheck = inputRotation; break; case 1: rotationtocheck = inputRotation2; break; case 2: rotationtocheck = inputRotation3; break; case 3: rotationtocheck = inputRotation4; break; default: break; } if (GPUImageRotationSwapsWIDthAndHeight(rotationtocheck)) { rotatedSize.wIDth = sizetoRotate.height; rotatedSize.height = sizetoRotate.wIDth; } return rotatedSize;}- (voID)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;{ outputTextureRetainCount = [targets count]; // You can set up infinite update loops,so this helps to short circuit them if (hasReceivedFrame1 && hasReceivedFrame2 && hasReceivedFrame3 && hasReceivedFrame4) { return; } BOol updatedMovIEFrameOppositeStillimage = NO; switch (textureIndex) { case 0: hasReceivedFrame1 = YES; frameTime1 = frameTime; if (frameCheckDisabled2) { hasReceivedFrame2 = YES; } if (frameCheckDisabled3) { hasReceivedFrame3 = YES; } if (frameCheckDisabled4) { hasReceivedFrame4 = YES; } if (!CMTIME_IS_INDEFINITE(frameTime)) { if (CMTIME_IS_INDEFINITE(frameTime2) && CMTIME_IS_INDEFINITE(frameTime3) && CMTIME_IS_INDEFINITE(frameTime4)) { updatedMovIEFrameOppositeStillimage = YES; } } break; case 1: hasReceivedFrame2 = YES; frameTime2 = frameTime; if (frameCheckDisabled1) { hasReceivedFrame1 = YES; } if (frameCheckDisabled3) { hasReceivedFrame3 = YES; } if (frameCheckDisabled4) { hasReceivedFrame4 = YES; } if (!CMTIME_IS_INDEFINITE(frameTime)) { if (CMTIME_IS_INDEFINITE(frameTime1) && CMTIME_IS_INDEFINITE(frameTime3) && CMTIME_IS_INDEFINITE(frameTime4)) { updatedMovIEFrameOppositeStillimage = YES; } } break; case 2: hasReceivedFrame3 = YES; frameTime3 = frameTime; if (frameCheckDisabled1) { hasReceivedFrame1 = YES; } if (frameCheckDisabled2) { hasReceivedFrame2 = YES; } if (frameCheckDisabled4) { hasReceivedFrame4 = YES; } if (!CMTIME_IS_INDEFINITE(frameTime)) { if (CMTIME_IS_INDEFINITE(frameTime1) && CMTIME_IS_INDEFINITE(frameTime2) && CMTIME_IS_INDEFINITE(frameTime4)) { updatedMovIEFrameOppositeStillimage = YES; } } break; case 3: hasReceivedFrame4 = YES; frameTime4 = frameTime; if (frameCheckDisabled1) { hasReceivedFrame1 = YES; } if (frameCheckDisabled3) { hasReceivedFrame3 = YES; } if (frameCheckDisabled2) { hasReceivedFrame2 = YES; } if (!CMTIME_IS_INDEFINITE(frameTime)) { if (CMTIME_IS_INDEFINITE(frameTime1) && CMTIME_IS_INDEFINITE(frameTime3) && CMTIME_IS_INDEFINITE(frameTime2)) { updatedMovIEFrameOppositeStillimage = YES; } } break; default: break; } // || (hasReceivedFirstFrame && secondFrameCheckDisabled) || (hasReceivedSecondFrame && firstFrameCheckDisabled) if ((hasReceivedFrame1 && hasReceivedFrame2 && hasReceivedFrame3 && hasReceivedFrame4) || updatedMovIEFrameOppositeStillimage) { [super newFrameReadyAtTime:frameTime atIndex:0]; hasReceivedFrame1 = NO; hasReceivedFrame2 = NO; hasReceivedFrame3 = NO; hasReceivedFrame4 = NO; }}- (voID)setTextureDelegate:(ID<GPUImageTextureDelegate>)newTextureDelegate atIndex:(NSInteger)textureIndex;{ switch (textureIndex) { case 0: firstTextureDelegate = newTextureDelegate; break; case 1: textureDelegate2 = newTextureDelegate; break; case 2: textureDelegate3 = newTextureDelegate; break; case 3: textureDelegate4 = newTextureDelegate; break; default: break; }}@end
名为IFAmaroFilter的类扩展了IFFourinputFilter.
#import "IFAmaroFilter.h"Nsstring *const kIFAmaroFilterFragmentShaderString = SHADER_STRING( precision lowp float; varying highp vec2 textureCoordinate; uniform sampler2D inputimageTexture; uniform sampler2D inputimageTexture2; //blowout; uniform sampler2D inputimageTexture3; //overlay; uniform sampler2D inputimageTexture4; //map voID main() { vec4 texel = texture2D(inputimageTexture,textureCoordinate); vec3 bbTexel = texture2D(inputimageTexture2,textureCoordinate).rgb; texel.r = texture2D(inputimageTexture3,vec2(bbTexel.r,texel.r)).r; texel.g = texture2D(inputimageTexture3,vec2(bbTexel.g,texel.g)).g; texel.b = texture2D(inputimageTexture3,vec2(bbTexel.b,texel.b)).b; vec4 mapped; mapped.r = texture2D(inputimageTexture4,vec2(texel.r,0.16666)).r; mapped.g = texture2D(inputimageTexture4,vec2(texel.g,.5)).g; mapped.b = texture2D(inputimageTexture4,vec2(texel.b,.83333)).b; mapped.a = 1.0; gl_Fragcolor = texel; } );@implementation IFAmaroFilter- (ID)init;{ if (!(self = [super initWithFragmentShaderFromString:kIFAmaroFilterFragmentShaderString])) { return nil; } return self;}@end
当我使用滤镜时,我得到了黑色输出.代码如下:
filter = [[IFAmaroFilter alloc] init]; GPUImagePicture *gp1 = [[GPUImagePicture alloc] initWithImage:[UIImage imageWithContentsOffile:[[NSBundle mainBundle] pathForResource:@"blackboard1024" ofType:@"png"]]]; GPUImagePicture *gp2 = [[GPUImagePicture alloc] initWithImage:[UIImage imageWithContentsOffile:[[NSBundle mainBundle] pathForResource:@"overlayMap" ofType:@"png"]]]; GPUImagePicture *gp3 = [[GPUImagePicture alloc] initWithImage:[UIImage imageWithContentsOffile:[[NSBundle mainBundle] pathForResource:@"amaroMap" ofType:@"png"]]]; [stillCamera addTarget:filter atTextureLocation:0]; [gp1 addTarget:filter atTextureLocation:1]; [gp1 processImage]; [gp2 addTarget:filter atTextureLocation:2]; [gp2 processImage]; [gp3 addTarget:filter atTextureLocation:3]; [gp3 processImage]; [filter addTarget:(GPUImageVIEw *)self.vIEw];解决方法 我发现GPUImagePicture会自动释放,因此过滤器不会接收纹理. 如果您遇到同样的问题,请仔细检查纹理的生命控制,观察它们何时被取消. 总结
以上是内存溢出为你收集整理的ios – 我想用GPUImage制作一个以上的输入纹理滤镜.但我得到了黑色输出全部内容,希望文章能够帮你解决ios – 我想用GPUImage制作一个以上的输入纹理滤镜.但我得到了黑色输出所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)