EAGLView到UIImage计时问题

时间:2011-08-13 00:18:33

标签: iphone ios uiview opengl-es eaglview

我有一个EAGLView,我希望将其转换为UIImage。我可以使用此处发布的解决方案执行此操作:

How to get UIImage from EAGLView?

但是,如果在创建EAGLView和UIImage之间花费了少量时间,我只能做到这一点。

此代码创建了一个EAGLView,然后是一个UIImageView,它不起作用:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

//I put a glfinish() here but it didn't help

UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
//glToUIImage is taken from the link above

[theWorkArea.photoArea2 addSubview:photoView];

我假设UIImageView尝试在EAGLView创建完成之前创建。我试图在它们之间放一个glfinish(),但它没有做任何事情。当我运行代码时,EAGLView显示正常,但UIImageView显示为黑色。

但是,上述代码的这个修改版本有效:

EAGLView *EAGLphoto = [[EAGLView alloc] initWithImage:photo.workAreaImage];

[theWorkArea.photoArea1 addSubview:EAGLphoto];

[self performSelector:@selector(getUIImage) withObject:nil afterDelay:0.1];

- (void)getUIImage {

    UIImageView *photoView = [[UIImageView alloc] initWithImage:[self glToUIImage]];
    //glToUIImage is taken from the link above

    [theWorkArea.photoArea2 addSubview:photoView];

}

我是否正确使用glfinish()?有没有比我的黑客更好的方法?

1 个答案:

答案 0 :(得分:0)

通常当您对UIKit对象进行可见的更改而不是立即更新时,他们只是标记自己以便将来进行这些更改,然后在您放弃主线程时将整个更改集合作为批处理(通过返回到runloop)。这不是错误或实现中的失败,它实际上通常是你所暗示的,是你可以编写代码的原因:

view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;

并且不用担心在采用其他更改之前,视图通常会明显采用新帧。通常,您希望对视图执行的操作看起来是原子的。

偶尔会遇到一种情况,就像你在这里一样,你已经要求的改变尚未生效的事实已暴露出来。 framesomeOtherProperty会在上面的示例中返回新值,这样您就不会关心更改是否立即生效,而是基于您对performSelector:withObject:afterDelay:的观察你偶然发现了变化并不是假装立刻的情况。

EAGLView难以诊断,因为它不是真正的UIKit功能。它所构建的CAEAGLLayer是,EAGLView只是Apple在各种示例项目中为CAEAGLLayer构建的自定义UIView子类所采用的名称。他们在他们的示例中对EAGLView的接口或实现并不一致,但我猜是可能会创建OpenGL帧缓冲对象(也就是说,OpenGL用来存储数字的东西)与像素相关,只允许glReadPixels工作),只有在被要求自己解决时,它才会自行解决,直到UIKit要求它这样做。直到你退出runloop之后才会这样做。

可以通过查看您拥有的EAGLView的代码来确认诊断。如果glGenFramebufferslayoutSubviews或某些其他方法(由相关的{{1}未直接调用)触发了drawRect之类的内容,则会发出大量调用然后证明了这一点。

假设诊断正确,您可以调整init,但我认为最好的解决方案可能就是坚持EAGLView。这不是一个竞争条件,因此解决方案没有丝毫不稳定或不可靠,只是略微迂回地说“让UIKit赶上所有这些指令,因为我知道这将让EAGLView进入一个有意义的状态,然后继续我的东西“。