我试图将我的nib文件中的视图之一用作GLView
。
在我的iphoneDisplay.nib
文件中,我将一个视图设置为GLView
的自定义类(底部的代码),并在我的应用程序委托中设置了出口。我将View设置为黑色背景,NSLogs显示它是从GLView
和我的GLViewController
绘制的,但是我什么也看不到:/。有人知道我在做什么错吗?
我的应用程式代表:
#import "HBAppDelegate.h"
#import "GLViewController.h"
#import "GLView.h"
#import "TestFlight.h"
@implementation HBAppDelegate
@synthesize window=_window;
@synthesize viewController=_controller;
@synthesize glViewFromNib;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[GLViewController alloc] initWithNibName:@"iPhoneDisplay" bundle:nil];
self.window.rootViewController = self.viewController;
glViewFromNib = [[GLView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
glViewFromNib.controller = self.window.rootViewController;
glViewFromNib.animationInterval = 1.0 / kRenderingFrequency;
[glViewFromNib startAnimation];
[glViewFromNib setUserInteractionEnabled:false];
[self.window makeKeyAndVisible];
return YES;
}
@end
我的
GLView
(来自Jeff LaMarche的样板代码)://
// GLView.m
// Part6Project
//
// Created by jeff on 5/31/09.
// Copyright Jeff LaMarche 2009. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import <OpenGLES/EAGLDrawable.h>
#import "GLView.h"
#import "GLViewController.h"
@interface GLView (private)
- (id)initGLES;
- (BOOL)createFramebuffer;
- (void)destroyFramebuffer;
@end
@implementation GLView
@synthesize animationInterval;
+ (Class) layerClass
{
return [CAEAGLLayer class];
}
-(id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if(self != nil)
{
NSLog(@"init with frame");
self = [self initGLES];
}
return self;
}
- (id)initWithCoder:(NSCoder*)coder
{
if((self = [super initWithCoder:coder]))
{
self = [self initGLES];
}
return self;
}
-(id)initGLES
{
NSLog(@"init GLES");
CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
if ([self respondsToSelector:@selector(contentScaleFactor)])
{
self.contentScaleFactor = [[UIScreen mainScreen] scale];
// scale value should be 1.0 on 3G and 3GS, and 2.0 on iPhone 4.
self.contentMode = UIViewContentModeScaleToFill;
}
// Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color.
eaglLayer.opaque = YES;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
nil];
// Create our EAGLContext, and if successful make it current and create our framebuffer.
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer])
{
[self release];
return nil;
}
// Default the animation interval to 1/60th of a second.
animationInterval = 1.0 / kRenderingFrequency;
return self;
}
-(GLViewController *)controller
{
return controller;
}
-(void)setController:(GLViewController *)d
{
controller = d;
controllerSetup = ![controller respondsToSelector:@selector(setupView:)];
}
// If our view is resized, we'll be asked to layout subviews.
// This is the perfect opportunity to also update the framebuffer so that it is
// the same size as our display area.
-(void)layoutSubviews
{
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
}
- (BOOL)createFramebuffer
{
NSLog(@"about to make FB");
// Generate IDs for a framebuffer object and a color renderbuffer
glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
// This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
// allowing us to draw into a buffer that will later be rendered to screen whereever the layer is (which corresponds with our view).
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)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);
// For this sample, we also need a depth buffer, so we'll create and attach one via another renderbuffer.
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);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
{
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
// Clean up any buffers we have allocated.
- (void)destroyFramebuffer
{
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
if(depthRenderbuffer)
{
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
- (void)startAnimation
{
animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
NSLog(@"starting animation");
}
- (void)stopAnimation
{
[animationTimer invalidate];
animationTimer = nil;
NSLog(@"stopping animation");
}
- (void)setAnimationInterval:(NSTimeInterval)interval
{
animationInterval = interval;
if(animationTimer)
{
[self stopAnimation];
[self startAnimation];
}
}
// Updates the OpenGL view when the timer fires
- (void)drawView
{
NSLog(@"draw");
// Make sure that you are drawing to the current context
[EAGLContext setCurrentContext:context];
// If our drawing delegate needs to have the view setup, then call -setupView: and flag that it won't need to be called again.
if(!controllerSetup)
{
[controller setupView:self];
controllerSetup = YES;
}
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
[controller drawView:self];
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
GLenum err = glGetError();
if(err)
NSLog(@"%x error", err);
}
// Stop animating and release resources when they are no longer needed.
- (void)dealloc
{
[self stopAnimation];
if([EAGLContext currentContext] == context)
{
[EAGLContext setCurrentContext:nil];
}
[context release];
context = nil;
[super dealloc];
}
@end
最佳答案
这是我认为您的代码正在运行的方式
self.viewController = [[GLViewController alloc] initWithNibName:@"iPhoneDisplay" bundle:nil]";
这将读取视图控制器并实例化(或按需计划实例化(不确定),以实例化)您在NIB文件中定义的GLView。
self.window.rootViewController = self.viewController;
执行,这时将您在NIB文件中定义的
GLView
添加到视图层次结构中。然后,创建一个全新的GLView,该视图永远不会添加到视图层次结构中,然后将该视图设置为动画。glViewFromNib = [[GLView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
glViewFromNib.controller = self.window.rootViewController;
glViewFromNib.animationInterval = 1.0 / kRenderingFrequency;
[glViewFromNib startAnimation];
您可能应该使用
IBOutlet
来获取随NIB一起加载的GLView
的句柄,然后开始进行动画处理。 (或者,如果要在代码中创建GLView
,请在分配rootViewController
之前先执行[self.viewController.view addSubView:glViewCreatedInCode]
之类的操作)