Beispiel #1
0
void CCFollow::step(ccTime dt)
{
    CC_UNUSED_PARAM(dt);

	CCPoint oldPos = m_pTarget->getPosition();
	CCPoint pos;

	if(m_bBoundarySet)
	{
		// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
		if(m_bBoundaryFullyCovered)
			return;

		CCPoint tempPos = ccpSub( m_obHalfScreenSize, m_pobFollowedNode->getPosition());

		pos = ccp(clampf(tempPos.x, m_fLeftBoundary, m_fRightBoundary), 
								   clampf(tempPos.y, m_fBottomBoundary, m_fTopBoundary));
	}
	else
	{
		pos = ccpSub(m_obHalfScreenSize, m_pobFollowedNode->getPosition());
	}

	CCPoint moveVect;

	double dist = ccpDistance(pos, oldPos);

	if(dist > 1){
		moveVect = ccpMult(ccpSub(pos, oldPos), 0.05);
		oldPos = ccpAdd(oldPos, moveVect);
		m_pTarget->setPosition(oldPos);
	}
}
// Estimate the velocity of the new point relative to previous points
// in points/second.
void LineSmoother::CalculateVelocities(uint32 newPointIndex)
{

   const float TS_MIN = 0.010f;  // 5 ms
   const float TS_MAX = 0.100f;  // 100 ms
   
   if(newPointIndex < 3)
   {  // Must be the first couple of points.
      _orgPoints[newPointIndex].pointsPerSecond = PPS_MIN;
   }
   else
   {
      
      ORIGINAL_POINT& p0 = _orgPoints[newPointIndex-2];
      ORIGINAL_POINT& p1 = _orgPoints[newPointIndex-1];
      ORIGINAL_POINT& p2 = _orgPoints[newPointIndex-0];
      
      float dist = ccpDistance(p2.point, p1.point);
      float dt = clampf(p2.timestamp-p1.timestamp,TS_MIN,TS_MAX);
      
      float ppsRaw = clampf(dist/dt,PPS_MIN,PPS_MAX);
      // The velocity is the mostly the previous and some of the current point.
      p2.pointsPerSecond = (ppsRaw + p1.pointsPerSecond + p0.pointsPerSecond)/3.0;
      // Round to the nearest 10 pps.
      //      p2.pointsPerSecond = roundf(p2.pointsPerSecond/25)*25;
      /*
      CCLOG("PPS(final):%f, dist:%f, dt:%f ms, PPS(raw):%f, PPS(rawClamped):%f",
            p2.pointsPerSecond,
            dist,
            dt*1000,
            dist/dt,
            ppsRaw);
       */
   }
}
Beispiel #3
0
void CGraphics_Threaded::SetColorVertex(const CColorVertex *pArray, int Num)
{
	dbg_assert(m_Drawing != 0, "called Graphics()->SetColorVertex without begin");

	for(int i = 0; i < Num; ++i)
	{
		if(m_UseOpenGL3_3)
		{
			float r = pArray[i].m_R, g = pArray[i].m_G, b = pArray[i].m_B, a = pArray[i].m_A;
			clampf(r, 0.f, 1.f);
			clampf(g, 0.f, 1.f);
			clampf(b, 0.f, 1.f);
			clampf(a, 0.f, 1.f);
			m_aColor[pArray[i].m_Index].r = (unsigned char)(r*255.f);
			m_aColor[pArray[i].m_Index].g = (unsigned char)(g*255.f);
			m_aColor[pArray[i].m_Index].b = (unsigned char)(b*255.f);
			m_aColor[pArray[i].m_Index].a = (unsigned char)(a*255.f);
		} 
		else
		{				
			m_aColorOld[pArray[i].m_Index].r = pArray[i].m_R;
			m_aColorOld[pArray[i].m_Index].g = pArray[i].m_G;
			m_aColorOld[pArray[i].m_Index].b = pArray[i].m_B;
			m_aColorOld[pArray[i].m_Index].a = pArray[i].m_A;
		}
	}
}
Beispiel #4
0
v3dmc_color rgbf(GLclampf r, GLclampf g, GLclampf b){
	v3dmc_color color;
	color.r = clampf(r);
	color.g = clampf(g);
	color.b = clampf(b);
	color.a = 1.0;
	return color;
}
Beispiel #5
0
v3dmc_color rgbai(GLint r, GLint g, GLint b, GLint a){
	v3dmc_color color;
	color.r = clampf((float)r/255.0);
	color.g = clampf((float)g/255.0);
	color.b = clampf((float)b/255.0);
	color.a = clampf((float)a/255.0);
	return color;
}
Beispiel #6
0
v3dmc_color rgbaf(GLclampf r, GLclampf g, GLclampf b, GLclampf a){
	v3dmc_color color;
	color.r = clampf(r);
	color.g = clampf(g);
	color.b = clampf(b);
	color.a = clampf(a);
	return color;
}
Beispiel #7
0
v3dmc_color rgbi(GLint r, GLint g, GLint b){
	v3dmc_color color;
	color.r = clampf((float)r/255.0);
	color.g = clampf((float)g/255.0);
	color.b = clampf((float)b/255.0);
	color.a = 1.0;
	return color;
} 
Point GameCamera::clamp(Rect _b, Point _p)
{
	if (Rect::ZERO.equals(_b)) return _p;

	return Point(
		clampf(_p.x, _b.getMinX(), _b.getMaxX()),
		clampf(_p.y, _b.getMinY(), _b.getMaxY())
		);
}
Beispiel #9
0
		explicit color(float r, float g, float b, float a=1.0f)
		{
			rgbaf_[0] = clampf(r);
			rgbaf_[1] = clampf(g);
			rgbaf_[2] = clampf(b);
			rgbaf_[3] = clampf(a);
			c_.rgba[0] = int(rgbaf_[0]*255.0f);
			c_.rgba[1] = int(rgbaf_[1]*255.0f);
			c_.rgba[2] = int(rgbaf_[2]*255.0f);
			c_.rgba[3] = int(rgbaf_[3]*255.0f);
		}
