たくさんのテクスチャ(文字列でできている)を作成してロードしています。アニメーションをスムーズに実行し続けるために、作業を別のワーカースレッドにオフロードします。それは多かれ少なかれ私が望むように正確に動作するようですが、古いデバイス(iPhone 3GS)では、長い(1秒)遅れに気付くことがあります。たまにしか発生しません。今、私はこれを正しく行っているのか、それとも概念的な問題があるのか疑問に思っています。以下にソースコードを貼り付けます。
また、GLKit TextureLoaderを使用したくないことにも言及する必要があります。これは、テクスチャ生成作業を、ロード部分だけでなく、他のスレッドにもオフロードしたいためです。
これらのテクスチャが何のために必要か疑問に思っている場合は、次のビデオをご覧ください:http: //youtu.be/U03p4ZhLjvY ?hd=1
NSLock* _textureLock;
NSMutableDictionary* _texturesWithString;
NSMutableArray* _texturesWithStringLoading;
// This is called when I request a new texture from the drawing routine.
// If this function returns 0, it means the texture is not ready and Im not displaying it.
-(unsigned int)getTextureWithString:(NSString*)string {
Texture2D* _texture = [_texturesWithString objectForKey:string];
if (_texture==nil){
if (![_texturesWithStringLoading containsObject:string]){
[_texturesWithStringLoading addObject:string];
NSDictionary* dic = [[NSDictionary alloc] initWithObjectsAndKeys:string,@"string", nil];
NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadTextureWithDictionary:)object:dic];
thread.threadPriority = 0.01;
[thread start];
[thread release];
}
return 0;
}
return _texture.name;
}
// This is executed on a separate worker thread.
// The lock makes sure that there are not hundreds of separate threads all creating a texture at the same time and therefore slowing everything down.
// There must be a smarter way of doing that. Please let me know if you know how! ;-)
-(void)loadTextureWithOptions:(NSDictionary*)_dic{
[_textureLock lock];
EAGLContext* context = [[SharegroupManager defaultSharegroup] getNewContext];
[EAGLContext setCurrentContext: context];
NSString* string = [_dic objectForKey:@"string"];
Texture2D* _texture = [[Texture2D alloc] initWithStringModified:string];
if (_texture!=nil) {
NSDictionary* _newdic = [[NSDictionary alloc] initWithObjectsAndKeys:_texture,@"texture",string,@"string", nil];
[self performSelectorOnMainThread:@selector(doneLoadingTexture:) withObject:_newdic waitUntilDone:NO];
[_newdic release];
[_texture release];
}
[EAGLContext setCurrentContext: nil];
[context release];
[_textureLock unlock];
}
// This callback is executed on the main thread and marks adds the texture to the texture cache.
-(void)doneLoadingTextureWithDictionary:(NSDictionary*)_dic{
[_texturesWithString setValue:[_dic objectForKey:@"texture"] forKey:[_dic objectForKey:@"string"]];
[_texturesWithStringLoading removeObject:[_dic objectForKey:@"string"]];
}