/***************************************************************/
//
//
//		DirectX	[ renderingorderdx9.cpp ]
//
//											Author	kazuki tanaka
//											Date	2017 5/24
/*---------------------------------------------------------------
■Update : 2017/5/24
			renderingorderdx9.cppの作成

/*---------------------------------------------------------------
	Include File
---------------------------------------------------------------*/

#include "rendering_orderdx9.h"

#include "mathematics.h"

#include "rendererdx9.h"

#include "vertexbufferdx9.h"
#include "indexbufferdx9.h"

#include "modeldx9_interface.h"
//#include "mesh3dobjectdx9.h"
#include "texturedx9_interface.h"

#include "camera.h"
#include "castdx9.h"

/*---------------------------------------------------------------
	Macro Difinition
---------------------------------------------------------------*/


/*---------------------------------------------------------------
	Const Number Difinition
---------------------------------------------------------------*/


/*----------------------------------------------------------------
	static member variable Initialize
----------------------------------------------------------------*/



// RenderingOrderDX9 Constructor
RenderingOrderDX9::RenderingOrderDX9( )
{

	// Menber Clear Process

}

// RenderingOrderDX9 Destructor
RenderingOrderDX9::~RenderingOrderDX9( )
{

	// Do Nothing!!

}

// RenderingOrderDX9 Create Instance 
RenderingOrderDX9* RenderingOrderDX9::Create( void )
{

	// Create Class Instance
	return new RenderingOrderDX9;

}

// RenderingOrder DrawPrimitiveStrip
void RenderingOrderDX9::DrawPrimitiveStrip( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	// Set < WorldMatrix >
	if( mtx ){
		GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );
	}

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( 
		D3DPT_TRIANGLESTRIP,				// Triangle Style
		0,									// Vertex Offset
		pVtxBuf->GetVertexNumber( )-2 );	// Primitive Number

}

// RenderingOrder DrawPrimitiveList
void RenderingOrderDX9::DrawPrimitiveList( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	// Set < WorldMatrix >
	if( mtx ){
		GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );
	}

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLELIST, 0, pVtxBuf->GetVertexNumber( )/3 );

}

// RenderingOrder DrawPrimitiveFan
void RenderingOrderDX9::DrawPrimitiveFan( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	*mtx = *mtx * Camera::GetMtxUserInterface();

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, false );

	GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, pVtxBuf->GetVertexNumber( )-2 );

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, true );


}

// RenderingOrder DrawSubset
void RenderingOrderDX9::DrawSubset( ModelInterface* pMeshObj, Matrix* mtx )
{

	// 現在デバイスに設定されているマテリアル情報の取得
	LPDIRECT3DDEVICE9 pDevice = GetDevice( );

	// デバイスにワールド変換行列を設定
	pDevice ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	D3DMATERIAL9 matDef;
	pDevice -> GetMaterial( &matDef );
	
	// マテリアル情報のポインタとしてアドレスを取得
	D3DXMATERIAL* pMat =( D3DXMATERIAL*)dynamic_cast<ModelDX9Interface*>(pMeshObj)->GetMatBuffer( ) -> GetBufferPointer( );

	for( int index = 0; index < (int)dynamic_cast<ModelDX9Interface*>(pMeshObj)->GetMatNumber( ); index++ ){

		// デバイスにマテリアルを設定
		pDevice -> SetMaterial( &pMat[ index ].MatD3D );

		// テクスチャ設定
		if( dynamic_cast<ModelDX9Interface*>(pMeshObj)->GetTexture( index ) ){
			//pDevice -> SetTexture( 0, dynamic_cast<TextureDX9Interface*>(dynamic_cast<Mesh3DObjectDX9*>(pMeshObj)->GetTexture( index ))->data );
			dynamic_cast<ModelDX9Interface*>(pMeshObj)->GetTexture( index )->SetTexture( );
		}else{
			pDevice -> SetTexture( 0, NULL );		
		}

		// MODEL描画
		dynamic_cast<ModelDX9Interface*>(pMeshObj)->GetMesh( )->DrawSubset( index );
	}

	pDevice -> SetMaterial( &matDef );

}

