刚刚发现我的应用程序只是在第四代 ipod touch 上显示黑屏。它适用于我测试过的大多数其他苹果设备,例如运行良好的 iphone 3gs。这是生成我的 GLView 的样板代码,有人知道可能是什么问题吗?或者更现代的样板用于opengl es 1.0?
GLView.m:
//
// 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)
{
self = [self initGLES];
}
return self;
}
- (id)initWithCoder:(NSCoder*)coder
{
if((self = [super initWithCoder:coder]))
{
self = [self initGLES];
}
return self;
}
-(id)initGLES
{
NSLog(@"created");
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
{
// 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];
}
- (void)stopAnimation
{
[animationTimer invalidate];
animationTimer = nil;
}
- (void)setAnimationInterval:(NSTimeInterval)interval
{
animationInterval = interval;
if(animationTimer)
{
[self stopAnimation];
[self startAnimation];
}
}
// Updates the OpenGL view when the timer fires
- (void)drawView
{
// 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 = nil;
}
@end
GLView.h:
//
// GLView.h
// Part6Project
//
// Created by jeff on 5/31/09.
// Copyright Jeff LaMarche 2009. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import "ConstantsAndMacros.h"
#import "OpenGLCommon.h"
@class GLViewController;
@interface GLView : UIView
{
@private
// The pixel dimensions of the backbuffer
GLint backingWidth;
GLint backingHeight;
EAGLContext *context;
GLuint viewRenderbuffer, viewFramebuffer;
GLuint depthRenderbuffer;
NSTimer *animationTimer;
NSTimeInterval animationInterval;
GLViewController *controller;
BOOL controllerSetup;
}
@property(nonatomic, weak) GLViewController *controller;
@property NSTimeInterval animationInterval;
-(void)startAnimation;
-(void)stopAnimation;
-(void)drawView;
@end