存档

2010年7月 的存档

How to differentiate between iphone4 and iphone 3

2010年7月20日 没有评论

I am trying to build a game for the iphone using cocos2d engine. I wanted to know how can I tell a difference whether the user is using iphone 4 or iphone 3 as I wanted to load hi-resolution graphics for the iphone4 and low-resolution for iphone 3. I know if I use @2x.png at the end of the image file name UIImage loads the hi-resolution image by itself if I am using an iphone 4 but for the game I am using cocos2d engine’s CCSprite class to load the graphics.

I would really appreciate the reply.

Regards,
Ankur

You could check the scale of the screen.

if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
    //iPhone 4
}

Despite what Apple’s docs say, the UIScreen’s scale property isn’t just available in iOS4, it’s also available in 3.2 on the iPad. This means it’s probably an unreliable way to check which device you’re on.

Instead, you should check if contentScaleFactor is available on your main window(or any UIView), and then check the scale value.

Checking the scale property is not sufficient, as on iPad 3.2 in 2x mode, the scale property exists and will return 2.0, but we know that device does NOT have a Retina display.

I’ve created at category on UIScreen to do this. For a more detailed explanation, see my answer to Detect Retina Display. Here’s the code:

@interface UIScreen(ZBScreenRetinaAdditions)

// Returns YES if this is a Retina display.
- (BOOL)zb_isRetina;

@end

@implementation UIScreen(ZBScreenRetinaAdditions)

- (BOOL)zb_isRetina {
  return [self respondsToSelector:@selector(displayLinkWithTarget:selector:)] && (self.scale == 2.0);
}

@end

Usage example:

if ([UIScreen mainScreen] zb_isRetina) {
  // Retina display
}

just adding my 2 cents :

I see what you are doing here, but binding this to a specific value like 2.0 is good for the moment, but what if for example next iPad got resolution bump like x1.5 ? For me anything that goes above 1.0 is kind of higher-than-normal display so I will load hi-res graphics. Does not matter much then if that is iPad,iPhone ….

- (NSString *) platform  
{  
    size_t size;  
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);  
    char *machine = malloc(size);  
    sysctlbyname("hw.machine", machine, &size, NULL, 0);  
    NSString *platform = [NSString stringWithCString:machine];  
    free(machine);  
    return platform;  
}  

- (NSString *) platformString  
{  
    NSString *platform = [self platform];  
    if ([platform isEqualToString:@"iPhone1,1"]) return @"Original iPhone";  
    if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";  
    if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3G[S]"; 
    if ([platform isEqualToString:@"iPhone3,1"]) return @"iPhone 4";   
    return @"Unknown";  
}  

I know that the topic is a bit old now, but It might help some people.
On Cocos2d you can load hi-resolution graphics for the iphone4 and low-resolution for iphone 3 using the -hd suffix on your files.

You just have to enable the retina display like this before:

// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices
if( ! [director enableRetinaDisplay:YES] )
    CCLOG(@"Retina Display Not supported");

For more information read the documentation here: RetinaDisplay in cocos2d

scale is available for iPad, however you can always use if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) to check whether it is iPad or iPhone/iTouch

import “UIScreen+Retina.h”

if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad){
    //IPAD        
    if ([[UIScreen mainScreen] isRetina]) {
        // IPAD 3 - Retina display
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_HIGHRES;            
    }else{
        //iPAD 1/2
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPAD_LOWRES;        }
}else{
    //IPHONE
    if ([[UIScreen mainScreen] isRetina]) {
        // IPHONE 4/4s/5 - Retina display
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_HIGHRES;

    }else{
        //IPHONE (3.x)
        bannersGetPromoServerRequest.size = kXML_API_IMAGESIZE_IPHONE_LOWRES;

    }
}

For detecting retina display on all devices including the new iPad

    +(BOOL)isRetinaDisplay {
    // since we call this alot, cache it
    static CGFloat scale = 0.0;
    if (scale == 0.0) {
        // NOTE: In order to detect the Retina display reliably on all iOS devices,
        // you need to check if the device is running iOS4+ and if the 
        // [UIScreen mainScreen].scale property is equal to 2.0. 
        // You CANNOT assume a device is running iOS4+ if the scale property exists,
        // as the iPad 3.2 also contains this property.
        // On an iPad running iOS3.2, scale will return 1.0 in 1x mode, and 2.0
        // in 2x mode -- even though we know that device does not contain a Retina display.
        // Apple changed this behavior in iOS4.2 for the iPad: it returns 1.0 in both
        // 1x and 2x modes. You can test this yourself in the simulator.
        // I test for the -displayLinkWithTarget:selector: method on the main screen
        // which exists in iOS4.x but not iOS3.2, and then check the screen's scale:

        if ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && 
            ([UIScreen mainScreen].scale == 2.0)) {
            scale = 2.0;
            return YES;
        } else {
            scale = 1.0;
            return NO;
        }   

    }
    return scale > 1.0;
}

Credit to: Adriano Paladini
http://developer.appcelerator.com/question/133826/detecting-new-ipad-3-dpi-and-retina

分类: cocos2d, stackoverflow精选 标签:

cocos2d scene question – where does init() get called within an app?

2010年7月8日 没有评论

I am totally new to cocos2d and Objective C. I just started studying the HelloWorld example that came with cocos2d package, and just couldn’t figure out where in the application the -init() function within HelloWorldScene.m is getting called.

Here is the tutorial that I was following:
http://www.bit-101.com/blog/?p=2123

Thanks in advance!

jtalarico is correct. I’d like to expand on his answer a bit.

In general, some form of [init] is called by convention whenever an object gets instantiated. For many objects, [init] is all that is needed, but some objects have more complex forms, such as [initWithSomething].

In Cocos2d, the init function is generally called by the [node] method, which is often used to construct an object in Cocos2d. For example, look in CCNode.m, and you will see this code:

+(id) node
{
    return [[[self alloc] init] autorelease];
}

Other objects have other constructors, but this is the main example.

So, if you subclass CCNode, you can override the [init] method and do your own stuff when an object gets created. Just be sure to call [super init] so that CCNode can do its own initialization, too.

The init() method is being overridden in the scene. It is getting called within the base class when an instance of the scene is created. By overriding it, you get the opportunity to fire your own code.

分类: stackoverflow精选, unity3d 标签:

大地形的优化

2010年7月1日 没有评论

                                             D3D之大地形的优化

先放图吧。介绍一下:

1024*1024格子,二百万面,带实时的九层地表纹理混合及法线运算。全网格没有用LOD。

 

大地形的优化

 

网格查看:

 

大地形的优化

 

 

 

                在游戏中,大场景地形往往是一个效率的瓶颈。在这方面。我最近吃了不少苦,研究了不少资料。什么四叉树,LOD,地表纹理混合。等等。

                由最初的雏形至如今的高效地形,由使用LOD到全网格,由GPU的地表高度图采样计算地表纹理到一次性填充所有顶点BUF。每一步都经过反复测试推敲。终于达到能接受的情况。

 

               现在做一下总结:

               1。顶点BUF的优化:千方百计减少顶点格式的大小,最好只缩减为XYZ

               2。充会利用GPU来进行多层纹理混合和阴影计算。如果能利用GPU进行VertexTexture Fetch,最好使用。

               3。对地形的大小进行合理划分。减少Batch与单Batch的内存量此消彼长,要多测试。

               4。不进行LOD的原因是因为使用LOD会导致CPU的工作过大。要想尽一切办法减小CPU工作量。

               5。不对顶点BUF进行逐帧的LOCK,UNLOCK

分类: 未分类 标签: