我有一个希望转换为UIImage的EAGLView。我可以使用这里发布的解决方案做到这一点:
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];我假设在EAGLView创建完成之前,会尝试创建UIImageView。我试着在两者之间放一个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()?有比我的hack更好的方法吗?
发布于 2011-08-14 10:00:50
通常,当您对UIKit对象进行可见更改而不是立即更新时,它们只是将自己标记为在将来进行这些更改,然后在下次您放弃主线程时将整个更改集作为批处理进行(通过返回到运行循环)。这不是实现中的错误或失败,它实际上是您隐含的期望,这是您可以编写如下代码的原因:
view.frame = someNewFrame;
view.someOtherProperty = someOtherValue;不要担心视图会在采用其他更改之前明显地采用新框架。通常,您希望对视图执行的操作看起来是原子的。
有时,您会遇到这样的情况,即您已经请求的更改尚未生效。在上面的示例中,frame和someOtherProperty将返回它们的新值,这样您就不必关心更改是否立即生效,但是根据您对performSelector:withObject:afterDelay:的观察,您很可能偶然发现了一种更改并不是立即生效的情况。
EAGLView很难诊断,因为它不是真正的UIKit特性。构建它的CAEAGLLayer是,但EAGLView只是苹果在各种示例项目中为构建在CAEAGLLayer上的自定义UIView子类采用的名称。在他们的示例中,他们对EAGLView的接口或实现并不一致,但我猜测它可能只在被要求布局时才创建OpenGL帧缓冲区对象(即OpenGL用来存储与像素相关的数字的对象,以允许glReadPixels工作),并且直到UIKit要求它才布局它自己。这是在你退出运行循环之前。
可以通过检查您拥有的EAGLView的代码来确认该诊断。如果有一堆像glGenFramebuffers这样的调用是由layoutSubviews、drawRect或其他方法触发的,而这些方法并不是由相关的init直接调用的,那么这就证明了这一点。
假设诊断是正确的,您可以采用EAGLView,但我认为最好的解决方案可能就是坚持使用performSelector:withObject:afterDelay:0。这不是一个竞争条件,所以这个解决方案一点也不奇怪或不可靠,它只是一种稍微拐弯抹角的方式,意思是“让UIKit赶上所有这些指令,因为我知道这会让EAGLView进入一个有意义的状态,然后继续我的工作”。
https://stackoverflow.com/questions/7047639
复制相似问题