如何在iPhone上调整多个UIImageVIews的Hue?

时间:2010-08-11 15:23:39

标签: iphone graphics opengl-es

我遇到了原本似乎应该是一个非常简单的问题,但是花了很多时间试图找出并且无处可去。

我正在使用Apple的GLImageProcessing示例代码,并将其简化为显示一个带有UISlider的EAGLView,用于调整图像的色调。我已经修改了EAGLView以继承UIImageView,这样我就可以对显示的图像有更多的控制权。这很好用。当我尝试将第二个图像添加到屏幕时出现问题。理想情况下,我想要显示背景图像和其他几个图像,并让色调滑块同时改变所有图像的色调。但是,当我尝试向屏幕添加第二个图像时,第一个图像变成一个普通的黑色视图,当我移动滑块时实际上变成了紫色,但是没有反应。新视图确实按预期运行。如果我要添加第三个,前两个将无效,第三个将正常运行。

我认为我想要做的是拥有一个EAGLView并为新图像添加纹理,但似乎没有任何效果。任何指导我正确方向的帮助将非常感激。谢谢!

来自ViewController.h。用于在viewDidLoad方法中添加新EAGLView子视图的代码。在笔尖中已经加载了另一个视图:

- (void)viewDidLoad
{

     UIImage *img = [UIImage imageNamed:@"Image.png"];
     EAGLView *newView = [[EAGLView alloc] initWithImage:img texID:0];
     self.view2 = newView;
     self.view2.frame = CGRectMake(110, 110, 100, 100);
     [self.view addSubview:self.view2];
     [newView release];

}

一个简单的IBAction就价值变化发起了:

- (void)sliderAction:(id)sender
{
     [self.imageView drawViewWithSliderValue:self.slider.value];
     [self.view2 drawViewWithSliderValue:self.slider.value];
}

从EAGLView.h,这是EAGLView初始化代码和绘图代码。它与示例代码几乎相同,只是它允许您将图像传递到initGL中:

-(id) initializeEAGLwithTexID:(int)texID{
     // Get the layer
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
     eaglLayer.opaque = YES;
     eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [NSNumber numberWithBool:NO], kEAGLDrawablePropertyRetainedBacking,
                                             kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
                                             nil];

     context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];        
     if (!context || ![EAGLContext setCurrentContext:context])
     {
          [self release];
          return nil;
     }

     // Create system framebuffer object. The backing will be allocated in -reshapeFramebuffer
     glGenFramebuffersOES(1, &viewFramebuffer[texID]);
     glGenRenderbuffersOES(1, &viewRenderbuffer[texID]);
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer[texID]);
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer[texID]);
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer[texID]);

     // Perform additional one-time GL initialization
     UIImage *myImage = self.image;
     NSLog(@"holding image of width: %f height %f", myImage.size.width, myImage.size.height);
     CGImageRef imageRef = myImage.CGImage;
     initGL(imageRef, texID);
     return self;
}

-(id) initWithImage:(UIImage *)image texID:(int)texID{
     if((self = [super initWithImage:image])){
          self.opaque = YES;
          self.contentMode = UIViewContentModeScaleToFill;
          [self initializeEAGLwithTexID:texID];

     }
     return self;
}

- (void)drawViewWithSliderValue:(float)value;
{
     drawGL(backingWidth, backingHeight, value, currentID);
     [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}

来自Imaging.c,initGL代码和drawGL。我修改了代码来处理用于处理多个纹理的数组。我相对肯定这里创建的一堆数组是不必要的,但是因为它们没有伤害任何东西,所以还没有尝试删除任何数组:

void initGL(CGImageRef myImage, int currID)
{
     int i;

     // Query renderer capabilities that affect this app's rendering paths
     renderer[currID].extension[APPLE_texture_2D_limited_npot] =
          (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_APPLE_texture_2D_limited_npot"));
     renderer[currID].extension[IMG_texture_format_BGRA8888] =
          (0 != strstr((char *)glGetString(GL_EXTENSIONS), "GL_IMG_texture_format_BGRA8888"));

     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &renderer[currID].maxTextureSize);

     // Constant state for the lifetime of the app-- position and unit0 are always used
     glEnableClientState(GL_VERTEX_ARRAY);
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
     glEnable(GL_TEXTURE_2D);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

     // Load image into texture
     loadTexture(myImage, &Input[currID], &renderer[currID], currID);

     // Modify quad texcoords to match (possibly padded) image
     for (i = 0; i < 4; i++)
     {
          fullquad[i].s *= Input[currID].s;
          fullquad[i].t *= Input[currID].t;
          flipquad[i].s *= Input[currID].s;
          flipquad[i].t *= Input[currID].t;
     }

     // Create 1x1 for default constant texture
     // To enable a texture unit, a valid texture has to be bound even if the combine modes do not access it
     GLubyte half[3][4] = {{ 0x80, 0x80, 0x80, 0x80 },{ 0x80, 0x80, 0x80, 0x80 },{ 0x80, 0x80, 0x80, 0x80 }};
     glActiveTexture(GL_TEXTURE1);


     glGenTextures(1, &Half[currID].texID);
     Half[currID].wide = Half[currID].high = 1;
     Half[currID].s = Half[currID].t = 1.0;
     glBindTexture(GL_TEXTURE_2D, Half[currID].texID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, half[currID]);
     glActiveTexture(GL_TEXTURE0);

     // Remember the FBO being used for the display framebuffer
     glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, (GLint *)&SystemFBO[currID]); 

     // Create scratch textures and FBOs
     glGenTextures(1, &Degen[currID].texID);
     Degen[currID].wide = Input[currID].wide;
     Degen[currID].high = Input[currID].high;
     Degen[currID].s = Input[currID].s;
     Degen[currID].t = Input[currID].t;
     glBindTexture(GL_TEXTURE_2D, Degen[currID].texID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Degen[currID].wide, Degen[currID].high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glGenFramebuffersOES(1, &DegenFBO[currID]);
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO[currID]);
     glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Degen[currID].texID, 0);

     glGenTextures(1, &Scratch[currID].texID);
     Scratch[currID].wide = Input[currID].wide;
     Scratch[currID].high = Input[currID].high;
     Scratch[currID].s = Input[currID].s;
     Scratch[currID].t = Input[currID].t;
     glBindTexture(GL_TEXTURE_2D, Scratch[currID].texID);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Scratch[currID].wide, Scratch[currID].high, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
     glGenFramebuffersOES(1, &ScratchFBO[currID]);
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, ScratchFBO[currID]);
     glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, Scratch[currID].texID, 0);
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO[currID]);
}

void drawGL(int wide, int high, float val, int currID)
{

     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrthof(0, wide, 0, high, -1, 1);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glScalef(wide, high, 1);

     glBindTexture(GL_TEXTURE_2D, Input[currID].texID);

     // Render filtered image to system framebuffer
     glViewport(0, 0, wide, high);

     hue(flipquad, val);

}

1 个答案:

答案 0 :(得分:0)

也许iPhone OS一次只支持一个Open GL视图?