gpt4 book ai didi

opengl-es - 尝试在后台线程中加载/设置场景导致 "OpenGL error 0x0502 in -[CCSprite draw] 530"

转载 作者:行者123 更新时间:2023-12-04 17:33:25 25 4
gpt4 key购买 nike

我有一个 cocos2d v2.x 应用程序,它有一个场景,里面有很多 Sprite 、节点、配置、数据等......加载非常昂贵,以至于在将场景添加到导演时,有一个1/2 到 1 秒的暂停,导致当前正在运行的动画卡住,直到场景加载完毕。我分析了最慢的方法,并尝试在后台线程中异步执行它们,并在加载时显示进度微调器。

我的实现是这样的:

-(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];

// ... expensive stuff here
// [self.containerForLoadedStuff addChild:sprites, etc...]

[self performSelectorOnMainThread:@selector(done) withObject:nil waitUntilDone:NO];
}
}

-(void)done {
glFlush();
[EAGLContext setCurrentContext:self.mainContext];
self.progressSpinner.visible = NO;
self.containerForLoadedStuff.visible = YES;
}

不幸的是,这不起作用,一旦调用该操作,它就会在 CCTextureAtlas 的第 523 行的 EXC_BAD_ACCESS 崩溃
glDrawElements(GL_TRIANGLES, (GLsizei) n*6, GL_UNSIGNED_SHORT, (GLvoid*) (start*6*sizeof(_indices[0])) );

并且控制台日志显示了数十亿:

OpenGL error 0x0502 in -[CCSprite draw] 530



我究竟做错了什么?

更新

我改变了我的代码来做:
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];

// expensive calls

glFlush();
[self performSelector:@selector(done) onThread:[[CCDirector sharedDirector] runningThread] withObject:nil waitUntilDone:NO];
[EAGLContext setCurrentContext:nil];
});

它停止了崩溃,一切正常,但我仍然得到十亿:
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

任何想法为什么会发生这些错误以及如何阻止它们?

另一个更新

这毫无意义……显然这些错误来自向 CCSpriteBatchNode 添加 Sprite 。如果我将它们放在常规 CCNode 上,那么一切正常。搞什么鬼!?!?!?!?!

以及最后一次最终更新*

似乎有很多我不明白的废话。我已经设法使这些错误消失了 98%,但它们似乎仍然非常间歇性地随机发生。我做了大量的调试器和试错测试,发现这段代码:
-(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];
}

导致随机崩溃 - 通常 cocos removeFromParent 试图删除无效索引处的四边形......所以我尝试在处理它之前暂停对象..
//... background thread stuff:
[self.myObject pauseSchedulerAndActions];
[self.myObject doExpensiveStuff];
[self.myObject resumeSchedulerAndActions];

然后它不再崩溃,而是将大量 OpenGL 错误 0x0502 放入日志中的 -[CCSprite draw] 530 ......

然后我做了一些极端的日志记录来试图找出这些错误发生的地方......
... // 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];
}

在我的日志中,我看到:
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

所以当 cocos 等待触发预定选择器时会发生这些错误????我勒个去!?我再也受不了了,也没有人能够帮助我,所以是时候悬赏了。

最佳答案

这是我的方法:

加载场景

-(void) onEnterTransitionDidFinish {
[super onEnterTransitionDidFinish];
[NSThread detachNewThreadSelector:@selector(loadGameSceneInAnotherThread) toTarget:self withObject:nil];
}

- (void) loadGameSceneInAnotherThread {
NSAutoreleasePool *autoreleasepool = [[NSAutoreleasePool alloc] init];
CCGLView *view = (CCGLView*)[[CCDirector sharedDirector] view];
EAGLContext *auxGLcontext = [[EAGLContext alloc]
initWithAPI:kEAGLRenderingAPIOpenGLES2
sharegroup:[[view context] sharegroup]];

if( [EAGLContext setCurrentContext:auxGLcontext] ) {
self.gameScene = [GameScene sceneWithLevelName:levelName];
self.gameLoadingDone = YES;
glFlush();
[EAGLContext setCurrentContext:nil];
}
[auxGLcontext release];
[autoreleasepool release];
}


//this method ticks every 0.5sec
-(void) checkIfGameSceneLoaded {
if (self.gameLoadingDone) {
[self unschedule:@selector(checkIfGameSceneLoaded)];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.75 scene:self.gameScene]];
}
}

但是,我不建议为场景加载背景……因为 cocos2d 并不是真正设计来这样做的……

关于opengl-es - 尝试在后台线程中加载/设置场景导致 "OpenGL error 0x0502 in -[CCSprite draw] 530",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34174702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com