#include "stdafx.h"
#include "DrawTexture.h"
#include "valMatrix.h"

namespace FDK
{
	// 以下はすべてD3Dデバイスがロックされている前提で呼び出されるのでスレッドセーフと見なす。

// public:

	HRESULT DrawTexture::t3D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, D3DMATRIX* pMatrix, LPRECT prc画像内の描画領域 )
	{
		if( ( NULL == pDevice ) || ( NULL == pTexture ) )
			return E_POINTER;

		HRESULT hr = S_OK;
		D3DSURFACE_DESC desc;

		
		// 物理縮小倍率を行列に反映。


		D3DXMATRIX matrix( *pMatrix );	// D3DXMATRIX は D3DMATRIX を継承する。
		
		D3DXMATRIX scaling;				// スケーリング
		::D3DXMatrixIdentity( &scaling );
		::D3DXMatrixScaling( &scaling, DrawTexture::f物理縮小倍率, DrawTexture::f物理縮小倍率, DrawTexture::f物理縮小倍率 );
		matrix *= scaling;

		BREAKABLE_BLOCK
		{
			if( FAILED( hr = pTexture->GetLevelDesc( 0, &desc ) ) )
				break;

			float x = ( (float) ( prc画像内の描画領域->right - prc画像内の描画領域->left ) ) / 2.0f;
			float y = ( (float) ( prc画像内の描画領域->bottom - prc画像内の描画領域->top ) ) / 2.0f;
			float z = 0.0f;
			float f左U値 = ( (float) prc画像内の描画領域->left ) / ( (float) desc.Width );
			float f右U値 = ( (float) prc画像内の描画領域->right ) / ( (float) desc.Width );
			float f上V値 = ( (float) prc画像内の描画領域->top ) / ( (float) desc.Height );
			float f下V値 = ( (float) prc画像内の描画領域->bottom ) / ( (float) desc.Height );
			DWORD color = ( (DWORD) ( n透明度0to255 ) << 24 ) | 0x00FFFFFF;

			pPositionColoredVertexies[ 0 ].u = f左U値;
			pPositionColoredVertexies[ 0 ].v = f上V値;
			pPositionColoredVertexies[ 0 ].x = -x;
			pPositionColoredVertexies[ 0 ].y = y;
			pPositionColoredVertexies[ 0 ].z = z;
			pPositionColoredVertexies[ 0 ].color = color;

			pPositionColoredVertexies[ 1 ].u = f右U値;
			pPositionColoredVertexies[ 1 ].v = f上V値;
			pPositionColoredVertexies[ 1 ].x = x;
			pPositionColoredVertexies[ 1 ].y = y;
			pPositionColoredVertexies[ 1 ].z = z;
			pPositionColoredVertexies[ 1 ].color = color;

			pPositionColoredVertexies[ 2 ].u = f左U値;
			pPositionColoredVertexies[ 2 ].v = f下V値;
			pPositionColoredVertexies[ 2 ].x = -x;
			pPositionColoredVertexies[ 2 ].y = -y;
			pPositionColoredVertexies[ 2 ].z = z;
			pPositionColoredVertexies[ 2 ].color = color;

			pPositionColoredVertexies[ 3 ].u = f右U値;
			pPositionColoredVertexies[ 3 ].v = f下V値;
			pPositionColoredVertexies[ 3 ].x = x;
			pPositionColoredVertexies[ 3 ].y = -y;
			pPositionColoredVertexies[ 3 ].z = z;
			pPositionColoredVertexies[ 3 ].color = color;

			if( FAILED( hr = DrawTexture::tレンダリングステートの設定( pDevice, b加算合成 ) ) ||
				FAILED( hr = pDevice->SetTransform( D3DTS_WORLD, &matrix ) ) ||						// ワールド行列の設定
				FAILED( hr = pDevice->SetTexture( 0, pTexture ) ) ||								// 描画テクスチャの設定
				FAILED( hr = pDevice->SetFVF( D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 ) ) ||		// 描画条件の設定(FVF)
				FAILED( hr = pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, pPositionColoredVertexies, sizeof( STPositionColoredVertexies ) ) )	// プリミティブの描画
				)
			{
				break;
			}
		}

		return hr;
	}
	HRESULT DrawTexture::t3D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, D3DMATRIX* pMatrix )
	{
		if( NULL == pTexture )
			return E_POINTER;

		HRESULT hr = S_OK;

		BREAKABLE_BLOCK
		{
			D3DSURFACE_DESC desc;
			RECT rc全画像;

			if( FAILED( hr = pTexture->GetLevelDesc( 0, &desc ) ) )
				break;

			rc全画像.left = 0;
			rc全画像.top = 0;
			rc全画像.right = desc.Width;
			rc全画像.bottom = desc.Height;

			if( FAILED( hr = DrawTexture::t3D描画( pDevice, pTexture, n透明度0to255, b加算合成, pMatrix, &rc全画像 ) ) )
				break;
		}

		return hr;
	}

	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, int x, int y, float depth, LPRECT prc画像内の描画領域 )
	{
		if( ( NULL == pDevice ) || ( pTexture == NULL ) )
			return E_POINTER;

		HRESULT hr = S_OK;

		BREAKABLE_BLOCK
		{
			D3DSURFACE_DESC desc;

			if( FAILED( hr = pTexture->GetLevelDesc( 0, &desc ) ) )
				break;

			float fx = ( x*DrawTexture::f物理縮小倍率 ) - 0.5f;	// -0.5 は座標とピクセルの誤差を吸収するための座標補正値。(MSDN参照)
			float fy = ( y*DrawTexture::f物理縮小倍率 ) - 0.5f;	//
			float w = ( prc画像内の描画領域->right - prc画像内の描画領域->left ) * f拡大縮小倍率X * DrawTexture::f物理縮小倍率;
			float h = ( prc画像内の描画領域->bottom - prc画像内の描画領域->top ) * f拡大縮小倍率Y * DrawTexture::f物理縮小倍率;
			float f左U値 = ( (float) prc画像内の描画領域->left ) / ( (float) desc.Width );
			float f右U値 = ( (float) prc画像内の描画領域->right ) / ( (float) desc.Width );
			float f上V値 = ( (float) prc画像内の描画領域->top ) / ( (float) desc.Height );
			float f下V値 = ( (float) prc画像内の描画領域->bottom ) / ( (float) desc.Height );
			D3DCOLOR color = ( (D3DCOLOR) ( n透明度0to255 ) << 24 ) | 0x00FFFFFF;

			pTransformedColoredTexturedVertexies[ 0 ].u = f左U値;
			pTransformedColoredTexturedVertexies[ 0 ].v = f上V値;
			pTransformedColoredTexturedVertexies[ 0 ].x = fx;
			pTransformedColoredTexturedVertexies[ 0 ].y = fy;
			pTransformedColoredTexturedVertexies[ 0 ].z = depth;
			pTransformedColoredTexturedVertexies[ 0 ].w = 1.0f;
			pTransformedColoredTexturedVertexies[ 0 ].color = color;

			pTransformedColoredTexturedVertexies[ 1 ].u = f右U値;
			pTransformedColoredTexturedVertexies[ 1 ].v = f上V値;
			pTransformedColoredTexturedVertexies[ 1 ].x = fx + w;
			pTransformedColoredTexturedVertexies[ 1 ].y = fy;
			pTransformedColoredTexturedVertexies[ 1 ].z = depth;
			pTransformedColoredTexturedVertexies[ 1 ].w = 1.0f;
			pTransformedColoredTexturedVertexies[ 1 ].color = color;

			pTransformedColoredTexturedVertexies[ 2 ].u = f左U値;
			pTransformedColoredTexturedVertexies[ 2 ].v = f下V値;
			pTransformedColoredTexturedVertexies[ 2 ].x = fx;
			pTransformedColoredTexturedVertexies[ 2 ].y = fy + h;
			pTransformedColoredTexturedVertexies[ 2 ].z = depth;
			pTransformedColoredTexturedVertexies[ 2 ].w = 1.0f;
			pTransformedColoredTexturedVertexies[ 2 ].color = color;

			pTransformedColoredTexturedVertexies[ 3 ].u = f右U値;
			pTransformedColoredTexturedVertexies[ 3 ].v = f下V値;
			pTransformedColoredTexturedVertexies[ 3 ].x = fx + w;
			pTransformedColoredTexturedVertexies[ 3 ].y = fy + h;
			pTransformedColoredTexturedVertexies[ 3 ].z = depth;
			pTransformedColoredTexturedVertexies[ 3 ].w = 1.0f;
			pTransformedColoredTexturedVertexies[ 3 ].color = color;

			if( FAILED( hr = DrawTexture::tレンダリングステートの設定( pDevice, b加算合成 ) ) ||	// レンダリングステートの設定
				FAILED( hr = pDevice->SetTexture( 0, pTexture ) ) ||								// 描画テクスチャの設定
				FAILED( hr = pDevice->SetFVF( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 ) ) ||	// 描画条件の設定(FVF)
				FAILED( hr = pDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, pTransformedColoredTexturedVertexies, sizeof( STTransformedColoredTextureVertexies ) ) )	// プリミティブの描画
				)
			{
				break;
			}
		}
		
		return hr;
	}
	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, int x, int y, LPRECT prc画像内の描画領域 )
	{
		return DrawTexture::t2D描画( pDevice, pTexture, n透明度0to255, b加算合成, f拡大縮小倍率X, f拡大縮小倍率Y, x, y, 1.0f, prc画像内の描画領域 );
	}
	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, int x, int y )
	{
		if( ( NULL == pDevice ) || ( NULL == pTexture ) )
			return E_POINTER;

		HRESULT hr = S_OK;

		BREAKABLE_BLOCK
		{
			D3DSURFACE_DESC desc;
			RECT rc画像内の描画領域;

			if( FAILED( hr = pTexture->GetLevelDesc( 0, &desc ) ) )		// サーフェイスレベル 0 の Description の取得
				break;

			rc画像内の描画領域.left = 0;
			rc画像内の描画領域.top = 0;
			rc画像内の描画領域.right = desc.Width;
			rc画像内の描画領域.bottom = desc.Height;

			if( FAILED( hr = DrawTexture::t2D描画( pDevice, pTexture, n透明度0to255, b加算合成, f拡大縮小倍率X, f拡大縮小倍率Y, x, y, &rc画像内の描画領域 ) ) )
				break;
		}

		return hr;
	}
	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, POINT pt, float depth, LPRECT prc画像内の描画領域 )
	{
		return DrawTexture::t2D描画( pDevice, pTexture, n透明度0to255, b加算合成, f拡大縮小倍率X, f拡大縮小倍率Y, pt.x, pt.y, depth, prc画像内の描画領域 );
	}
	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, POINT pt, LPRECT prc画像内の描画領域 )
	{
		return DrawTexture::t2D描画( pDevice, pTexture, n透明度0to255, b加算合成, f拡大縮小倍率X, f拡大縮小倍率Y, pt.x, pt.y, 1.0f, prc画像内の描画領域 );
	}
	HRESULT DrawTexture::t2D描画( IDirect3DDevice9Ex *pDevice, IDirect3DTexture9* pTexture, int n透明度0to255, bool b加算合成, float f拡大縮小倍率X, float f拡大縮小倍率Y, POINT pt )
	{
		if( ( NULL == pDevice ) || ( NULL == pTexture ) )
			return E_POINTER;

		HRESULT hr = S_OK;

		BREAKABLE_BLOCK
		{
			D3DSURFACE_DESC desc;
			RECT rc画像内の描画領域;

			if( FAILED( hr = pTexture->GetLevelDesc( 0, &desc ) ) )		// サーフェイスレベル 0 の Description の取得
				break;

			rc画像内の描画領域.left = 0;
			rc画像内の描画領域.top = 0;
			rc画像内の描画領域.right = desc.Width;
			rc画像内の描画領域.left = 0;

			if( FAILED( hr = DrawTexture::t2D描画( pDevice, pTexture, n透明度0to255, b加算合成, f拡大縮小倍率X, f拡大縮小倍率Y, pt.x, pt.y, 1.0f, &rc画像内の描画領域 ) ) )
				break;
		}

		return hr;
	}

// protected:

	STPositionColoredVertexies DrawTexture::pPositionColoredVertexies[ 4 ];
	STTransformedColoredTextureVertexies DrawTexture::pTransformedColoredTexturedVertexies[ 4 ];
	float DrawTexture::f物理縮小倍率 = 1.0f;

	HRESULT DrawTexture::tレンダリングステートの設定( IDirect3DDevice9Ex *pDevice, bool b加算合成 )
	{
		if( NULL == pDevice )
			return E_POINTER;
		
		HRESULT hr = S_OK;

		BREAKABLE_BLOCK
		{
			if( b加算合成 )
			{
				if( FAILED( hr = pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ) ) ||
					FAILED( hr = pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ) ) ||
					FAILED( hr = pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ) )
					)
				{
					break;
				}
			}
			else
			{
				if( FAILED( hr = pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ) ) ||
					FAILED( hr = pDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ) ) ||
					FAILED( hr = pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ) )
					)
				{
					break;
				}
			}
		}

		return hr;
	}
}
