#include"CGraphic.h"

//	ここのソースには 3DBLT系

static const float TexelClip = 0.5f;

namespace Maid
{

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ空間上の指定した矩形を単色で塗りつぶす
/*!
 	SetBltState() で設定した描画モードで行われます
 
 	@param	Rect	[i ]	塗りつぶし範囲
 	@param	Scale	[i ]	拡縮率 1.0 で等倍
 	@param	Rotate	[i ]	回転量（ラジアン）
 	@param	vec		[i ]	回転軸（正規化しておくこと）
 	@param	Center	[i ]	基準となる(Rect.Left,Rect.Top)を(0,0)としたオフセット
 	@param	ColorLT	[i ]	描画する左上の色
 	@param	ColorRT	[i ]	描画する左上の色
 	@param	ColorLB	[i ]	描画する左上の色
 	@param	ColorRB	[i ]	描画する左上の色
 */
void CGraphic::Fill3DSR( const POINT3DF& Pos, const SIZE2DF& Size, const SIZE2DF& Scale, float Rotate, const VECTOR3DF& vec, const POINT3DF& Center, const COLOR_A08R08G08B08I& ColorLT, const COLOR_A08R08G08B08I& ColorRT, const COLOR_A08R08G08B08I& ColorLB, const COLOR_A08R08G08B08I& ColorRB )
{
	const MATRIX4DF wold = MATRIX4DF().SetScale( Scale.w, Scale.h, 0 )
						 * MATRIX4DF().SetRotationXYZ( Rotate, vec )
						 * MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z )
						 ;

	Fill3D( wold, Size, Center, ColorLT, ColorRT, ColorLB, ColorRB );
}



void CGraphic::Fill3D( const MATRIX4DF& mat, const SIZE2DF& Size, const POINT3DF& Center, const COLOR_A08R08G08B08I& ColorLT, const COLOR_A08R08G08B08I& ColorRT, const COLOR_A08R08G08B08I& ColorLB, const COLOR_A08R08G08B08I& ColorRB )
{
	const float l =  - Center.x;
	const float r =  Size.w - Center.x;
	const float t =  -Center.y;
	const float b =  Size.h - Center.y;
	const float z =  -Center.z;


	const CUSTOMVERTEX_3DCOLOR	Sprite[] =
	{
		CUSTOMVERTEX_3DCOLOR(POINT3DF(l, -t, z), ColorLT ),
		CUSTOMVERTEX_3DCOLOR(POINT3DF(r, -t, z), ColorRT ),
		CUSTOMVERTEX_3DCOLOR(POINT3DF(l, -b, z), ColorLB ),
		CUSTOMVERTEX_3DCOLOR(POINT3DF(r, -b, z), ColorRB ),
	};

	SetRenderStateZWriteEnable(m_IsBlt3DZTest);
	SetRenderStateZTestEnable(m_IsBlt3DZTest);
	SetCullingMode(CULLINGMODE_NONE);

	const MATRIX4DF m = mat * m_CameraMatrix;

	m_VertexShaderBlt3D[0].SetConstantF( 0, m.GetTranspose() );

	UnsetAllTexture();
	SetVertexShader( m_VertexShaderBlt3D[0] );
	SetPixelShader( m_PixelShaderFill[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );

}



/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形描画
/*!
 	設定したカメラクラスの設定描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3D( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const POINT3DF& Center, unt08 Alpha )
{
	const MATRIX4DF trance = MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );

	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIX4DF m	= m_Blt3DParentMatrix
						* trance;

	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}




/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形拡縮描画
/*!
 	設定したカメラクラスの設定描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Scale	[i ]	拡縮率
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3DS( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, const POINT3DF& Center, unt08 Alpha )
{
	const MATRIX4DF trance = MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );
	const MATRIX4DF scale  = MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f );
	
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIX4DF m	= m_Blt3DParentMatrix
						* scale * trance;


	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形回転描画
/*!
 	設定したカメラクラスの設定描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Rotate	[i ]	回転量
 	@param	vec		[i ]	回転軸
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3DR ( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, float Rotate, const VECTOR3DF& vec, const POINT3DF& Center, unt08 Alpha )
{
	const MATRIX4DF trance = MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );
	const MATRIX4DF rot    = MATRIX4DF().SetRotationXYZ( Rotate, vec );
	
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIX4DF m	= m_Blt3DParentMatrix
						* rot * trance;


	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形回転拡縮描画
/*!
 	設定したカメラクラスの設定で描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Scale	[i ]	拡縮率
 	@param	Rotate	[i ]	回転量
 	@param	vec		[i ]	回転軸
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3DSR( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float Rotate, const VECTOR3DF& vec, const POINT3DF& Center, unt08 Alpha )
{
	const MATRIX4DF trance = MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );
	const MATRIX4DF rot    = MATRIX4DF().SetRotationXYZ( Rotate, vec );
	const MATRIX4DF scale  = MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f );

	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIX4DF m	= m_Blt3DParentMatrix
						* scale * rot * trance;


	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}

#if 0

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形回転拡縮描画
/*!
 	設定したカメラクラスの設定で描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Rotate	[i ]	回転量(Ｘ軸)
 	@param	Rotate	[i ]	回転量(Ｙ軸)
 	@param	Rotate	[i ]	回転量(Ｚ軸)
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3DR ( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, float RotateX, float RotateY, float RotateZ, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, m_Blt3DParentMatrix );

	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ３Ｄ矩形回転拡縮描画
/*!
 	設定したカメラクラスの設定で描画されます
 
 	@param	Pos		[i ]	転送先座標
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Scale	[i ]	拡縮率
 	@param	Rotate	[i ]	回転量(Ｘ軸)
 	@param	Rotate	[i ]	回転量(Ｙ軸)
 	@param	Rotate	[i ]	回転量(Ｚ軸)
 	@param	Center	[i ]	オフセット
 	@param	Alpha	[i ]	不透明度 0xFF で完全に見える（デフォルトで0xFF)
 */
void CGraphic::Blt3DSR( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateX, float RotateY, float RotateZ, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );



	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}