Beispiel #10
0
inline QColor FColor_to_QColor( const FColor& theColor )
{
	FColor	clampedColor;

	// avoid QT warning: QColor::fromRgbF: RGB parameters out of range
	clampedColor.R = clampf( theColor.R, 0.0001f, 0.999f );
	clampedColor.G = clampf( theColor.G, 0.0001f, 0.999f );
	clampedColor.B = clampf( theColor.B, 0.0001f, 0.999f );
	clampedColor.A = clampf( theColor.A, 0.0001f, 0.999f );

	return QColor::fromRgbF( clampedColor.R, clampedColor.G, clampedColor.B, clampedColor.A );
}
Beispiel #11
0
void SpritePolygonPerformance::update(float dt)
{
    dt = dt*0.3 + prevDt*0.7;
    prevDt = dt;
    elapsedTime += dt;
    int loops = (0.025-dt)*1000;
    if(dt < 0.025 && loops>0)
    {
        continuousHighDtTime = clampf(continuousHighDtTime-dt*2, 0.0, 1.0);
        waitingTime = clampf(waitingTime-dt, 0.0, 5.0);
        continuousLowDt++;
    }
    else
    {
        continuousHighDtTime+=dt;
        continuousLowDt = 0;
    }
    if (continuousLowDt >= 5 && loops > 0) {
        for(int i = 0; i < loops; i++)
        {
            if(_posX >= _rightX)
            {
                goRight = false;
            }
            else if(_posX <= _leftX)
            {
                goRight = true;
            }
            auto s = makeSprite();
            addChild(s);
            s->setPosition(_posX, _posY);
            if(goRight)
                _posX++;
            else
                _posX--;
            
            incrementStats();
        }
        updateLabel();
    }

    //if we have 10 continuous low dt, then we will start to create more sprites
    else if(continuousHighDtTime >= .5 || waitingTime > 3.0){
        // its now 1 seconds with high DT time, time to end
        ended = true;
        unscheduleUpdate();
        perfLabel->setString("Test ended in " + Value(elapsedTime).asString() + " seconds\nNodes: " + Value(spriteCount).asString() + "   Triangles: " + Value(triCount).asString() + "\nPixels: " + Value(pixelCount).asString() + "   Vertices: " + Value(vertCount).asString());
        _subtitleLabel->setString("Test ended");
    }
    else{
        waitingTime += dt;
    }
}
Beispiel #12
0
static inline void YUV2RGB( int y, int u, int v, uint8_t *rgb ) {
#ifdef HAVE_FLOAT_CONVERSION
	rgb[0] = clampf( y +                 1.402*(u-128) );
	rgb[1] = clampf( y - 0.344*(v-128) - 0.714*(u-128) );
	rgb[2] = clampf( y + 1.772*(v-128)                 );
#else
	const int C = y -  16;
	const int D = u - 128;
	const int E = v - 128;
	rgb[0] = clampi( (298*C         + 409*E + 128) >> 8 );
	rgb[1] = clampi( (298*C - 100*D - 208*E + 128) >> 8 );
	rgb[2] = clampi( (298*C + 516*D         + 128) >> 8 );
#endif
}
size_t CCAssetInputStream_android::seek(int offset, int mode) {
    switch(mode) {
        case SEEK_CUR:
            m_position = clampf(m_position + offset, 0, m_length);
            break;
        case SEEK_END:
            m_position = clampf(m_length + offset, 0, m_length);
            break;
        case SEEK_SET:
            m_position = clampf(offset, 0, m_length);
            break;
    }
	
	return m_position;
}
Beispiel #14
0
EXPORT void
framefunc_get_rgba_f32( rgba_f32 *result, FrameFunctionHolder *holder, double frame ) {
    if( holder->funcs && holder->funcs->get_values ) {
        double dresult[4];

        holder->funcs->get_values( holder->source, 1, &frame, &dresult );

        *result = (rgba_f32) { (float) dresult[0], (float) dresult[1],
            (float) dresult[2], clampf( (float) dresult[3], 0.0f, 1.0f ) };
    }
    else {
        *result = (rgba_f32) { (float) holder->constant[0], (float) holder->constant[1],
            (float) holder->constant[2], clampf( (float) holder->constant[3], 0.0f, 1.0f ) };
    }
}
Beispiel #15
0
static float
sminf(float a, float b)
{
	float k = 0.1;
	float h = clampf(0.5+0.5*(b-a)/k, 0.0, 1.0);
	return lerpf(b, a, h) - k*h*(1.0-h);
}
Beispiel #16
0
void Tank::rotateGun(float dt)
{
    if (_rotationSpeed != 0.0f) {
        _angle = clampf(_angle + _angleStep * _rotationSpeed * dt, _angleMin, _angleMax);
        draw();
    }
}
void CCScrollBar::syncThumbPositionSizeForScrollView(ScrollView* scrollView) {
	CCSize svSize = scrollView->getSize();
	CCSize innerSize = scrollView->getInnerContainerSize();
	CCSize sbSize = getContentSize();
	CCSize thumbSize = m_thumb ? m_thumb->getContentSize() : m_fixedThumb->getContentSize();
	float percentage = 0;
    float thumbLength = 0;
	if(m_horizontal) {
		float minX = svSize.width - innerSize.width;
		percentage = (scrollView->getInnerContainer()->getPosition().x - minX) / -minX;
        thumbLength = MIN(1, svSize.width / innerSize.width) * sbSize.height;
	} else {
		float minY = svSize.height - innerSize.height;
		percentage = (scrollView->getInnerContainer()->getPosition().y - minY) / -minY;
        thumbLength = MIN(1, svSize.height / innerSize.height) * sbSize.height;
	}
	percentage = clampf(percentage, 0, 1);
	if(m_thumb) {
        m_thumb->setPreferredSize(CCSizeMake(sbSize.width, thumbLength));
		m_thumb->setPosition(ccp(sbSize.width / 2,
								 sbSize.height - percentage * (sbSize.height - thumbSize.height) - thumbSize.height / 2));
	} else {
		m_fixedThumb->setPosition(ccp(sbSize.width / 2,
									  sbSize.height - percentage * (sbSize.height - thumbSize.height) - thumbSize.height / 2));
	}
}
Beispiel #18
0
void MagicJoystick::onTouchMoved(Touch* touch, Event* event)
{
    float distance = touch->getLocation().getDistance( this->getPosition());
    distance =  clampf(distance, 0, kMaxDistance);
    float angle = angleBetween(getPosition(), touch->getLocation());
    
    float vx = cos(angle * M_PI / 180) * (distance * 1.5);
    float vy = sin(angle * M_PI / 180) * (distance * 1.5);
    
    _direction = Point(vx / distance, vy / distance);
    
    float darkness = (127 * (vy / kMaxDistance));
    
    float i = 0;
    float count = this->getChildren().size();
    for (Node *layer : this->getChildren()) {
        Point addition = Point(vx / getContentSize().width,vy / getContentSize().height) * i / count;
        layer->setPosition(joystickNormalizedCenter + addition);
        if (std::strcmp(layer->getName().c_str(), kStickTag) == 0) {
            layer->setColor(Color3B(0,0,.8 - (( darkness / 200.0) * (i / count))));
        }
        i ++;
    }
    if (joystickDirection) {
        joystickDirection(Point(vx / getContentSize().width,vy / getContentSize().height));
    }
}
Beispiel #19
0
EXPORT void
video_mix_cross_gl_pull( rgba_frame_gl *out, video_source *a, int frame_a, video_source *b, int frame_b, float mix_b ) {
    // Gather the mix factor
    g_debug( "In video_mix_cross_gl_pull, mix_b=%f", mix_b );
    mix_b = clampf(mix_b, 0.0f, 1.0f);

    if( mix_b == 1.0f ) {
        // We only need frame B
        video_get_frame_gl( b, frame_b, out );
        return;
    }
    else if( mix_b == 0.0f ) {
        video_get_frame_gl( a, frame_a, out );
        return;
    }

    rgba_frame_gl fa = *out, fb = *out;

    video_get_frame_gl( a, frame_a, &fa );
    video_get_frame_gl( b, frame_b, &fb );

    video_mix_cross_gl( out, &fa, &fb, mix_b );

    glDeleteTextures( 1, &fa.texture );
    glDeleteTextures( 1, &fb.texture );
}
std::vector<Vec2> AutoPolygon::reduce(const std::vector<Vec2>& points, const Rect& rect , const float& epsilon)
{
    auto size = points.size();
    // if there are less than 3 points, then we have nothing
    if(size<3)
    {
        log("AUTOPOLYGON: cannot reduce points for %s that has less than 3 points in input, e: %f", _filename.c_str(), epsilon);
        return std::vector<Vec2>();
    }
    // if there are less than 9 points (but more than 3), then we don't need to reduce it
    else if (size < 9)
    {
        log("AUTOPOLYGON: cannot reduce points for %s e: %f",_filename.c_str(), epsilon);
        return points;
    }
    float maxEp = MIN(rect.size.width, rect.size.height);
    float ep = clampf(epsilon, 0.0, maxEp/_scaleFactor/2);
    std::vector<Vec2> result = rdp(points, ep);
    
    auto last = result.back();
    if(last.y > result.front().y && last.getDistance(result.front()) < ep*0.5)
    {
        result.front().y = last.y;
        result.pop_back();
    }
    return result;
}
Beispiel #21
0
void ResolveOverlap(  const glm::vec2& Ncoll, float depth, float spring_value, float spring_damper,
					  const glm::vec2& C0, const glm::vec2& P0, glm::vec2& V0, float w0,
					  const glm::vec2& C1, const glm::vec2& P1, glm::vec2& V1, float w1,
					  glm::vec2& Fspring)
{
	glm::vec2 R0    = C0 - P0;
	glm::vec2 R1    = C1 - P1;
	glm::vec2 T0    = glm::vec2(-R0.y, R0.x);
	glm::vec2 T1    = glm::vec2(-R1.y, R1.x);
	glm::vec2 VP0   = V0 - T0 * w0; // point velocity (SIGN IS WRONG)
	glm::vec2 VP1   = V1 - T1 * w1; // point velocity (SIGN IS WRONG)

	glm::vec2 D = C0 - C1;
	glm::vec2 V = VP0 - VP1;

	float  vn = glm::dot(V, Ncoll);
	float  dn = glm::dot(D, Ncoll);

//	if (dn > 0.0f) dn = 0.0f;

	float  f = (spring_value * dn) - (spring_damper * vn);

	f = clampf(f, -1000.0f, 1000.0f);
	Fspring = -f * Ncoll;
}
Beispiel #22
0
/* Calculates the fade time from the changes in gain and listener to source
 * angle between updates. The result is a the time, in seconds, for the
 * transition to complete.
 */
