Esempio n. 1
0
void ETHParallaxManager::SetShaderParameters(const VideoConstPtr& video, const ShaderPtr& shader, const Vector3& entityPos,
											 const float& individualParallaxIntensity, const bool drawToTarget) const
{
	if (!drawToTarget)
	{
		const float parallaxIntensity = GetIntensity() * individualParallaxIntensity;
		#ifdef GLES2
			shader->SetConstant(GS_L("entityPos3D_parallaxIntensity"), Vector4(entityPos, parallaxIntensity));
		#else
			shader->SetConstant(GS_L("entityPos3D"), entityPos);
			shader->SetConstant(GS_L("parallaxIntensity"), parallaxIntensity);
		#endif
		shader->SetConstant(GS_L("parallaxOrigin_verticalIntensity"), Vector3(GetInScreenOrigin(video), GetVerticalIntensity()));
	}
	else
	{
		shader->SetConstant(GS_L("parallaxIntensity"), 0.0f);
	}
}
Esempio n. 2
0
void GLSprite::BeginFastRendering()
{
	GLVideo* video = m_video.lock().get();
	video->SetVertexShader(video->GetFontShader());
	ShaderPtr pCurrentVS = video->GetVertexShader();
	pCurrentVS->SetConstant("bitmapSize", GetBitmapSizeF());

	// apply textures according to the rendering mode (pixel shaded or not)
	ShaderPtr pCurrentPS = video->GetPixelShader();
	SetDiffuseTexture(pCurrentPS);
}
Esempio n. 3
0
bool ETHVertexLightDiffuse::BeginLightPass(ETHSpriteEntity *pRender, Vector3 &v3LightPos, const Vector2 &v2Size,
	const ETHLight* light, const float maxHeight, const float minHeight, const float lightIntensity,
	const bool drawToTarget)
{
	GS2D_UNUSED_ARGUMENT(drawToTarget);
	const Vector2 &v2Origin = pRender->ComputeOrigin(v2Size);
	const Vector3 &v3EntityPos = pRender->GetPosition();

	m_video->SetPixelShader(ShaderPtr());

	ShaderPtr pLightShader;

	if (pRender->GetType() == ETH_VERTICAL)
	{
		m_vVertexLightVS->SetConstant(GS_L("spaceLength"), (maxHeight-minHeight));
		m_vVertexLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-(Vector3(v2Origin.x, 0, -v2Origin.y)));
		pLightShader = m_vVertexLightVS;
	}
	else
	{
		m_hVertexLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-Vector3(v2Origin, 0));
		pLightShader = m_hVertexLightVS;
	}
	m_video->SetVertexShader(pLightShader);

	m_lastAM = m_video->GetAlphaMode();
	m_video->SetAlphaMode(GSAM_ADD);

	// Set a depth value depending on the entity type
	pRender->SetDepth(maxHeight, minHeight);
 
	pLightShader->SetConstant(GS_L("pivotAdjust"), pRender->GetProperties()->pivotAdjust);
	pLightShader->SetConstant(GS_L("lightPos"), v3LightPos);
	pLightShader->SetConstant(GS_L("lightRange"), light->range);
	pLightShader->SetConstant(GS_L("lightColor"), light->color);
	pLightShader->SetConstant(GS_L("lightIntensity"), lightIntensity);
	return true;
}
Esempio n. 4
0
bool D3D9Sprite::DrawShapedFast(const Vector2 &v2Pos, const Vector2 &v2Size, const Color& color)
{
	if (v2Size == Vector2(0,0))
	{
		return true;
	}

	Video* video = m_video.lock().get();
	ShaderPtr pCurrentVS = video->GetVertexShader();

	// rounds up the final position to avoid alpha distortion
	Vector2 v2FinalPos;
	if (video->IsRoundingUpPosition())
	{
		v2FinalPos.x = floor(v2Pos.x);
		v2FinalPos.y = floor(v2Pos.y);
	}
	else
	{
		v2FinalPos = v2Pos;
	}

	// subtract 0.5 to align pixel-texel
	v2FinalPos -= math::constant::HALF_VECTOR2;

	pCurrentVS->SetConstant(L"size", v2Size);
	pCurrentVS->SetConstant(L"entityPos", v2FinalPos);
	pCurrentVS->SetConstant(L"color0", color);

	if (m_rect.size.x == 0 || m_rect.size.y == 0)
	{
		pCurrentVS->SetConstant(L"rectSize", GetBitmapSizeF());
		pCurrentVS->SetConstant(L"rectPos", 0, 0);
	}
	else
	{
		pCurrentVS->SetConstant(L"rectSize", m_rect.size);
		pCurrentVS->SetConstant(L"rectPos", m_rect.pos);
	}

	pCurrentVS->SetShader();

	// draw the one-pixel-quad applying the vertex shader
	m_pVideoInfo->DrawSpriteFast(m_pDevice, m_rectMode);

	return true;
}
Esempio n. 5
0
bool GLSprite::DrawShapedFast(const math::Vector2 &v2Pos, const math::Vector2 &v2Size, const Color& color)
{
	if (v2Size == math::Vector2(0,0))
	{
		return true;
	}

	GLVideo* video = m_video.lock().get();
	ShaderPtr pCurrentVS = video->GetVertexShader();

	// rounds up the final position to avoid alpha distortion
	math::Vector2 v2FinalPos;
	if (video->IsRoundingUpPosition())
	{
		v2FinalPos.x = floor(v2Pos.x);
		v2FinalPos.y = floor(v2Pos.y);
	}
	else
	{
		v2FinalPos = v2Pos;
	}

	pCurrentVS->SetConstant("size", v2Size);
	pCurrentVS->SetConstant("entityPos", v2FinalPos);
	pCurrentVS->SetConstant("color0", color);

	if (m_rect.size.x == 0 || m_rect.size.y == 0)
	{
		pCurrentVS->SetConstant("rectSize", GetBitmapSizeF());
		pCurrentVS->SetConstant("rectPos", 0, 0);
	}
	else
	{
		pCurrentVS->SetConstant("rectSize", m_rect.size);
		pCurrentVS->SetConstant("rectPos", m_rect.pos);
	}

	pCurrentVS->SetShader();

	video->GetRectRenderer().Draw(m_rectMode);
	return true;
}
Esempio n. 6
0
void D3D9Sprite::BeginFastRendering()
{
	Video* video = m_video.lock().get();
	video->SetVertexShader(video->GetFontShader());
	ShaderPtr pCurrentVS = video->GetVertexShader();
	pCurrentVS->SetConstant(L"bitmapSize", GetBitmapSizeF());

	// apply textures according to the rendering mode (pixel shaded or not)
	ShaderPtr pCurrentPS = video->GetPixelShader();
	if (!pCurrentPS)
	{
		m_pDevice->SetTexture(0, m_pTexture);
		//for (unsigned int t=1; t<GS_TEXTURE_CHANNELS; t++)
		//	pDevice->SetTexture(t, NULL);
	}
	else
	{
		pCurrentPS->SetShader();
		pCurrentPS->SetTexture(L"diffuse", GetTexture());
	}
	m_pVideoInfo->BeginFastDraw(m_pDevice, m_rectMode);
}
Esempio n. 7
0
void GLVideo::UpdateShaderViewData(const ShaderPtr& shader, const math::Vector2& screenSize, const math::Matrix4x4& ortho)
{
	shader->SetConstant("screenSize", screenSize);
	shader->SetMatrixConstant("viewMatrix", ortho);
}
Esempio n. 8
0
bool ETHRenderEntity::DrawProjShadow(const float maxHeight, const float minHeight, const ETHSceneProperties& sceneProps, const ETHLight& light, ETHSpriteEntity *pParent,
									 const bool maxOpacity, const bool drawToTarget, const float targetAngle, const Vector3& v3TargetPos)
{
	if (!m_pSprite || IsHidden())
		return false;

	VideoPtr video = m_provider->GetVideo();
	ETHShaderManagerPtr shaderManager = m_provider->GetShaderManager();
	SpritePtr pShadow = shaderManager->GetProjShadow();

	Vector3 v3LightPos;
	Vector3 v3ParentPos(0,0,0);

	const Vector3 v3EntityPos = GetPosition();

	if (pParent)
	{
		v3ParentPos = pParent->GetPosition();
		v3LightPos = Vector3(v3ParentPos.x, v3ParentPos.y, 0) + light.pos;
	}
	else
	{
		v3LightPos = light.pos;
	}

	// if the object is higher than the light, then the shadow shouldn't be cast on the floor
	if (v3LightPos.z < v3EntityPos.z)
	{
		return true;
	}

	const float scale = (m_properties.shadowScale <= 0.0f) ? 1.0f : m_properties.shadowScale;
	const float opacity = (m_properties.shadowOpacity <= 0.0f) ? 1.0f : m_properties.shadowOpacity;
	const Vector2 v2Size = GetCurrentSize();
	Vector2 v2ShadowSize(v2Size.x, v2Size.y);
	Vector2 v2ShadowPos(v3EntityPos.x, v3EntityPos.y);

	// if we are drawing to a target of a rotated entity
	if (drawToTarget && targetAngle != 0)
	{
		// rotate the shadow position according to entity angle
		Matrix4x4 matRot = RotateZ(-DegreeToRadian(targetAngle));
		Vector3 newShadowPos(v2ShadowPos, 0);
		newShadowPos = newShadowPos - v3TargetPos;
		newShadowPos = Multiply(newShadowPos, matRot);
		newShadowPos = newShadowPos + v3TargetPos;
		v2ShadowPos.x = newShadowPos.x;
		v2ShadowPos.y = newShadowPos.y;

		// rotate the light source to cast it correctly
		Vector3 newPos = v3LightPos - v3TargetPos;
		newPos = Multiply(newPos, matRot);
		v3LightPos = newPos + v3TargetPos;
	}

	Vector3 diff = v3EntityPos - v3LightPos;
	const float squaredDist = DP3(diff, diff);
	float squaredRange = light.range * light.range;

	if (squaredDist > squaredRange)
	{
		return true;
	}

	v2ShadowSize.x *= _ETH_SHADOW_SCALEX * scale;

	// calculate the correct shadow length according to the light height
	if ((GetPosition().z+v2Size.y) < light.pos.z) // if the light is over the entity
	{
		const float planarDist = Distance(GetPositionXY(), ETHGlobal::ToVector2(v3LightPos));
		const float verticalDist = Abs((v3EntityPos.z+v2Size.y)-v3LightPos.z);
		const float totalDist = (planarDist/verticalDist)*Abs(v3LightPos.z);
		v2ShadowSize.y = totalDist-planarDist;

		// clamp shadow length to the object's height. This is not realistic
		// but it looks better for the real-time shadows.
		v2ShadowSize.y = Min(v2Size.y*_ETH_SHADOW_FAKE_STRETCH, v2ShadowSize.y);
	}
	else
	{
		v2ShadowSize.y *= ((drawToTarget) ? _ETH_SHADOW_SCALEY : _ETH_SHADOW_SCALEY/4);
	}

	// specify a minimum length for the shadow
	v2ShadowSize.y = Max(v2ShadowSize.y, v2Size.y);

	ShaderPtr pVS = video->GetVertexShader();
	pVS->SetConstant(GS_L("shadowLength"), v2ShadowSize.y * m_properties.shadowLengthScale);
	pVS->SetConstant(GS_L("entityZ"), Max(m_shadowZ, v3EntityPos.z));
	pVS->SetConstant(GS_L("shadowZ"), m_shadowZ);
	pVS->SetConstant(GS_L("lightPos"), v3LightPos);
	video->SetSpriteDepth(
		(GetType() == ETHEntityProperties::ET_VERTICAL) ?
		ETHEntity::ComputeDepth(m_shadowZ, maxHeight, minHeight)
		: Max(0.0f, ComputeDepth(maxHeight, minHeight) - m_layrableMinimumDepth));

	v2ShadowSize.y = 1.0f;

	Vector2 lightPos2(v3LightPos.x, v3LightPos.y);
	const float shadowAngle = ::GetAngle((lightPos2 - Vector2(v3EntityPos.x, v3EntityPos.y))) + DegreeToRadian(targetAngle);

	squaredRange = Max(squaredDist, squaredRange);
	float attenBias = 1;

	// adjust brightness according to ambient light
	if (!maxOpacity)
	{
		attenBias = (1-(squaredDist/squaredRange));
		//fade the color according to the light brightness
		const float colorLen = Max(Max(light.color.x, light.color.y), light.color.z);
		attenBias *= Min(colorLen, 1.0f);

		//fade the color according to the ambient light brightness
		const Vector3 &ambientColor = sceneProps.ambient;
		const float ambientColorLen = 1.0f-((ambientColor.x + ambientColor.y + ambientColor.z)/3.0f);
		attenBias = Min(attenBias*ambientColorLen, 1.0f);
		attenBias *= Max(Min((1-(GetPosition().z/Max(GetCurrentSize().y, 1.0f))), 1.0f), 0.0f);
	}

	GS_BYTE alpha = static_cast<GS_BYTE>(attenBias*255.0f*opacity);

	if (alpha < 8)
		return true;

	Color dwShadowColor(alpha,255,255,255);

	pShadow->SetOrigin(Vector2(0.5f, 0.79f));
	pShadow->SetRectMode(Sprite::RM_THREE_TRIANGLES);
	pShadow->DrawShaped(v2ShadowPos, v2ShadowSize,
		dwShadowColor, dwShadowColor, dwShadowColor, dwShadowColor,
		RadianToDegree(shadowAngle));

	return true;
}
bool ETHPixelLightDiffuseSpecular::BeginLightPass(ETHSpriteEntity *pRender, Vector3 &v3LightPos, const Vector2 &v2Size,
	const ETHLight* light, const float maxHeight, const float minHeight, const float lightIntensity, const bool drawToTarget)
{
	const Vector2 &v2Origin = pRender->ComputeOrigin(v2Size);
	const Vector3 &v3EntityPos = pRender->GetPosition();

	// set the correct light shader
	ShaderPtr pLightShader;
	const bool hasGloss = pRender->GetGloss();
	if (pRender->GetType() == ETH_VERTICAL)
	{
		if (hasGloss)
		{
			pLightShader = m_vPixelLightSpecularPS;
		}
		else
		{
			pLightShader = m_vPixelLightPS;
		}
	}
	else
	{
		if (hasGloss)
		{
			pLightShader = m_hPixelLightSpecularPS;
		}
		else
		{
			pLightShader = m_hPixelLightPS;
		}
	}

	// if it has a gloss map, send specular data to shader
	if (hasGloss)
	{
		pLightShader->SetConstant(GS_L("specularPower"), pRender->GetSpecularPower());
		pLightShader->SetConstant(GS_L("specularBrightness"), pRender->GetSpecularBrightness());
		pLightShader->SetTexture(GS_L("glossMap"), pRender->GetGloss()->GetTexture());
		pLightShader->SetConstant(GS_L("fakeEyePos"), m_fakeEyeManager->ComputeFakeEyePosition(m_video, pLightShader, drawToTarget, v3LightPos, pRender->GetAngle()));
	}

	// choose which normalmap to use
	m_video->SetPixelShader(pLightShader);
	if (pRender->GetNormal())
	{
		pLightShader->SetTexture(GS_L("normalMap"), pRender->GetNormal()->GetTexture());
	}
	else
	{
		pLightShader->SetTexture(GS_L("normalMap"), GetDefaultNormalMap()->GetTexture());
	}

	// sets spatial information to the shader
	if (pRender->GetType() == ETH_VERTICAL)
	{
		m_vPixelLightVS->SetConstant(GS_L("spaceLength"), (maxHeight-minHeight));
		m_vPixelLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-(Vector3(v2Origin.x,0,-v2Origin.y)));
		m_video->SetVertexShader(m_vPixelLightVS);
	}
	else
	{
		m_hPixelLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-Vector3(v2Origin,0));
		m_video->SetVertexShader(m_hPixelLightVS);
	}

	const Vector2 v2ScreenDim = (drawToTarget) ? pRender->GetLightmap()->GetBitmapSizeF() : m_video->GetScreenSizeF();

	if (pRender->GetType() != ETH_VERTICAL)
	{
		if (pRender->GetAngle() != 0.0f)
		{
			Vector3 newPos = v3LightPos-v3EntityPos;
			Matrix4x4 matRot = RotateZ(-DegreeToRadian(pRender->GetAngle()));
			newPos = Multiply(newPos, matRot);
			v3LightPos = newPos + v3EntityPos;
		}
	}

	m_lastAM = m_video->GetAlphaMode();
	m_video->SetAlphaMode(GSAM_ADD);

	// Set a depth value depending on the entity type
	pRender->SetDepth(maxHeight, minHeight);
 
	pLightShader->SetConstant(GS_L("lightPos"), v3LightPos);
	pLightShader->SetConstant(GS_L("squaredRange"), light->range * light->range);
	pLightShader->SetConstant(GS_L("lightColor"), Vector4(light->color, 1.0f) * lightIntensity);

	return true;
}
bool ETHPixelLightDiffuseSpecular::BeginLightPass(ETHSpriteEntity *pRender, Vector3 &v3LightPos, const Vector2 &v2Size,
	const ETHLight* light, const float maxHeight, const float minHeight, const float lightIntensity, const bool drawToTarget)
{
	const Vector2 &v2Origin = pRender->ComputeAbsoluteOrigin(v2Size);
	const Vector3 &v3EntityPos = pRender->GetPosition();

	// set the correct light shader
	ShaderPtr pLightShader;
	const bool hasGloss = pRender->GetGloss();
	if (pRender->GetType() == ETHEntityProperties::ET_VERTICAL)
	{
		if (hasGloss)
		{
			pLightShader = m_vPixelLightSpecularPS;
		}
		else
		{
			pLightShader = m_vPixelLightPS;
		}
	}
	else
	{
		if (hasGloss)
		{
			pLightShader = m_hPixelLightSpecularPS;
		}
		else
		{
			pLightShader = m_hPixelLightPS;
		}
	}

	// if it has a gloss map, send specular data to shader
	if (hasGloss)
	{
		pLightShader->SetConstant(GS_L("specularPower"), pRender->GetSpecularPower());
		pLightShader->SetConstant(GS_L("specularBrightness"), pRender->GetSpecularBrightness());
		pLightShader->SetTexture(GS_L("glossMap"), pRender->GetGloss()->GetTexture());
		pLightShader->SetConstant(GS_L("fakeEyePos"), m_fakeEyeManager->ComputeFakeEyePosition(m_video, pLightShader, drawToTarget, v3LightPos, pRender->GetAngle()));
	}

	// choose which normalmap to use
	m_video->SetPixelShader(pLightShader);
	if (pRender->GetNormal())
	{
		pLightShader->SetTexture(GS_L("normalMap"), pRender->GetNormal()->GetTexture());
	}
	else
	{
		pLightShader->SetTexture(GS_L("normalMap"), GetDefaultNormalMap()->GetTexture());
	}

	// sets spatial information to the shader
	if (pRender->GetType() == ETHEntityProperties::ET_VERTICAL)
	{
		m_vPixelLightVS->SetConstant(GS_L("spaceLength"), (maxHeight-minHeight));
		m_vPixelLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-(Vector3(v2Origin.x,0,-v2Origin.y)));
		m_video->SetVertexShader(m_vPixelLightVS);
	}
	else
	{
		m_hPixelLightVS->SetConstant(GS_L("topLeft3DPos"), v3EntityPos-Vector3(v2Origin,0));
		m_video->SetVertexShader(m_hPixelLightVS);
	}

	// TO-DO it looks like a mess around here...
	if (pRender->GetType() != ETHEntityProperties::ET_VERTICAL)
	{
		if (pRender->GetAngle() != 0.0f)
		{
			Vector3 newPos = v3LightPos-v3EntityPos;
			Matrix4x4 matRot = RotateZ(-DegreeToRadian(pRender->GetAngle()));
			newPos = Multiply(newPos, matRot);
			v3LightPos = newPos + v3EntityPos;
		}
	}

	m_lastAM = m_video->GetAlphaMode();
	m_video->SetAlphaMode(Video::AM_ADD);

	// Set a depth value depending on the entity type
	pRender->SetDepth(maxHeight, minHeight);
 
 	// downscales pixel shader ranges on android to prevent from lower precision glitches
 	float lightPrecisionDownScale = 1.0f;
 	#ifdef GLES2
	 	lightPrecisionDownScale = LIGHT_PRECISION_DOWNSCALE;
 	#endif

	pLightShader->SetConstant(GS_L("lightPos"), v3LightPos * lightPrecisionDownScale);

	const float scaledRange = (light->range * lightPrecisionDownScale);
	pLightShader->SetConstant(GS_L("squaredRange"), scaledRange * scaledRange);
	pLightShader->SetConstant(GS_L("lightColor"), Vector4(light->color, 1.0f) * lightIntensity);

	return true;
}
Esempio n. 11
0
bool D3D9Sprite::DrawShaped(
	const Vector2& v2Pos,
	const Vector2& v2Size,
	const Color& color0,
	const Color& color1,
	const Color& color2,
	const Color& color3,
	const float angle)
{
	if (v2Size == Vector2(0,0))
	{
		return true;
	}

	// do the flip (parameters that will be send to the VS)
	Vector2 flipMul(1,1), flipAdd(0,0);
	if (m_flipX)
	{
		flipMul.x =-1;
		flipAdd.x = 1;
	}
	if (m_flipY)
	{
		flipMul.y =-1;
		flipAdd.y = 1;
	}

	// centralizes the sprite according to the origin
	Vector2 v2Center = m_normalizedOrigin*v2Size;

	Video* video = m_video.lock().get();
	ShaderPtr pCurrentVS = video->GetVertexShader();

	Matrix4x4 mRot;
	if (angle != 0.0f)
		mRot = RotateZ(DegreeToRadian(angle));
	pCurrentVS->SetMatrixConstant(L"rotationMatrix", mRot);

	// rounds up the final position to avoid alpha distortion
	Vector2 v2FinalPos;
	if (video->IsRoundingUpPosition())
	{
		v2FinalPos.x = floor(v2Pos.x);
		v2FinalPos.y = floor(v2Pos.y);
	}
	else
	{
		v2FinalPos = v2Pos;
	}

	// subtract 0.5 to align pixel-texel
	v2FinalPos -= math::constant::HALF_VECTOR2;

	pCurrentVS->SetConstant(L"size", v2Size);
	pCurrentVS->SetConstant(L"entityPos", v2FinalPos);
	pCurrentVS->SetConstant(L"center", v2Center);
	pCurrentVS->SetConstant(L"flipMul", flipMul);
	pCurrentVS->SetConstant(L"flipAdd", flipAdd);
	pCurrentVS->SetConstant(L"bitmapSize", GetBitmapSizeF());
	pCurrentVS->SetConstant(L"scroll", GetScroll());
	pCurrentVS->SetConstant(L"multiply", GetMultiply());

	const bool setCameraPos = pCurrentVS->ConstantExist(L"cameraPos");
	if (setCameraPos)
		pCurrentVS->SetConstant(L"cameraPos", video->GetCameraPos());

	if (m_rect.size.x == 0 || m_rect.size.y == 0)
	{
		pCurrentVS->SetConstant(L"rectSize", GetBitmapSizeF());
		pCurrentVS->SetConstant(L"rectPos", 0, 0);
	}
	else
	{
		pCurrentVS->SetConstant(L"rectSize", m_rect.size);
		pCurrentVS->SetConstant(L"rectPos", m_rect.pos);
	}

	pCurrentVS->SetConstant(L"color0", color0);
	pCurrentVS->SetConstant(L"color1", color1);
	pCurrentVS->SetConstant(L"color2", color2);
	pCurrentVS->SetConstant(L"color3", color3);

	if (pCurrentVS->ConstantExist(L"depth"))
		pCurrentVS->SetConstant(L"depth", video->GetSpriteDepth());

	pCurrentVS->SetShader();

	// apply textures according to the rendering mode (pixel shaded or not)
	ShaderPtr pCurrentPS = video->GetPixelShader();
	if (!pCurrentPS)
	{
		m_pDevice->SetTexture(0, m_pTexture);
		//for (unsigned int t=1; t<GS_TEXTURE_CHANNELS; t++)
		//	pDevice->SetTexture(t, NULL);
	}
	else
	{
		pCurrentPS->SetShader();
		pCurrentPS->SetTexture(L"diffuse", GetTexture());
	}

	// draw the one-pixel-quad applying the vertex shader
	m_pVideoInfo->DrawSprite(m_pDevice, m_rectMode);

	m_pDevice->SetVertexShader(NULL);

	return true;
}
Esempio n. 12
0
bool GLSprite::DrawShaped(
	const math::Vector2 &v2Pos,
	const math::Vector2 &v2Size,
	const Color& color0,
	const Color& color1,
	const Color& color2,
	const Color& color3,
	const float angle)
{
	if (v2Size == math::Vector2(0,0))
	{
		return true;
	}

	// compute flip parameters that will be sent to the VS
	math::Vector2 flipMul, flipAdd;
	GetFlipShaderParameters(flipAdd, flipMul);

	// centralizes the sprite according to the origin
	math::Vector2 v2Center = m_normalizedOrigin * v2Size;

	GLVideo* video = m_video.lock().get();
	ShaderPtr pCurrentVS = video->GetVertexShader();

	math::Matrix4x4 mRot;
	if (angle != 0.0f)
		mRot = math::RotateZ(math::DegreeToRadian(angle));
	pCurrentVS->SetMatrixConstant("rotationMatrix", mRot);

	// rounds up the final position to avoid alpha distortion
	math::Vector2 v2FinalPos;
	if (video->IsRoundingUpPosition())
	{
		v2FinalPos.x = floor(v2Pos.x);
		v2FinalPos.y = floor(v2Pos.y);
	}
	else
	{
		v2FinalPos = v2Pos;
	}

	pCurrentVS->SetConstant("size", v2Size);
	pCurrentVS->SetConstant("entityPos", v2FinalPos);
	pCurrentVS->SetConstant("center", v2Center);
	pCurrentVS->SetConstant("flipMul", flipMul);
	pCurrentVS->SetConstant("flipAdd", flipAdd);
	pCurrentVS->SetConstant("bitmapSize", GetBitmapSizeF());
	pCurrentVS->SetConstant("scroll", GetScroll());
	pCurrentVS->SetConstant("multiply", GetMultiply());

	const bool setCameraPos = pCurrentVS->ConstantExist("cameraPos");
	if (setCameraPos)
		pCurrentVS->SetConstant("cameraPos", video->GetCameraPos());

	if (m_rect.size.x == 0 || m_rect.size.y == 0)
	{
		pCurrentVS->SetConstant("rectSize", GetBitmapSizeF());
		pCurrentVS->SetConstant("rectPos", 0, 0);
	}
	else
	{
		pCurrentVS->SetConstant("rectSize", m_rect.size);
		pCurrentVS->SetConstant("rectPos", m_rect.pos);
	}

	pCurrentVS->SetConstant("color0", color0);
	pCurrentVS->SetConstant("color1", color1);
	pCurrentVS->SetConstant("color2", color2);
	pCurrentVS->SetConstant("color3", color3);

	if (pCurrentVS->ConstantExist("depth"))
		pCurrentVS->SetConstant("depth", video->GetSpriteDepth());

	// apply textures according to the rendering mode (pixel shaded or not)
	ShaderPtr pCurrentPS = video->GetPixelShader();
	SetDiffuseTexture(pCurrentPS);

	pCurrentVS->SetShader();

	// draw the one-pixel-quad applying the vertex shader
	video->GetRectRenderer().Draw(m_rectMode);

	return true;
}