void CGraphic::Blt3DSXYZ( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateX, float RotateY, float RotateZ, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );


	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}


void CGraphic::Blt3DSXZY( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateX, float RotateZ, float RotateY, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );


	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}



void CGraphic::Blt3DSYXZ( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateY, float RotateX, float RotateZ, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );

	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}


void CGraphic::Blt3DSYZX( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateY, float RotateZ, float RotateX, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );

	Blt3D( Src, Rect, Center, Color, Color, Color, Color );
}


void CGraphic::Blt3DSZXY( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateZ, float RotateX, float RotateY, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
/*
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );
*/
	MATRIX4DF m = m_Blt3DParentMatrix
				* MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f )
				* MATRIX4DF().SetRotationY( RotateX )
				* MATRIX4DF().SetRotationX( RotateY )
				* MATRIX4DF().SetRotationZ( RotateZ )
				* MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );

	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}


void CGraphic::Blt3DSZYX( const POINT3DF& Pos, const CTexture& Src, const RECT2DI& Rect, const SIZE2DF& Scale, float RotateZ, float RotateY, float RotateX, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
/*
	const MATRIXPOSITION pos = MATRIXPOSITION_WORLD0;

	SetMatrix( pos, MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z ) );
	MulMatrix( pos, MATRIX4DF().SetRotationZ( RotateZ ) );
	MulMatrix( pos, MATRIX4DF().SetRotationY( RotateY ) );
	MulMatrix( pos, MATRIX4DF().SetRotationX( RotateX ) );
	MulMatrix( pos, MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f ) );
	MulMatrix( pos, m_Blt3DParentMatrix );
*/

	MATRIX4DF m = m_Blt3DParentMatrix
				* MATRIX4DF().SetScale( Scale.w, Scale.h, 0.0f )
				* MATRIX4DF().SetRotationX( RotateX )
				* MATRIX4DF().SetRotationY( RotateY )
				* MATRIX4DF().SetRotationZ( RotateZ )
				* MATRIX4DF().SetTranslate( Pos.x-TexelClip, Pos.y+TexelClip, Pos.z );

	Blt3D( m, Src, Rect, Center, Color, Color, Color, Color );
}

