Load UIViewController programmatically? (OpenGL ES 2.0)
I tried to get the XCode openGL ES template running without the xib files from interface builder.
But still getting at this line [(EAGLView *)self.view setContext:context];
an
[UIView setContext:]: unrecognized selector sent to instance 0x4b1fac0
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView setContext:]: unrecognized selector sent to instance 0x4b1fac0
What I'm doing wrong?
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;
}
I removed the default xib from my plist file (and the xib files from the project) and also every IBoutlet. Have I missed anything? I'm guessing my appDelegate is wrong something - but can't figure out what or why. Any help would be highly appreciated.
Definitely you seem to be calling setContext on a standard UIView, rather than on an EAGLView. Your view controller should probably implement -loadView, and do something like this:
- (void)loadView {
self.view = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
}
One thing that seems odd is that you're initializing your view controller with initWithNibName rather than initWithFrame, which is what I would expect you need to do when doing away with nib/xib files.
Here's what I'm doing, maybe it will help.
(Note that: I have a custom view controller, which has a UIView and a subview which is the EAGLView. (I'm also working on adding an ADBanner subview). I'm not calling 'init' on my controller, its view gets loaded when I try to add it to the window as a subview.)
main.m - similar.
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;
}
The cast you are making (EAGLView*) self.view
isn't working. It thinks it is a UIView (probably because you don't say anywhere in the viewController that your self.view = myEAGLView;
) and since UIView doesn't respond to setContext:
you are getting the error. Note: i'm not too familiar with using openGL classes in general, but this seems like a more general error.
精彩评论