I have a cocos2d v2.x application in which there is a scene in which there are a lot of sprites, nodes, configuration, data, etc. It loads quite expensive, so adding a scene to the director has a pause of 1/2 to 1 second, causing the current run animation to freeze until this scene is loaded. I have profiled the slowest methods and am trying to execute them asynchronously in the background thread and display a progress counter when it loads.
My implementation looks something like this:
-(void)performAsyncLoad { self.progressSpinner.visible = YES; self.containerForLoadedStuff.visible = NO; self.mainContext = [EAGLContext currentContext]; NSOperationQueue *queue = [NSOperationQueue new]; NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadDependencies) object:nil]; [queue addOperation:operation]; } -(void)loadDependencies { @autoreleasepool { glFlush(); EAGLSharegroup *shareGroup = [[(CCGLView*)[[CCDirector sharedDirector] view] context] sharegroup]; EAGLContext *context = [[EAGLContext alloc] initWithAPI:[[EAGLContext currentContext] API] sharegroup:shareGroup]; [EAGLContext setCurrentContext:context];
Unfortunately, this does not work, as soon as the operation is called, it flies from EXC_BAD_ACCESS on line 523 CCTextureAtlas to
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) );
and billions are displayed in the console log:
OpenGL Error 0x0502 in - [CCSprite draw] 530
what am I doing wrong?
UPDATE
I changed my code:
dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); CCGLView *view = (CCGLView*)[[Director sharedDirector] view]; EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[view context] sharegroup]]; dispatch_async(queue, ^{ [EAGLContext setCurrentContext:context];
And he stopped the crash, and everything works, but I still get a billion:
OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530
Any ideas why these errors occur and how I can stop them?
EVEN OTHER UPDATE
It makes no sense ... obviously, these errors are due to adding sprites to CCSpriteBatchNode. If I put them on a regular CCNode, then everything will be fine. WHAT IS IT!!!!?!?!?!
AND ONE LAST FINAL UPDATE *
It seems that there are just a lot of stupid things that I just don't understand. I managed to remove these errors by 98%, but they still seem randomly too intermittent. I did a ton of debugger and trial and trial testing, and found that this code:
-(void)loadDependencies { dispatch_queue_t queue = dispatch_queue_create("myqueue", NULL); CCGLView *view = (CCGLView*)[[Director sharedDirector] view]; EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[[view context] sharegroup]]; dispatch_async(queue, ^{ [EAGLContext setCurrentContext:context]; [self.myObject doExpensiveStuff]; glFlush(); [self performSelector:@selector(done) onThread:[[CCDirector sharedDirector] runningThread] withObject:nil waitUntilDone:NO]; [EAGLContext setCurrentContext:nil]; }); } -(void)done { [self.delegate completedAsyncStuff]; }
Causes of random crashes - usually cocos removeFromParent tries to remove a square with an invalid index ... So, I tried to pause the object before doing work on it.
Then it no longer crashed, but put gazillions from this OpenGL error 0x0502 in - [CCSprite draw] 530 in the log ......
So, I made some extreme protocols to try and find where these errors occur ...
... // previous code above... etc NSLog(@"gl flush..."); glFlush(); NSLog(@"after gl flush..."); [self performSelector:@selector(done) onThread:[[CCDirector sharedDirector] runningThread] withObject:nil waitUntilDone:NO]; [EAGLContext setCurrentContext:nil]; }); } -(void)done { NSLog(@"done scheduling notify delegate"); [self scheduleOnce:@selector(notifyDelegate) delay:1]; } -(void)notifyDelegate { NSLog(@"about to notify delegate"); [self.delegate completedAsyncStuff]; }
In my log I see:
gl flush after gl flush done scheduling notify delegate OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 OpenGL error 0x0502 in -[CCSprite draw] 530 about to notify delegate
So, these errors occur when coconuts wait for the fire of the planned selector ???? What the heck!? I can no longer tolerate this, and no one could help me, so the time has come for generosity.