Exemplo n.º 1
0
void Sprite::DrawTexture( const TweenState *state )
{
	Actor::SetGlobalRenderStates(); // set Actor-specified render states

	RectF crop = state->crop;
	// bail if cropped all the way 
	if( crop.left + crop.right >= 1  || 
		crop.top + crop.bottom >= 1 ) 
		return; 

	// use m_temp_* variables to draw the object
	RectF quadVerticies;
	quadVerticies.left   = -m_size.x/2.0f;
	quadVerticies.right  = +m_size.x/2.0f;
	quadVerticies.top    = -m_size.y/2.0f;
	quadVerticies.bottom = +m_size.y/2.0f;

	/* Don't draw anything outside of the texture's image area.  Texels outside 
	 * of the image area aren't guaranteed to be initialized. */
	/* HACK: Clamp the crop values. It would be more accurate to clip the 
	 * vertices so that the diffuse value is adjusted. */
	CLAMP( crop.left, 0, 1 );
	CLAMP( crop.right, 0, 1 );
	CLAMP( crop.top, 0, 1 );
	CLAMP( crop.bottom, 0, 1 );

	RectF croppedQuadVerticies = quadVerticies; 
#define IF_CROP_POS(side,opp_side) \
	if(state->crop.side!=0) \
		croppedQuadVerticies.side = \
			SCALE( crop.side, 0.f, 1.f, quadVerticies.side, quadVerticies.opp_side )
	IF_CROP_POS( left, right ); 
	IF_CROP_POS( top, bottom ); 
	IF_CROP_POS( right, left ); 
	IF_CROP_POS( bottom, top ); 

	static RageSpriteVertex v[4];
	v[0].p = RageVector3( croppedQuadVerticies.left,	croppedQuadVerticies.top,	0 );	// top left
	v[1].p = RageVector3( croppedQuadVerticies.left,	croppedQuadVerticies.bottom,	0 );	// bottom left
	v[2].p = RageVector3( croppedQuadVerticies.right,	croppedQuadVerticies.bottom,	0 );	// bottom right
	v[3].p = RageVector3( croppedQuadVerticies.right,	croppedQuadVerticies.top,	0 );	// top right
	if( m_bUsingCustomPosCoords )
	{
		for( int i=0; i < 4; ++i)
		{
			v[i].p.x+= m_CustomPosCoords[i*2];
			v[i].p.y+= m_CustomPosCoords[(i*2)+1];
		}
	}

	DISPLAY->ClearAllTextures();
	DISPLAY->SetTexture( TextureUnit_1, m_pTexture? m_pTexture->GetTexHandle():0 );

	// Must call this after setting the texture or else texture 
	// parameters have no effect.
	Actor::SetTextureRenderStates(); // set Actor-specified render states
	DISPLAY->SetEffectMode( m_EffectMode );

	if( m_pTexture )
	{
		float f[8];
		GetActiveTextureCoords( f );

		if( state->crop.left || state->crop.right || state->crop.top || state->crop.bottom )
		{
			RageVector2 texCoords[4] = {
				RageVector2( f[0], f[1] ),	// top left
				RageVector2( f[2], f[3] ),	// bottom left
				RageVector2( f[4], f[5] ),	// bottom right
				RageVector2( f[6], f[7] ) 	// top right
			};

			for( int i = 0; i < 4; ++i )
			{
				RageSpriteVertex *pVert = &v[i];

				float fTopX = SCALE( pVert->p.x, quadVerticies.left, quadVerticies.right, texCoords[0].x, texCoords[3].x );
				float fBottomX = SCALE( pVert->p.x, quadVerticies.left, quadVerticies.right, texCoords[1].x, texCoords[2].x );
				pVert->t.x = SCALE( pVert->p.y, quadVerticies.top, quadVerticies.bottom, fTopX, fBottomX );

				float fLeftY = SCALE( pVert->p.y, quadVerticies.top, quadVerticies.bottom, texCoords[0].y, texCoords[1].y );
				float fRightY = SCALE( pVert->p.y, quadVerticies.top, quadVerticies.bottom, texCoords[3].y, texCoords[2].y );
				pVert->t.y = SCALE( pVert->p.x, quadVerticies.left, quadVerticies.right, fLeftY, fRightY );
			}
		}
		else
		{
			v[0].t = RageVector2( f[0], f[1] );	// top left
			v[1].t = RageVector2( f[2], f[3] );	// bottom left
			v[2].t = RageVector2( f[4], f[5] );	// bottom right
			v[3].t = RageVector2( f[6], f[7] );	// top right
		}
	}
	else
	{
		// Just make sure we don't throw NaN/INF at the renderer:
		for( unsigned i = 0; i < 4; ++i )
			v[i].t.x = v[i].t.y = 0;
	}

	// Draw if we're not fully transparent
	if( state->diffuse[0].a > 0 || 
		state->diffuse[1].a > 0 ||
		state->diffuse[2].a > 0 ||
		state->diffuse[3].a > 0 )
	{
		DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );

		// render the shadow
		if( m_fShadowLengthX != 0  ||  m_fShadowLengthY != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLengthX, m_fShadowLengthY, 0 );	// shift by 5 units
			RageColor c = m_ShadowColor;
			c.a *= state->diffuse[0].a;
			v[0].c = v[1].c = v[2].c = v[3].c = c;	// semi-transparent black
			DISPLAY->DrawQuad( v );
			DISPLAY->PopMatrix();
		}

		// render the diffuse pass
		v[0].c = state->diffuse[0]; // top left
		v[1].c = state->diffuse[2]; // bottom left
		v[2].c = state->diffuse[3]; // bottom right
		v[3].c = state->diffuse[1]; // top right
		DISPLAY->DrawQuad( v );
	}

	// render the glow pass
	if( state->glow.a > 0.0001f )
	{
		DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );
		v[0].c = v[1].c = v[2].c = v[3].c = state->glow;
		DISPLAY->DrawQuad( v );
	}
	DISPLAY->SetEffectMode( EffectMode_Normal );
}
Exemplo n.º 2
0
void Sprite::DrawTexture( const TweenState *state )
{
	Actor::SetGlobalRenderStates();	// set Actor-specified render states

	// bail if cropped all the way 
    if( state->crop.left + state->crop.right >= 1  || 
		state->crop.top + state->crop.bottom >= 1 ) 
		return; 

	// use m_temp_* variables to draw the object
	RectF quadVerticies;

	switch( m_HorizAlign )
	{
	case align_left:	quadVerticies.left = 0;				quadVerticies.right = m_size.x;		break;
	case align_center:	quadVerticies.left = -m_size.x/2;	quadVerticies.right = m_size.x/2;	break;
	case align_right:	quadVerticies.left = -m_size.x;		quadVerticies.right = 0;			break;
	default:		ASSERT( false );
	}

	switch( m_VertAlign )
	{
	case align_top:		quadVerticies.top = 0;				quadVerticies.bottom = m_size.y;	break;
	case align_middle:	quadVerticies.top = -m_size.y/2;	quadVerticies.bottom = m_size.y/2;	break;
	case align_bottom:	quadVerticies.top = -m_size.y;		quadVerticies.bottom = 0;			break;
	default:		ASSERT(0);
	}


	/* Don't draw anything outside of the texture's image area.  Texels outside 
	 * of the image area aren't guaranteed to be initialized. */
	/* HACK: Clamp the crop values. It would be more accurate to clip the 
	 * vertices to that the diffuse value is adjusted. */
	RectF crop = state->crop;
	CLAMP( crop.left, 0, 1 );
	CLAMP( crop.right, 0, 1 );
	CLAMP( crop.top, 0, 1 );
	CLAMP( crop.bottom, 0, 1 );

	RectF croppedQuadVerticies = quadVerticies; 
#define IF_CROP_POS(side,opp_side) \
	if(state->crop.side!=0) \
		croppedQuadVerticies.side = \
			SCALE( crop.side, 0.f, 1.f, quadVerticies.side, quadVerticies.opp_side ); 
	IF_CROP_POS( left, right ); 
	IF_CROP_POS( top, bottom ); 
	IF_CROP_POS( right, left ); 
	IF_CROP_POS( bottom, top ); 

	static RageSpriteVertex v[4];
	v[0].p = RageVector3( croppedQuadVerticies.left,	croppedQuadVerticies.top,		0 );	// top left
	v[1].p = RageVector3( croppedQuadVerticies.left,	croppedQuadVerticies.bottom,	0 );	// bottom left
	v[2].p = RageVector3( croppedQuadVerticies.right,	croppedQuadVerticies.bottom,	0 );	// bottom right
	v[3].p = RageVector3( croppedQuadVerticies.right,	croppedQuadVerticies.top,		0 );	// top right

	DISPLAY->ClearAllTextures();
	DISPLAY->SetTexture( 0, m_pTexture );

	// Must call this after setting the texture or else texture 
	// parameters have no effect.
	Actor::SetTextureRenderStates();	// set Actor-specified render states

	if( m_pTexture )
	{
		float f[8];
		GetActiveTextureCoords(f);
		TexCoordsFromArray(v, f);


		RageVector2 texCoords[4] = {
			RageVector2( f[0], f[1] ),	// top left
			RageVector2( f[2],	f[3] ),	// bottom left
			RageVector2( f[4],	f[5] ),	// bottom right
			RageVector2( f[6],	f[7] ) 	// top right
		};
	

		if( crop.left!=0 )
		{
			v[0].t.x = SCALE( crop.left, 0.f, 1.f, texCoords[0].x, texCoords[3].x );
			v[1].t.x = SCALE( crop.left, 0.f, 1.f, texCoords[1].x, texCoords[2].x );
		}
		if( crop.right!=0 )
		{
			v[2].t.x = SCALE( crop.right, 0.f, 1.f, texCoords[2].x, texCoords[1].x );
			v[3].t.x = SCALE( crop.right, 0.f, 1.f, texCoords[3].x, texCoords[0].x );
		}
		if( crop.top!=0 )
		{
			v[0].t.y = SCALE( crop.top, 0.f, 1.f, texCoords[0].y, texCoords[1].y );
			v[3].t.y = SCALE( crop.top, 0.f, 1.f, texCoords[3].y, texCoords[2].y );
		}
		if( crop.bottom!=0 )
		{
			v[1].t.y = SCALE( crop.bottom, 0.f, 1.f, texCoords[1].y, texCoords[0].y );
			v[2].t.y = SCALE( crop.bottom, 0.f, 1.f, texCoords[2].y, texCoords[3].y );
		}
	}
	else
	{
		// Just make sure we don't throw NaN/INF at the renderer:
		for( unsigned i = 0; i < 4; ++i )
			v[i].t.x = v[i].t.y = 0;
	}

	/* Draw if we're not fully transparent */
	if( state->diffuse[0].a > 0 || 
		state->diffuse[1].a > 0 ||
		state->diffuse[2].a > 0 ||
		state->diffuse[3].a > 0 )
	{
		DISPLAY->SetTextureModeModulate();

		//////////////////////
		// render the shadow
		//////////////////////
		if( m_fShadowLength != 0 )
		{
			DISPLAY->PushMatrix();
			DISPLAY->TranslateWorld( m_fShadowLength, m_fShadowLength, 0 );	// shift by 5 units
			v[0].c = v[1].c = v[2].c = v[3].c = RageColor(0,0,0,0.5f*state->diffuse[0].a);	// semi-transparent black
			DISPLAY->DrawQuad( v );
			DISPLAY->PopMatrix();
		}

		//////////////////////
		// render the diffuse pass
		//////////////////////
		v[0].c = state->diffuse[0];	// top left
		v[1].c = state->diffuse[2];	// bottom left
		v[2].c = state->diffuse[3];	// bottom right
		v[3].c = state->diffuse[1];	// top right
		DISPLAY->DrawQuad( v );
	}

	//////////////////////
	// render the glow pass
	//////////////////////
	if( state->glow.a > 0.0001f )
	{
		DISPLAY->SetTextureModeGlow();
		v[0].c = v[1].c = v[2].c = v[3].c = state->glow;
		DISPLAY->DrawQuad( v );
	}
}