2011-01-19 91 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类不太熟悉,但这似乎是一个更一般的错误。