static ALfloat CalcFadeTime(ALfloat oldGain, ALfloat newGain, const aluVector *olddir, const aluVector *newdir)
{
    ALfloat gainChange, angleChange, change;

    /* Calculate the normalized dB gain change. */
    newGain = maxf(newGain, 0.0001f);
    oldGain = maxf(oldGain, 0.0001f);
    gainChange = fabsf(log10f(newGain / oldGain) / log10f(0.0001f));

    /* Calculate the angle change only when there is enough gain to notice it. */
    angleChange = 0.0f;
    if(gainChange > 0.0001f || newGain > 0.0001f)
    {
        /* No angle change when the directions are equal or degenerate (when
         * both have zero length).
         */
        if(newdir->v[0] != olddir->v[0] || newdir->v[1] != olddir->v[1] || newdir->v[2] != olddir->v[2])
        {
            ALfloat dotp = aluDotproduct(olddir, newdir);
            angleChange = acosf(clampf(dotp, -1.0f, 1.0f)) / F_PI;
        }
    }

    /* Use the largest of the two changes, and apply a significance shaping
     * function to it. The result is then scaled to cover a 15ms transition
     * range.
     */
    change = maxf(angleChange * 25.0f, gainChange) * 2.0f;
    return minf(change, 1.0f) * 0.015f;
}
Beispiel #23
0
EXPORT void
video_copy_frame_alpha_f32( rgba_frame_f32 *out, rgba_frame_f32 *in, float alpha ) {
    alpha = clampf(alpha, 0.0f, 1.0f);

    if( out == in && alpha == 1.0f )
        return;

    if( alpha == 0.0f ) {
        box2i_set_empty( &out->current_window );
        return;
    }

    box2i inner;
    box2i_intersect( &inner, &out->full_window, &in->current_window );
    out->current_window = inner;

    if( box2i_is_empty( &inner ) )
        return;

    int width = inner.max.x - inner.min.x + 1;

    for( int y = inner.min.y; y <= inner.max.y; y++ ) {
        rgba_f32 *row_out = video_get_pixel_f32( out, inner.min.x, y );
        rgba_f32 *row_in = video_get_pixel_f32( in, inner.min.x, y );

        memcpy( row_out, row_in, sizeof(rgba_f32) * width );

        if( alpha != 1.0f ) {
            for( int x = 0; x < width; x++ )
                row_out[x].a *= alpha;
        }
    }
}
Beispiel #24
0
EXPORT void
video_mix_over_gl( rgba_frame_gl *out, rgba_frame_gl *a, rgba_frame_gl *b, float mix_b ) {
    // Really, this is almost exactly the same code as video_mix_cross_gl; the two
    // should probably be combined (difference is just the shader text)
    GQuark shader_quark = g_quark_from_static_string( "cprocess::video_mix::over_shader" );

    // Gather the mix factor
    mix_b = clampf(mix_b, 0.0f, 1.0f);

    void *context = getCurrentGLContext();
    gl_shader_state *shader = (gl_shader_state *) g_dataset_id_get_data( context, shader_quark );

    if( !shader ) {
        // Time to create the program for this context
        shader = g_new0( gl_shader_state, 1 );

        shader->program = video_create_filter_program( over_shader_text, "Video mix over shader" );
        shader->mix_b_uniform = glGetUniformLocation( shader->program->program, "mix_b" );

        g_dataset_id_set_data_full( context, shader_quark, shader, (GDestroyNotify) destroy_shader );
    }

    glUseProgram( shader->program->program );
    glUniform1f( shader->mix_b_uniform, mix_b );

    video_render_gl_frame_filter2( shader->program, out, a, b );
}
Beispiel #25
0
EXPORT void
video_mix_cross_f32_pull( rgba_frame_f32 *out, video_source *a, int frame_a, video_source *b, int frame_b, float mix_b ) {
    mix_b = clampf(mix_b, 0.0f, 1.0f);

    if( mix_b == 0.0 ) {
        video_get_frame_f32( a, frame_a, out );
    }
    else if( mix_b == 1.0 ) {
        video_get_frame_f32( b, frame_b, out );
    }
    else {
        rgba_frame_f32 tempFrame;
        v2i size;

        box2i_get_size( &out->full_window, &size );

        tempFrame.data = g_slice_alloc( sizeof(rgba_f32) * size.y * size.x );
        tempFrame.full_window = out->full_window;

        video_get_frame_f32( a, frame_a, out );
        video_get_frame_f32( b, frame_b, &tempFrame );
        video_mix_cross_f32( out, out, &tempFrame, mix_b );

        g_slice_free1( sizeof(rgba_f32) * size.y * size.x, tempFrame.data );
    }
}
Beispiel #26
0
extern int
mkbrmap(void)			/* make dynamic range map */
{
	double	Tdb, b, s;
	double	ceiling, trimmings;
	register int	i;
					/* copy initial histogram */
	memcpy((void *)modhist, (void *)bwhist, sizeof(modhist));
	s = (bwmax - bwmin)/HISTRES;	/* s is delta b */
					/* loop until satisfactory */
	do {
		mkcumf();			/* sync brightness mapping */
		if (mhistot <= histot*CVRATIO)
			return(-1);		/* no compression needed! */
		Tdb = mhistot * s;
		trimmings = 0.;			/* clip to envelope */
		for (i = 0, b = bwmin + .5*s; i < HISTRES; i++, b += s) {
			ceiling = Tdb*clampf(Lb(b));
			if (modhist[i] > ceiling) {
				trimmings += modhist[i] - ceiling;
				modhist[i] = ceiling;
			}
		}
	} while (trimmings > histot*CVRATIO);

#if ADJ_VEIL
	mkcrfimage();			/* contrast reduction image */
#endif

	return(0);			/* we got it */
}
Beispiel #27
0
EXPORT void
video_mix_cross_gl( rgba_frame_gl *out, rgba_frame_gl *a, rgba_frame_gl *b, float mix_b ) {
    GQuark shader_quark = g_quark_from_static_string( "cprocess::video_mix::crossfade_shader" );
    g_debug( "In video_mix_cross_gl, mix_b=%f", mix_b );

    // Gather the mix factor
    mix_b = clampf(mix_b, 0.0f, 1.0f);

    void *context = getCurrentGLContext();
    gl_shader_state *shader = (gl_shader_state *) g_dataset_id_get_data( context, shader_quark );

    if( !shader ) {
        // Time to create the program for this context
        shader = g_new0( gl_shader_state, 1 );

        shader->program = video_create_filter_program( crossfade_shader_text, "Video mix crossfade shader" );
        shader->mix_b_uniform = glGetUniformLocation( shader->program->program, "mix_b" );

        g_dataset_id_set_data_full( context, shader_quark, shader, (GDestroyNotify) destroy_shader );
    }

    glUseProgram( shader->program->program );
    glUniform1f( shader->mix_b_uniform, mix_b );

    video_render_gl_frame_filter2( shader->program, out, a, b );
}
Beispiel #28
0
void FXLightning::render(){

	float angle = atan2f(end.y - start.y , end.x - start.x);
	float x = cosf(angle - M_PI/2.0) * width;
	float y = sinf(angle - M_PI/2.0) * width;
	float rx = cosf(angle - M_PI/2.0) * spread;
	float ry = sinf(angle - M_PI/2.0) * spread;
    static int counter = 0;
	
	int n_samples = ccpDistance(start, end)/480 * K_NUMBER_OF_LIGHTNING_SAMPLES;
	if (n_samples > K_NUMBER_OF_LIGHTNING_SAMPLES) {
		n_samples = K_NUMBER_OF_LIGHTNING_SAMPLES;
	}
   
	for (int i=0; i < n_samples; i+=2) {
        CCPoint p = ccpLerp(start, end, i/(float)(n_samples-1));
		float r = ((rand()%100) / 100.0 - 0.5) * 7;
//        float r = 20* noise1(counter*speed);
        float w = 0;
        if (i < n_samples*0.5) {
            w = i/(float)n_samples * 3;
        }
        else{
            w = (n_samples-i-2)/(float)n_samples * 3;
        }
        w = clampf(w, 0, 1);
        if (tapper == 0) {
            vtx[ i+0 ].x = p.x + x + rx*r*w;
            vtx[ i+0 ].y = p.y + y + ry*r*w;
            
            vtx[ i+1 ].x = p.x - x + rx*r*w;
            vtx[ i+1 ].y = p.y - y + ry*r*w;
        }
        else{
            vtx[ i+0 ].x = p.x + x*tapper*(1-i/(float)n_samples) + rx*r;
            vtx[ i+0 ].y = p.y + y*tapper*(1-i/(float)n_samples) + ry*r;
            
            vtx[ i+1 ].x = p.x - x*tapper*(1-i/(float)n_samples) + rx*r;
            vtx[ i+1 ].y = p.y - y*tapper*(1-i/(float)n_samples) + ry*r;
        }
        counter+=5;
	}
    
    
    
    pShaderProgram->use();
    pShaderProgram->setUniformsForBuiltins();
    
    ccGLBindTexture2D(texture->getName());
    
    glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, 0, vtx);
    glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, 0, uvs);
    glDrawArrays(GL_TRIANGLE_STRIP, 0,n_samples);
    
    //DEBUG
//    glDrawArrays(GL_LINE_STRIP, 0, n_samples);
    
    CC_INCREMENT_GL_DRAWS(1);
}
void HowToPlayScene::onPressRight(cocos2d::Ref *sender, cocos2d::extension::Control::EventType pControlEvent)
{
	if (pControlEvent == Control::EventType::TOUCH_UP_INSIDE && !IS_LOCKED)
    {
        m_currentPage = clampf(m_currentPage + 1, 0, m_maxPages - 1);
        fixArrows();
	}
}
void ProgressTimer::setPercentage(float fPercentage)
{
    if (_percentage != fPercentage)
    {
        _percentage = clampf(fPercentage, 0, 100);
        updateProgress();
    }
}