- by KJ
Hi, I'm quite new to iPhone OpenGL ES, and I'm really stuck.
I was trying to implement shadow mapping on iPhone, and I allocated two 512*1024*32bit textures for the shadow map and the diffuse map respectively. The problem is that my application started to freeze and reboot the device after I added the shadow map allocation part to the code (so I guess the shadow map allocation is causing all this mess). It happens randomly, but mostly within 10 minutes. (sometimes within a few secs) And it only happens on the real iPhone device, not on the virtual device.
I backtracked the problem by removing irrelevant code lines by lines and now my code is really simple, but it's still crashing (I mean, freezing). Could anybody please download my xcode project linked below and see what on earth is wrong? The code is really simple:
http://www.tempfiles.net/download/201004/95922/CrashTest.html
I would really appreciate if someone can help me. My iPhone is a 3GS and running on the OS version 3.1. Again, run the code and it'll take about 5 mins in average for the device to freeze and reboot. (Don't worry, it does no harm) It'll just display cyan screen before it freezes, but you'll be able to notice when it happens because the device will reboot soon, so please be patient. Just in case you can't reproduce the problem, please let me know. (That could possibly mean it's specifically my device that something's wrong with)
Observation: The problem goes away when I change the size of the shadow map to 512*512. (but with the diffuse map still 512*1024)
I'm desperate for help, thanks in advance!
Just for the people's information who can't download the link, here is the OpenGL code:
#import "GLView.h"
#import <OpenGLES/ES2/glext.h>
#import <QuartzCore/QuartzCore.h>
@implementation GLView
+ (Class)layerClass {
return [CAEAGLLayer class];
}
- (id)initWithCoder: (NSCoder*)coder {
if ((self = [super initWithCoder:coder])) {
CAEAGLLayer* layer = (CAEAGLLayer*)self.layer;
layer.opaque = YES;
layer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool: NO], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
displayLink_ = nil;
context_ = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
if (!context_ || ![EAGLContext setCurrentContext: context_]) {
[self release];
return nil;
}
glGenFramebuffers(1, &framebuffer_);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
glViewport(0, 0, self.bounds.size.width, self.bounds.size.height);
glGenRenderbuffers(1, &defaultColorBuffer_);
glBindRenderbuffer(GL_RENDERBUFFER, defaultColorBuffer_);
[context_ renderbufferStorage: GL_RENDERBUFFER fromDrawable: layer];
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, defaultColorBuffer_);
glGenTextures(1, &shadowColorBuffer_);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowColorBuffer_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 1024,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glGenTextures(1, &texture_);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 1024,
0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
}
return self;
}
- (void)startAnimation {
displayLink_ = [CADisplayLink displayLinkWithTarget: self
selector: @selector(drawView:)];
[displayLink_ setFrameInterval: 1];
[displayLink_ addToRunLoop: [NSRunLoop currentRunLoop]
forMode:NSDefaultRunLoopMode];
}
- (void)useDefaultBuffers {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, defaultColorBuffer_);
glClearColor(0.0, 0.8, 0.8, 1);
glClear(GL_COLOR_BUFFER_BIT);
}
- (void)useShadowBuffers {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, shadowColorBuffer_, 0);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
}
- (void)drawView: (id)sender {
NSTimeInterval startTime = [NSDate timeIntervalSinceReferenceDate];
[EAGLContext setCurrentContext: context_];
[self useShadowBuffers];
[self useDefaultBuffers];
glBindRenderbuffer(GL_RENDERBUFFER, defaultColorBuffer_);
[context_ presentRenderbuffer: GL_RENDERBUFFER];
NSTimeInterval endTime = [NSDate timeIntervalSinceReferenceDate];
NSLog(@"FPS : %.1f", 1 / (endTime - startTime));
}
- (void)stopAnimation {
[displayLink_ invalidate];
displayLink_ = nil;
}
- (void)dealloc {
if (framebuffer_)
glDeleteFramebuffers(1, &framebuffer_);
if (defaultColorBuffer_)
glDeleteRenderbuffers(1, &defaultColorBuffer_);
if (shadowColorBuffer_)
glDeleteTextures(1, &shadowColorBuffer_);
glDeleteTextures(1, &texture_);
if ([EAGLContext currentContext] == context_)
[EAGLContext setCurrentContext: nil];
[context_ release];
context_ = nil;
[super dealloc];
}
@end