从笔尖中的视图制作GLView

时间:2012-05-17 00:46:41

标签: ios ios5 opengl-es

我正在尝试将我的nib文件中的一个视图用作GLView

在我的iphoneDisplay.nib文件中,我将视图设置为GLView的自定义类(底部的代码),并在我的应用代理中设置了插座。 View i设置更改为黑色背景颜色,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

1 个答案:

答案 0 :(得分:0)

以下是我认为您的代码正在运行的方式

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]之类的操作