#endif

void CGraphic::Blt3D  ( const MATRIX4DF& mat, const CTexture& Src, const RECT2DI& Rect, const POINT3DF& Center, unt08 Alpha )
{
	const COLOR_A08R08G08B08I Color(Alpha,0xFF,0xFF,0xFF);
	Blt3D( mat, Src, Rect, Center, Color, Color, Color, Color );
}








/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! ポリゴン描画する
/*!	
 	Blt3D 関係のまとめ関数です
 	すでに行列は設定されているものとします
 
 	@param	Src		[i ]	使用テクスチャ
 	@param	Rect	[i ]	使う矩形
 	@param	Center	[i ]	オフセット
 	@param	ColorLT	[i ]	左上の頂点カラー
 	@param	ColorRT	[i ]	右上の頂点カラー
 	@param	ColorLD	[i ]	左下の頂点カラー
 	@param	ColorRD	[i ]	右下の頂点カラー
 */
void CGraphic::Blt3D  ( const MATRIX4DF& mat, const CTexture& Src, const RECT2DI& Rect, const POINT3DF& Center, const COLOR_A08R08G08B08I& ColorLT, const COLOR_A08R08G08B08I& ColorRT, const COLOR_A08R08G08B08I& ColorLD, const COLOR_A08R08G08B08I& ColorRD  )
{
	const float Width  = (float)Rect.w;
	const float Height = (float)Rect.h; 

	const float vLeft  = 0.0f - Center.x;//-TexelClip;
	const float vTop   = 0.0f - Center.y;//-TexelClip;
	const float vRight = vLeft + Width;
	const float vBottom= vTop  + Height;
	const float vDepth = -Center.z;

	const SIZE2DI texsize = Src.GetTextureSize();

	const float tLeft  = (float)Rect.x  /(float)texsize.w;
	const float tTop   = (float)Rect.y  /(float)texsize.h;
	const float tRight = (float)Rect.GetRight() /(float)texsize.w;
	const float tBottom= (float)Rect.GetBottom()/(float)texsize.h;

	const CUSTOMVERTEX_3DSPRITE	Sprite[] =
	{
		CUSTOMVERTEX_3DSPRITE(POINT3DF(vLeft,  -vTop,	vDepth), ColorLT, POINT2DF(tLeft ,tTop   ) ),
		CUSTOMVERTEX_3DSPRITE(POINT3DF(vRight, -vTop,	vDepth), ColorRT, POINT2DF(tRight,tTop   ) ),
		CUSTOMVERTEX_3DSPRITE(POINT3DF(vLeft,  -vBottom, vDepth), ColorLD, POINT2DF(tLeft ,tBottom) ),
		CUSTOMVERTEX_3DSPRITE(POINT3DF(vRight, -vBottom, vDepth), ColorRD, POINT2DF(tRight,tBottom) ),
	};

	SetRenderStateZWriteEnable(m_IsBlt3DZTest);
	SetRenderStateZTestEnable(m_IsBlt3DZTest);
	SetCullingMode(CULLINGMODE_NONE);
	SetSamplerStateMagFilter( 0, m_FilterType );
	SetSamplerStateMinFilter( 0, m_FilterType );

	const MATRIX4DF m = mat * m_CameraMatrix;

	m_VertexShaderBlt3D[0].SetConstantF( 0, m.GetTranspose() );

	SetTexture( Src );
	SetVertexShader( m_VertexShaderBlt3D[0] );
	SetPixelShader( m_PixelShaderBlt[m_BltState] );
	DrawPrimitiveUP( PRIMITIVE_TRIANGLESTRIP, Sprite, Sprite[0].GetStructSize(), 2 );
}

}