<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Fancy Rat Studios &#187; cocos2d</title>
	<atom:link href="http://fancyratstudios.com/category/programming/cocos2d/feed/" rel="self" type="application/rss+xml" />
	<link>http://fancyratstudios.com</link>
	<description>A Fancy Rat Blog</description>
	<lastBuildDate>Mon, 08 Feb 2010 17:13:46 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Fun with cocosDenshion and Audio Metering [Update]</title>
		<link>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/</link>
		<comments>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/#comments</comments>
		<pubDate>Sat, 06 Feb 2010 05:15:50 +0000</pubDate>
		<dc:creator>Lam</dc:creator>
				<category><![CDATA[cocos2d]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=242</guid>
		<description><![CDATA[For those of you that have gotten a chance to use CocosDenshion, it is the sound engine written by Steve Oldmeadow.
It&#8217;s great since loading audio effects and music for us was quite a task beforehand.
Here&#8217;s a little demo of what we are going to make in this article shown running on the iPhone simulator.



Well today [...]]]></description>
			<content:encoded><![CDATA[<p>For those of you that have gotten a chance to use <strong>CocosDenshion</strong>, it is the sound engine written by Steve Oldmeadow.<br />
It&#8217;s great since loading audio effects and music for us was quite a task beforehand.</p>
<p>Here&#8217;s a little demo of what we are going to make in this article shown running on the iPhone simulator.</p>
<div class="video-embedded">
<object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/GgORVtsyEuU&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/GgORVtsyEuU&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object>
</div>
<p>Well today what we&#8217;ll look at is the <strong>CDAudioManager</strong> class of the <strong>CocosDenshion</strong> package itself and see if we can produce some neat effects to spice up our games.<br />
<span id="more-242"></span></p>
<p>Let&#8217;s understand <strong>CDAudioManager</strong> a bit by looking at the comments in the source.<br />
</p>
<pre style="background:white;">
/** CDAudioManager is a wrapper around AVAudioPlayer.
 CDAudioManager is basically a thin wrapper around an AVAudioPlayer object used for playing
 background music and a CDSoundEngine object used for playing sound effects. It manages the
 audio session for you deals with audio session interruption. It is fairly low level and it
 is expected you have some understanding of the underlying technologies. For example, for
 many use cases regarding background music it is expected you will work directly with the
 backgroundMusic AVAudioPlayer which is exposed as a property.

 Requirements:
 - Firmware: OS 2.2 or greater
 - Files: CDAudioManager.*, CocosDenshion.*
 - Frameworks: OpenAL, AudioToolbox, AVFoundation
 @since v0.8
 */
</pre>
<p>Since it&#8217;s a wrapper around <strong>AVAudioPlayer</strong> we have some functionality for obtaining data that you can use for playback-level metering.</p>
<p>The methods to use for level metering are:</p>
<ul>
<li>the <em>meteringEnabled</em>  property</li>
<li>-(void)updateMeters</li>
<li>-(float)averagePowerForChannel:(NSUInteger)channelNumber</li>
<li>-(float)peakPowerForChannel:(NSUInteger)channelNumber</li>
</ul>
<p>Since we&#8217;re just quickly setting up some background audio, let&#8217;s do this as simple as possible by using <strong>SimpleAudioEngine</strong>.</p>
<h2>Accessing CDAudioManager</h2>
<p><strong>SimpleAudioEngine</strong> (as of this post) won&#8217;t give us direct access to the audio manager for our background music so let&#8217;s quickly add a get method to return the audio manager.</p>
<h3>SimpleAudioEngine.m</h3>
<pre class="brush: objc;">
-(CDAudioManager*)audioManager
{
	return am;
}
</pre>
<p><em>Update: The alternative for accessing is through the sharedInstance of audio manager and I&#8217;ve now reworked the code to use that instead. So now you don&#8217;t need to modify SimpleAudioEngine anymore.</em></p>
<p>We needed access to CDAudioManager so we can get access to AVAudioPlayer to access metering methods. We do this below:</p>
<p><em>Updated for performance by weak referencing the <strong>AVAudioPlayer</strong> instance into a class variable.</em></p>
<pre class="brush: objc;">
audioPlayer_ = [[SimpleAudioEngine sharedEngine] audioManager].backgroundMusic;
audioPlayer_.meteringEnabled = YES;
</pre>
<p>Well we have enabled metering but what we now need to do is call <em>updateMeters</em> every time we need<br />
to get meter level values. Cocos2D has functionality for scheduling timers so we set that up and call <em>updateMeters</em>.</p>
<pre class="brush: objc;">
-(void)tick:(ccTime) dt
{
	[audioPlayer_ updateMeters];
}
</pre>
<p>While still in the loop where we update our meter, we can now get values for the average and peak power of our background music.</p>
<pre class="brush: objc;">
-(void)tick:(ccTime) dt
{
	[audioPlayer_ updateMeters];
	double peakPowerForChannel = 0.f, avgPowerForChannel = 0.f;

	for(ushort i = 0; i &amp;lt; audioPlayer_.numberOfChannels; ++i){
		//	convert the -160 to 0 dB to [0..1] range
		peakPowerForChannel = pow(10, (0.05 * [audioPlayer_ peakPowerForChannel:i]));
		avgPowerForChannel = pow(10, (0.05 * [audioPlayer_ averagePowerForChannel:i]));

		filteredPeak_[i] = filterSmooth_ * peakPowerForChannel + (1.0 - filterSmooth_) * filteredPeak_[i];
		filteredAverage_[i] = filterSmooth_ * avgPowerForChannel + (1.0 - filterSmooth_) * filteredAverage_[i];
	}
}
</pre>
<p>What I&#8217;ve done is set all this up in the class <strong>AudioVisualization</strong> which will handle all the background audio metering for you. You access the class through the <em>sharedAV</em> method which returns a shared singleton instance.</p>
<p>All you need to do is add your delegate with the method:</p>
<pre class="brush: objc;">
-(void)addDelegate:(id&amp;lt;AudioVisualizationProtocol&amp;gt;)delegate forChannel:(ushort)channel;
</pre>
<p>The forChannel argument specifies the channel you want to meter for your background music. If it is mono then just set it to 0.</p>
<p>Now you just need to implement one of the <em>AudioVisualizationProtocol</em>&#8217;s to receive level values for your delegate.</p>
<pre class="brush: objc;">
-(void)avAvgPowerLevelDidChange:(float)level channel:(ushort)aChannel;
</pre>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/MeterLevelDemoScreen.jpg"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/MeterLevelDemoScreen.jpg" alt="" title="MeterLevelDemoScreen" width="317" height="479" class="aligncenter size-full wp-image-264" /></a></p>
<p>That&#8217;s pretty much it! Hope you find this as cool as I did when I figured it out.</p>
<p>Just download the example demo file below to try it out.</p>
<div class="clearfix download-wrapper">
<a href="http://dl.dropbox.com/u/271717/DenshionAudioVisualDemo.zip"><span class="xcode-download-icon" style="vertical-align:text-top;"></span></a><br />
<a class="download" href="http://dl.dropbox.com/u/271717/DenshionAudioVisualDemo.zip">Download the XCode Demo</a>
</div>
<p>This demo uses the fast, easy and open source cocos2d framework.<br />
CocosDenshion is the sound engine for the cocos2d framework if you didn&#8217;t know that from reading this whole post =/.<br />
<a href="http://www.cocos2d-iphone.org/"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/official-cocos-logo-landscape-happy-300x89.png" alt="" title="cocos2d" width="300" height="89" class="alignnone size-medium wp-image-195" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/programming/cocos2d/fun-with-cocosdenshion-and-audio-metering/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>ProgressTimer for cocos2d</title>
		<link>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/</link>
		<comments>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 23:49:45 +0000</pubDate>
		<dc:creator>Lam</dc:creator>
				<category><![CDATA[OpenGL]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[bar]]></category>
		<category><![CDATA[indicator]]></category>
		<category><![CDATA[loading]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[radial]]></category>
		<category><![CDATA[timer]]></category>

		<guid isPermaLink="false">http://fancyratstudios.com/?p=126</guid>
		<description><![CDATA[Every Monday, Wednesday and Friday I will put my thoughts on game design concepts and ideas into words so for today let&#8217;s focus on a topic that I hope many games will use. A Loading indicator!
The problem at hand
Sometimes we will need to process data or have an in-game wait or delay. We can&#8217;t let [...]]]></description>
			<content:encoded><![CDATA[<p>Every Monday, Wednesday and Friday I will put my thoughts on game design concepts and ideas into words so for today let&#8217;s focus on a topic that I hope many games will use. A Loading indicator!</p>
<h2>The problem at hand</h2>
<p>Sometimes we will need to process data or have an in-game wait or delay. We can&#8217;t let users wait without any visual indication so generally we&#8217;ll implement a loading progress image. This simple concept is shown below.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/progress-timer-1.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/progress-timer-1.png" alt="" title="progress-timer-1" width="271" height="64" class="alignnone size-full wp-image-135" /></a><br />
If that&#8217;s what you are also aiming to do then read ahead!<br />
<span id="more-126"></span></p>
<h2>Discovery</h2>
<p>We want a solution that can work for any image type and is setup for cocos2d-iphone. A really neat idea is that we can map triangles using opengl to show certain portions of the image.</p>
<p>We see that for the mapping to work, we&#8217;ll use:</p>
<ol>
<li>the midpoint vertex (vertex 0)</li>
<li>the 12 o&#8217;clock vertex (vertex 1)</li>
<li>each corner edge up-to, (vertex 2-5)</li>
<li>the point created from the progress percentage (vertex 6)</li>
</ol>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png" alt="" title="texture-mapping-triangles" width="209" height="231" class="alignnone size-full wp-image-181" /></a><br />
Not too hard when we really get down to solving it.</p>
<h2>Let&#8217;s implement the thing</h2>
<p>First we setup a <strong>ProgressTimer</strong> class that inherits a <strong>CCNode</strong> so we can add it to the engine.<br />
<strong>ProgressTimer</strong>, at it&#8217;s core, will hold the percentage value, a texture, and the vertex data so we can render the object in opengl. (Note that the sample below has more because I&#8217;ve implemented the option to change its opacity and color. I&#8217;ve also added different progress timer types.)</p>
<h3>ProgressTimer.h</h3>
<pre class="brush: objc;">
typedef enum {
	kProgressTimerTypeRadialCCW,
	kProgressTimerTypeRadialCW,
	kProgressTimerTypeHorizontalBarLR,
	kProgressTimerTypeHorizontalBarRL,
	kProgressTimerTypeVerticalBarBT,
	kProgressTimerTypeVerticalBarTB,
} ProgressTimerType;

@interface ProgressTimer : CCNode {
	ProgressTimerType	type_;
	float				percentage_;
	CCTexture2D			*texture_;

	int					vertexDataCount_;
	ccV2F_C4F_T2F		*vertexData_;

	int					indicesCount_;
	GLubyte				*indices_;

	GLubyte				opacity_;
	ccColor3B			color_;
	ccBlendFunc			blendFunc_;
}
///
//	Change the percentage to change progress.
///
@property ProgressTimerType type;
///
//     The percentage of progress from 0..100
///
@property float percentage;
@property (retain) CCTexture2D *texture;
@property ccColor3B color;
@property GLubyte opacity;
@property ccBlendFunc blendFunc;

///
//	Creates a progress timer with the texture as the shape the timer goes through
///
+ (id) progressWithTexture:(CCTexture2D*) aTexture;
- (id) initWithTexture:(CCTexture2D*) aTexture;

@end
</pre>
<p>We&#8217;ll skip the basic initializing and destruction of variables and get right to the most important piece. The mapping of the image in order to create the radial indicator.</p>
<p>Every time a user changes the percentage we will update the ProgressTimer vertex data.</p>
<pre class="brush: objc;">

-(void)setPercentage:(float) percentage
{
	if(percentage_ &lt; 0.f)
		percentage_ = 0.f;
	else if(percentage &gt; 100.0f)
		percentage_  = 100.f;
	else
		percentage_ = percentage;

	[self updateProgress];
}
</pre>
<p><strong>ProgressTimer</strong>&#8217;s <em>updateProgress</em> will call <em>updateRadial</em> if our type is set to <em>kProgressTimerTypeRadialCCW</em> or <em>kProgressTimerTypeRadialCCW</em>. Radial type is our pie slice indicator and the CW/CCW suffix represents it&#8217;s rotation direction (clockwise or counter-clockwise).</p>
<p>What we will do is understand the implementation details of developing the radial slices.</p>
<p>Every radial update, we will release all vertex data memory on the heap.</p>
<h3>ProgressTimer.m <em>updateRadial</em></h3>
<pre class="brush: objc;">
	//	release all previous information
	if(vertexData_){
		free(vertexData_);
		vertexData_ = 0;
		vertexDataCount_ = 0;
	}

	if(indices_){
		free(indices_);
		indices_ = 0;
		indicesCount_ = 0;
	}

	//	If percentage is zero it's quicker not to create the vertexData
	if(percentage_ == 0.f)
		return;
</pre>
<h3>Finding that midpoint</h3>
<p>The easiest vertex point to find on the image is the midpoint and as an added bonus we will use a <strong>CCNode</strong>&#8217;s <em>anchorPoint</em> so we have a choice for the center. The midpoint has to be adjusted by the actual texture maximums since we don&#8217;t always deal with texture sizes with powers of 2. Once we have the midpoint we now have enough information to find the next needed vertex.</p>
<pre class="brush: objc;">
	CGPoint tMax = ccp(texture_.maxS,texture_.maxT);
	CGPoint midpoint = ccpCompMult(self.anchorPoint, tMax);
</pre>
<p>ccCompMult is just a multiplying each component of the two points together</p>
<pre class="brush: objc;">
CGPoint ccpCompMult(CGPoint a, CGPoint b)
{
	return ccp(a.x * b.x, a.y * b.y);
}
</pre>
<h3>The percentage point</h3>
<p>Now we find the vertex point based on the <strong>ProgressTimer</strong> percentage.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-rotation-point.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-rotation-point.png" alt="" title="finding-rotation-point" width="201" height="204" class="alignnone size-full wp-image-168" /></a></p>
<p>We can find the angle needed to rotate from the 12 o&#8217;clock position.<br />
Taking that angle, the point of rotation is found by doing a vector rotation from the vertex at the 12 o&#8217;clock to the percentage point.</p>
<pre class="brush: objc;">
	float alpha = percentage_ / 100.f;
	//	Otherwise we can get the angle from the alpha
	float angle = 2.f*M_PI * ( type_ == kProgressTimerTypeRadialCW? alpha : 1.f - alpha);

	//	We find the vector to do a hit detection based on the percentage
	//	We know the first vector is the one @ 12 o'clock (top,mid) so we rotate
	//	from that by the progress angle around the midpoint pivot
	CGPoint percentagePt = ccpRotateByAngle(ccp(midpoint.x, 0.f), midpoint, angle);
</pre>
<p>ccpRotateByAngle takes our point and a pivot and rotates it around the pivot by the angle.</p>
<pre class="brush: objc;">
CGPoint ccpRotateByAngle(CGPoint v, CGPoint pivot, float angle) {
	CGPoint r = ccpSub(v, pivot);
	float t = r.x;
	double cosa = cosf(angle), sina = sinf(angle);
	r.x = t*cosa - r.y*sina;
	r.y = t*sina + r.y*cosa;
	r = ccpAdd(r, pivot);
	return r;
}
</pre>
<p>We&#8217;re almost there but the rotated point isn&#8217;t the correct point needed for the vertex data. What we really need is the intersection point from the line edge of the texture and the percentage line.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-hit-point.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/finding-hit-point.png" alt="" title="finding-hit-point" width="221" height="217" class="alignnone size-full wp-image-169" /></a></p>
<p>How I attacked this problem is that the texture coordinates need to be in an array so we can quickly find the correct edge for the intersection test.</p>
<pre class="brush: cpp;">
#define kProgressTextureCoordsCount 4
const CGPoint kProgressTextureCoords[kProgressTextureCoordsCount] = {{0,0},{0,1},{1,1},{1,0}};
</pre>
<p><a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-corner-vertex.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-corner-vertex.png" alt="" title="texture-corner-vertex" width="228" height="244" class="alignnone size-full wp-image-174" /></a><br />
As I finished writing this I noted that maximum texture coordinate values are always 0 and 1 so let&#8217;s represent the array as a sequence of bits 00011110 (which corresponds to 0&#215;1e).</p>
<p>So I rewrote the array as</p>
<pre class="brush: cpp;">
#define kProgressTextureCoordsCount 4
const char kProgressTextureCoords = 0x1e;
</pre>
<p>And a function that will give me the corresponding texture coordinates for an index value. It pretty much operates at the bit level to retrieve the correct value (if this is confusing I may write a lesson on bit operations).</p>
<pre class="brush: objc;">
-(CGPoint)boundaryTexCoord:(char)index
{
	if (index &lt; kProgressTextureCoordsCount) {
		switch (type_) {
			case kProgressTimerTypeRadialCW:
				return ccp((kProgressTextureCoords&gt;&gt;((index&lt;&lt;1)+1))&amp;1,(kProgressTextureCoords&gt;&gt;(index&lt;&lt;1))&amp;1);
			case kProgressTimerTypeRadialCCW:
				return ccp((kProgressTextureCoords&gt;&gt;(7-(index&lt;&lt;1)))&amp;1,(kProgressTextureCoords&gt;&gt;(7-((index&lt;&lt;1)+1)))&amp;1);
			default:
				break;
		}
	}
	return CGPointZero;
}
</pre>
<p>Now we have the texture corner coordinates; we now need the edge of the texture and the percentage point line.</p>
<p>We can find the nearest edge based on the alpha value. Since we need 2 points for the line, we grab the previous index and make sure the previous index is wrapped within our array bounds.</p>
<pre class="brush: objc;">
	int index = roundf(kProgressTextureCoordsCount*alpha);
	int pIndex = (index + (kProgressTextureCoordsCount - 1))%kProgressTextureCoordsCount;

	CGPoint edgePtA = [self boundaryTexCoord:index % kProgressTextureCoordsCount];
	CGPoint edgePtB = [self boundaryTexCoord:pIndex];
</pre>
<p>The percentage line is just the midpoint and the percentage point.</p>
<p><em>ccpLineIntersect</em> returns true if an intersection occurred. We pass it 4 points that make up 2 lines.<br />
L1 = p2 &#8211; p1<br />
L2 = p4 &#8211; p3<br />
Then we grab the hit point using the returned &#8217;s&#8217; or &#8216;t&#8217; value.<br />
hit = midpoint + (percentagePoint &#8211; midpoint)*t;</p>
<pre class="brush: cpp;">
bool ccpLineIntersect(CGPoint p1, CGPoint p2,
								 CGPoint p3, CGPoint p4,
								 float *s, float *t){
	CGPoint p13, p43, p21;
	float d1343, d4321, d1321, d4343, d2121;
	float numer, denom;

	p13 = ccpSub(p1, p3);

	p43 = ccpSub(p4, p3);

	//Roughly equal to zero but with an epsilon deviation for float
	//correction
	if (ccpFuzzyEqual(p43, CGPointZero, kCGPointEpsilon))
		return false;

	p21 = ccpSub(p2, p1);

	//Roughly equal to zero
	if (ccpFuzzyEqual(p21,CGPointZero, kCGPointEpsilon))
		return false;

	d1343 = ccpDot(p13, p43);
	d4321 = ccpDot(p43, p21);
	d1321 = ccpDot(p13, p21);
	d4343 = ccpDot(p43, p43);
	d2121 = ccpDot(p21, p21);

	denom = d2121 * d4343 - d4321 * d4321;
	if (fabs(denom) &lt; kCGPointEpsilon)
		return false;
	numer = d1343 * d4321 - d1321 * d4343;

	*s = numer / denom;
	*t = (d1343 + d4321 *(*s)) / d4343;
	return true;
}
</pre>
<p>We pass the points into our intersect formula (notice we multiply the corner components by tMax since we need the actual texture coordinates and sometimes we&#8217;ll have images that are not powers of 2.</p>
<pre class="brush: objc;">
//	s and t are returned by ccpLineIntersect which explains how to use them
	float s = 0, t = 0;
	ccpLineIntersect(ccpCompMult(edgePtA,tMax), ccpCompMult(edgePtB,tMax),
					 midpoint, percentagePt, &amp;s, &amp;t);

	//	get the hit point
	CGPoint hit = ccpAdd(midpoint, ccpMult(ccpSub(r2, midpoint),t));
</pre>
<p>We have all our needed points calculated! Now all that&#8217;s left is creating the vertex data.</p>
<h2>Creating Our Vertex Data</h2>
<p>To create the vertex data we first need to convert texture coordinates (in the 0..1) range to actual vertex coordinates [0..imageSize] which I have written below.</p>
<pre class="brush: objc;">
///
//	@returns the vertex position from the texture coordinate
///
-(CGPoint)vertexFromTexCoord:(CGPoint) texCoord
{
	if (texture_) {
		float min = 0, maxW = texture_.contentSize.width, maxH = texture_.contentSize.height;
		return ccp(lerp(min, maxW, texCoord.x/texture_.maxS),
				   lerp(min, maxH, (1.f -(texCoord.y/texture_.maxT))));
	} else {
		return CGPointZero;
	}
}
</pre>
<p>Now we have all that we need to create our vertex data what we&#8217;ll do is first store the midpoint position. Then the point at 12 o&#8217;clock on the texture.</p>
<p>Now we add each corner of the texture into the vertex array until we reach the hit point and we add the hit point last.</p>
<p>After the vertex data is complete we begin creating the triangle by setting up the indexes. Let&#8217;s take a look at our original setup of vertex data.<br />
<a href="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/texture-mapping-triangles.png" alt="" title="texture-mapping-triangles" width="209" height="231" class="alignnone size-full wp-image-181" /></a><br />
To create triangles from the example vertexes above we can see that the indexes will hold.</p>
<pre>
indices_ = {0,1,2, 0,2,3, 0,4,5, 0,5,6};
</pre>
<p>The code is shown below:</p>
<pre class="brush: objc;">
	//	The size of the vertex data is the index from the hitpoint
	//	the 3 is for the midpoint, 12 o'clock point and hitpoint position.
	vertexDataCount_ = index + 3;
	vertexData_ = malloc(vertexDataCount_ * sizeof(ccV2F_C4F_T2F));

	//	First we populate the array with the midpoint, then all
	//	vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint
	vertexData_[0].texCoords = (ccTex2F){midpoint.x, midpoint.y};
	vertexData_[0].vertices = [self vertexFromTexCoord:midpoint];

	vertexData_[1].texCoords = (ccTex2F){midpoint.x, 0.f};
	vertexData_[1].vertices = [self vertexFromTexCoord:ccp(midpoint.x, 0.f)];

	for(int i = 0; i &lt; index; ++i){
		CGPoint texCoords = ccpCompMult([self boundaryTexCoord:i], tMax);

		vertexData_[i+2].texCoords = (ccTex2F){texCoords.x, texCoords.y};
		vertexData_[i+2].vertices = [self vertexFromTexCoord:texCoords];
	}

	//	hitpoint will go last
	vertexData_[vertexDataCount_ - 1].texCoords = (ccTex2F){hit.x, hit.y};
	vertexData_[vertexDataCount_ - 1].vertices = [self vertexFromTexCoord:hit];	

	indicesCount_ = 3 * (index + 1);
	indices_ = malloc(indicesCount_ * sizeof(GLubyte));

	//	We only go up to index since we do three increments
	for(int i=0;i &lt; indicesCount_/3; ++i){
		indices_[3*i] = 0;
		indices_[3*i + 1] = i + 1;
		indices_[3*i + 2] = i + 2;
	}
</pre>
<p>The only thing left to do is draw our vertex data</p>
<h3><strong>ProgressTimer</strong> <em>draw</em></h3>
<pre class="brush: objc;">
	glBindTexture(GL_TEXTURE_2D, texture_.name);
	glVertexPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].vertices);
	glTexCoordPointer(2, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].texCoords);
	glColorPointer(4, GL_FLOAT, sizeof(ccV2F_C4F_T2F), &amp;vertexData_[0].colors);
	glDrawElements(GL_TRIANGLES, indicesCount_, GL_UNSIGNED_BYTE, indices_);
</pre>
<p>And now we have a ProgressTimer indicator. If you want to see the demo file of this tutorial then just click on the link.</p>
<div class="clearfix download-wrapper">
<a href="http://dl.dropbox.com/u/271717/ProgressDemo.zip"><span class="xcode-download-icon" style="vertical-align:text-top;"></span></a><br />
<a class="download" href="http://dl.dropbox.com/u/271717/ProgressDemo.zip">Download the XCode Demo</a>
</div>
<p>This demo uses the fast, easy and open source cocos2d framework.<br />
<a href="http://www.cocos2d-iphone.org/"><img src="http://fancyratstudios.com/wp-content/uploads/2010/02/official-cocos-logo-landscape-happy-300x89.png" alt="" title="cocos2d" width="300" height="89" class="alignnone size-medium wp-image-195" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://fancyratstudios.com/2010/02/programming/progresstimer-for-cocos2d/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
