その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

CCDirector のソース解析

CCDirectorのソースを解析してたときのメモがあったので、載せておきます。
(UIKitとcocos2dの併用時にCCSceneの遷移でハマっていたので、原因の目星をつけられるようソースを読んでました)

CCDirectorの正体

CCDirector *director = [CCDirector sharedDirector];


とすると、

+ (CCDirector *)sharedDirector
{
	if (!_sharedDirector) {

		//
		// Default Director is TimerDirector
		// 
		if( [ [CCDirector class] isEqual:[self class]] )
			_sharedDirector = [[CC_DIRECTOR_DEFAULT alloc] init];
		else
			_sharedDirector = [[self alloc] init];
	}
		
	return _sharedDirector;
}


とシングルトンが生成されるのですが、ここでalloc/initされてる CC_DIRECTOR_DEFAULT は

#define CC_DIRECTOR_DEFAULT CCDirectorTimer


と定義されてるので、実は CCDirectorTimer (CCDirectorのサブクラスであるCCDirectorIOSのサブクラス)のインスタンスが生成されています。

CCDirectorTimer

アニメーションのフレーム処理はNSTimerで実装されてるようです。

- (void)startAnimation
{
	// (略)
	
	animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval_ target:self selector:@selector(mainLoop) userInfo:nil repeats:YES];
}


-(void) mainLoop
{
	[self drawScene];
}

CCDirectorIOS

- (void) drawScene
{    
	// (略)
	
	/* draw the scene */
	[runningScene_ visit];
	
	/* draw the notification node */
	[notificationNode_ visit];

	// (略)
}

CCNode

-(void) visit
{
	// (略)
	[self draw];
	// (略)	
}


CCNodeのdrawメソッドは空。
CCNodeのサブクラスで実装。たとえばCCSpriteでは

-(void) draw
{
	NSAssert(!usesBatchNode_, @"If CCSprite is being rendered by CCSpriteBatchNode, CCSprite#draw SHOULD NOT be called");

	// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Needed states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
	// Unneeded states: -

	BOOL newBlend = blendFunc_.src != CC_BLEND_SRC || blendFunc_.dst != CC_BLEND_DST;
	if( newBlend )
		glBlendFunc( blendFunc_.src, blendFunc_.dst );

#define kQuadSize sizeof(quad_.bl)
	glBindTexture(GL_TEXTURE_2D, [texture_ name]);
	
	long offset = (long)&quad_;
	
	// vertex
	NSInteger diff = offsetof( ccV3F_C4B_T2F, vertices);
	glVertexPointer(3, GL_FLOAT, kQuadSize, (void*) (offset + diff) );
	
	// color
	diff = offsetof( ccV3F_C4B_T2F, colors);
	glColorPointer(4, GL_UNSIGNED_BYTE, kQuadSize, (void*)(offset + diff));
	
	// tex coords
	diff = offsetof( ccV3F_C4B_T2F, texCoords);
	glTexCoordPointer(2, GL_FLOAT, kQuadSize, (void*)(offset + diff));
	
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
	if( newBlend )
		glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
	
#if CC_SPRITE_DEBUG_DRAW
	CGSize s = [self contentSize];
	CGPoint vertices[4]={
		ccp(0,0),ccp(s.width,0),
		ccp(s.width,s.height),ccp(0,s.height),
	};
	ccDrawPoly(vertices, 4, YES);
#endif // CC_TEXTURENODE_DEBUG_DRAW
	
}


ここでOpenGL ESベースの描画処理を行っていることがわかります。