2

我试图让 XCode openGL ES 模板在没有来自界面生成器的 xib 文件的情况下运行。但仍然在这一行得到[(EAGLView *)self.view setContext:context];一个 [UIView setContext:]: unrecognized selector sent to instance 0x4b1fac0 Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setContext:]: unrecognized selector sent to instance 0x4b1fac0

我做错了什么?

主要.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;
}

我的视图控制器.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 文件(以及项目中的 xib 文件)以及每个 IBoutlet 中删除了默认的 xib。我错过了什么吗?我猜我的 appDelegate 出了点问题 - 但不知道是什么或为什么。任何帮助将不胜感激。

4

2 回答 2

6

当然,您似乎是在标准 UIView 上调用 setContext,而不是在 EAGLView 上。您的视图控制器可能应该实现 -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;
}

视图控制器.h:

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

视图控制器.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;
}
于 2011-01-20T01:23:19.530 回答
1

你正在制作的演员阵容(EAGLView*) self.view不起作用。它认为它是一个 UIView (可能是因为你没有在 viewController 的任何地方说你的self.view = myEAGLView;),并且由于 UIView 没有响应setContext:你得到错误。注意:我一般不太熟悉使用 openGL 类,但这似乎是一个更普遍的错误。

于 2011-01-19T23:12:00.963 回答