2011-01-19 61 views
2

我試圖讓XCode openGL ES模板運行時沒有來自界面構建器的xib文件。 但仍然得到這條線[(EAGLView *)self.view setContext:context];的 [UIView的setContext:]:無法識別的選擇發送到實例0x4b1fac0 終止應用程序由於未捕獲的異常「NSInvalidArgumentException」,原因是:「 - [UIView的setContext:]:無法識別的選擇發送到實例0x4b1fac0以編程方式加載UIViewController? (OpenGL ES 2.0)

我在做什麼錯了?

main.mm

int main(int argc, char *argv[]) { 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
    int retVal = UIApplicationMain(argc, argv, nil, @"myAppDelegate"); 
    [pool release]; 
    return retVal; 
} 

myAppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.viewController = [[myViewController alloc] initWithNibName:nil bundle:nil]; 
    self.window.rootViewController = self.viewController; 
    return YES; 
} 

myViewController.m

- (id)initWithNibName:(NSString *)nibName bundle:(NSBundle *)nibBundle 
{ 
    EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
    if (!aContext) { 
     aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 
    } 
    if (!aContext) 
     NSLog(@"Failed to create ES context"); 
    else if (![EAGLContext setCurrentContext:aContext]) 
     NSLog(@"Failed to set ES context current"); 

    self.context = aContext; 
    [aContext release]; 

    [(EAGLView *)self.view setContext:context]; 
    [(EAGLView *)self.view setFramebuffer]; 

    if ([context API] == kEAGLRenderingAPIOpenGLES2) 
     [self loadShaders]; 

    animating = FALSE; 
    animationFrameInterval = 1; 
    self.displayLink = nil; 
    return 0; 
} 

我刪除從我的plist文件默認的廈門國際銀行(以及從廈門國際銀行的文件項目)以及每個IBoutlet。我錯過了什麼?我猜我的appDelegate是錯誤的 - 但無法弄清楚什麼或爲什麼。任何幫助將不勝感激。

回答

6

當然,你似乎是在標準的UIView而不是EAGLView上調用setContext。您的視圖控制器可能應該實施-loadView,做這樣的事情:

這似乎很奇怪
- (void)loadView { 
    self.view = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
} 

的一件事是你與initWithNibName而不是initWithFrame,這正是我所期望的,你需要初始化你的視圖控制器在取消nib/xib文件時要做的事情。

這是我正在做的事情,也許它會有所幫助。我注意到:我有一個自定義視圖控制器,它有一個UIView和一個子視圖,它是EAGLView。(我也在研究添加一個ADBanner子視圖)。我沒有在我的調用'init'控制器,它的視圖當我嘗試將它添加到窗口作爲子視圖時被加載。)

main.m - 類似。

AppDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Create the window programatically: 
    window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 

    controller = [GLViewController alloc]; 
    [window addSubview:controller.view]; 
    glView = [controller.glView retain]; 

    [window makeKeyAndVisible]; 

    return YES; 
} 

ViewController.h:

@interface GLViewController : UIViewController <ADBannerViewDelegate> 
{ 
    EAGLView *glView; 
} 
@property(nonatomic, retain) /*IBOutlet*/ EAGLView *glView; 
@end 

ViewController.m:

- (void)loadView 
{ 
    self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
} 

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    glView = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds]; 
    glView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleBottomMargin; 
    glView.userInteractionEnabled=YES; 
    [self.view addSubview:glView]; 
} 

EAGLView.m:

- (id)initWithFrame:(CGRect)frame 
{ 
    if (self = [super initWithFrame:frame]) 
    { 
     CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;// JPS - WARNING: this does not work on iOS 3.2!!! 

     self.contentScaleFactor = [UIScreen mainScreen].scale; 
     CGSize displaySize = [[UIScreen mainScreen]currentMode].size; 
     CGRect displayRect = [UIScreen mainScreen].bounds; 

     eaglLayer.frame = displayRect; 
     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; 
     } 

     glGenFramebuffersOES(1, &viewFramebuffer); 
     glGenRenderbuffersOES(1, &viewRenderbuffer); 

     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
     [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; 
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); 

     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); 
     glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); 

     glGenRenderbuffersOES(1, &depthRenderbuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); 
     glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); 
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); 

     // Set up thd display link to sync rendering with vblank 
     animating = FALSE; 
     displayLinkSupported = FALSE; 
     animationFrameInterval = 1; 
     displayLink = nil; 
     animationTimer = nil; 

     // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer 
     // class is used as fallback when it isn't available. 
     NSString *reqSysVer = @"3.1"; 
     NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
     if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) 
      displayLinkSupported = TRUE; 
    } 
    return self; 
} 
1

您正在製作的演員(EAGLView*) self.view無法使用。它認爲它是一個UIView(可能是因爲你沒有說在你的self.view = myEAGLView; viewController中的任何地方),並且因爲UIView沒有響應setContext:你會得到錯誤。注意:我對通常使用openGL類不太熟悉,但這似乎是一個更一般的錯誤。