// RenderingOrder DrawIndexPrimitive
void RenderingOrderDX9::DrawIndexPrimitive( VertexBuffer* pVtxBuf, IndexBuffer* pIdxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	// Set < WorldMatrix >
	if( mtx ){
		GetDevice( ) ->SetTransform( D3DTS_WORLD, &(D3DXMATRIX)(*mtx) );
	}

	// Set < Texture >
	pTexture->SetTexture( );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < IndexBuffer >
	pIdxBuf->SetIndex( );

	// Render
	GetDevice( ) ->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, pIdxBuf->GetIndexNumber( ), 0, (pIdxBuf->GetIndexNumber( )-2) );

}

// RenderingOrder DrawBillboard
void RenderingOrderDX9::DrawBillboard( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	*mtx = *mtx * Camera::GetMtxView();

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, false );

	// Set < WorldMatrix >
	GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, pVtxBuf->GetVertexNumber( )-2 );

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, true );

}

// RenderingOrder DrawBillboard
void RenderingOrderDX9::Draw3DUserInterface( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx )
{

	*mtx = Camera::GetMtxUserInterface() * (*mtx);

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, false );

	// Set < WorldMatrix >
	GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, pVtxBuf->GetVertexNumber( )-2 );

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, true );


}

// RenderingOrder DrawLineList
void RenderingOrderDX9::DrawLineList( VertexBuffer* pVtxBuf, Matrix* mtx )
{

	LPDIRECT3DDEVICE9 pDevice = GetDevice();

	pDevice ->SetRenderState( D3DRS_LIGHTING, false );

	// Set < WorldMatrix >
	pDevice ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex( );

	pDevice->SetTexture(0,NULL);

	// Render
	pDevice ->DrawPrimitive( D3DPT_LINELIST, 0, pVtxBuf->GetVertexNumber( )>>1 );

	pDevice ->SetRenderState( D3DRS_LIGHTING, true );

}

// RenderingOrder DrawPrimitive CurringOff
void RenderingOrderDX9::DrawPrimitiveCurringOff( VertexBuffer* pVtxBuf, TextureInterface* pTexture, Matrix* mtx	)
{

	// Curring Off
	GetDevice()->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);			

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, false );

	// Set < WorldMatrix >
	GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < Texture > 
	pTexture->SetTexture( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, pVtxBuf->GetVertexNumber( )-2 );

	GetDevice() ->SetRenderState( D3DRS_LIGHTING, true );

	GetDevice() ->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );				

}

// RenderingOrder DrawPrimitive CurringOff
void RenderingOrderDX9::DrawReverseObject( VertexBuffer* pVtxBuf, IndexBuffer* pIdxBuf, TextureInterface* pTexture, Matrix* mtx	)
{

	// light Off
	//GetDevice() ->SetRenderState( D3DRS_LIGHTING, false );

	*mtx = mtx->Rotate( Vector3(0,0,_PI) );

	// Set < WorldMatrix >
	GetDevice( ) ->SetTransform( D3DTS_WORLD, &CastMtx( *mtx ) );
	
	// Set < Texture >
	pTexture->SetTexture( );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex3D( );

	// Set < IndexBuffer >
	pIdxBuf->SetIndex( );

	// Render
	GetDevice( ) ->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, pIdxBuf->GetIndexNumber( ), 0, (pIdxBuf->GetIndexNumber( )-2) );

	//GetDevice() ->SetRenderState( D3DRS_LIGHTING, true );


}

// RenderingOrder DrawSprite
void RenderingOrderDX9::DrawSprite( VertexBuffer* pVtxBuf, TextureInterface* pTexture )
{

	// Set < Texture >
	pTexture->SetTexture( );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex2D( );

	// Render
	GetDevice( ) ->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, pVtxBuf->GetVertexNumber( )-2 );

}

// RenderingOrder DrawSpriteEx
void RenderingOrderDX9::DrawSpriteEx( VertexBuffer* pVtxBuf, IndexBuffer* pIdxBuf, TextureInterface* pTexture )
{

	// Set < Texture >
	pTexture->SetTexture( );

	// Set < VertexBuffer >
	pVtxBuf->SetVertex2D( );

	// Set < IndexBuffer >
	pIdxBuf->SetIndex( );

	// Render
	GetDevice( ) ->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, pIdxBuf->GetIndexNumber( ), 0, (pIdxBuf->GetIndexNumber( )-2) );


}





