所以我在新iPad(4g)上尝试的第一件事当然是旧的GLGravity示例。我所做的唯一修改是将目标设备设置为"iPad"。
但是,在设备上运行时,UIView的边界设置为7681024,createFramebuffer中的"backingWidth,backingHeight"也是如此。
对图像进行眼珠分析,确认其仍在以768x1024渲染。我错过了什么?如何使其以本机分辨率进行渲染?
要启用对Retina图形的有条件支持,就像我们对iPhone 4所做的那样,您需要在OpenGL ES宿主视图(本例中为GLGravityView)的设置中有一行这样的代码:
self.contentScaleFactor = [[UIScreen mainScreen] scale];
这样可以确保该视图中的内容(如Quartz绘图)以iPhone和iPad上当前Retina显示器中使用的每点2像素缩放进行渲染。
视图的边界将保持在768 x 1024的点大小,但当glGetRenderbufferParameterivOES()
查询时,渲染缓冲区将返回1536 x 2048作为其像素维度。这将允许您在OpenGL ES上下文中渲染Retina级别的图形。
请注意,苹果的一些示例代码(如GLGravity)使用视图边界来调整其他显示元素的大小,因此它们在场景中会显得太小。您可能需要将基于视图边界(以点为单位)的计算替换为背景宽度(以像素为单位),以确保考虑到Retina图形的2.0缩放。
作为对此答案的扩展,GLGravity示例需要进行另一次更改,以确保GL视口设置正确。这是因为bounds
属性返回的是Quartz点,而不是像素。
-(void)setupView
{
...
CGRect rect = self.bounds;
// new code - modify the viewport dimensions.
rect.size.width *= self.contentScaleFactor;
rect.size.height *= self.contentScaleFactor;
// end of new code
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size / (rect.size.width / rect.size.height), zNear, zFar);
glViewport(0, 0, rect.size.width, rect.size.height);
...
}
我也遇到了同样的问题:存在@2x个ipad图像,但所有图像都在新ipad上呈现@1x。iPhone/iPod Touch在视网膜和非视网膜设备上工作正常。搜索苹果开发者论坛,我发现了问题:我仍然使用Xcode 4.2,为iOS 5.0构建。这个操作系统没有预见到视网膜ipad的可能性。所以我需要使用5.1进行构建。
我想我有点明白了。
XIB文件的度量单位是pts,而不是像素。pt是距离的单位,如厘米或光年。像素是而不是距离的单位,它代表"图像元素"。不同的设备可以具有不同的像素密度。
您的XIB文件告诉您的显示区域的大小(以pts为单位)。iPhone应用程序默认为320x480分,iPad 768x1024点。你可以在你的xib文件中查看这个。
现在,Brad所指的self.contentScaleFactor
就是答案。该值的作用是:"从默认逻辑坐标空间(768x1024pts)转换到此屏幕的设备坐标空间(1536x2048px
换句话说,self.contentScaleFactor
是设备使用的像素/pt的度量。该值随设备的不同而自然变化。XCode让您在pts(现实世界距离的单位)中指定UI元素,这样在不同的分辨率下就不会出现问题。
您甚至可以设置self.contentScaleFactor=4
,它实际上看起来有点酷(它超级采样)(但运行速度可能很慢)。
这里的另一个问题是触摸事件将始终以pts为单位,而不是以像素为单位。也就是说,视网膜设备仍然只能在768x1024的范围内解决触摸事件。
因此,如果视图支持触摸拾取,则需要将每个传入触摸事件乘以self.contentScaleFactor
,以便pts中的传入位置映射到帧缓冲区中的像素。