/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2015/11/14
/// 
/// @brief  DirectX 頂点シェーダフラグメント
/// 
/// ****************************************************************************

#include "CPL_DX_Shader_VS_Fragment.h"

namespace CPL {
namespace DX {
namespace Shader {
/// @brief
/// VertexShaderFragment
namespace VSF {


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：３Ｄ座標　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_Position::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_position_No;
  CIVariable
    va_in_position =
      CPType(float4_) | CPName(kw_in_position)[No] | CPSemantic(POSITION)[No];
    
  out_input_param << va_in_position;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：２Ｄ座標　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_PositionT::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  CIVariable
    va_in_position =
      CPType(float4_) | CPName(kw_in_positiont) | CPSemantic(POSITIONT);
    
  //
  out_input_param << va_in_position;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：ブレンドの重み＆インデックス　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Input_Blend::Input_Blend
( U16 in_vtx_bwight_No
, U16 in_vtx_bindex_No
) : m_in_vtx_bweight_No( in_vtx_bwight_No )
  , m_in_vtx_bindex_No( in_vtx_bindex_No )
{
  // 今のところ何もしない
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：ブレンドの重み＆インデックス　入力パラメーター登録
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_Blend::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int bw_No = m_in_vtx_bweight_No;
  const int bi_No = m_in_vtx_bindex_No;
  CIVariable
    va_in_vtx_bweight =
      CPType(float4_) | CPName(kw_in_bweight)[bw_No] | CPSemantic(BLENDWEIGHT)[bw_No];
  CIVariable
    va_in_vtx_bindex =
      CPType(int4_) | CPName(kw_in_bindex)[bi_No] | CPSemantic(BLENDINDICES)[bi_No];
    
  out_input_param
    << va_in_vtx_bweight
    << va_in_vtx_bindex;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：法線ベクトル　入力パラメーター登録
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_Normal::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_normal_No;
  CIVariable
    va_in_normal =
      CPType(float4_) | CPName(kw_in_normal)[No] | CPSemantic(NORMAL)[No];

  out_input_param << va_in_normal;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：ポイントサイズ　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_PSize::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_psize_No;
  CIVariable va_in_psize =
    CPType(float_) | CPName(kw_in_psize)[No] | CPSemantic(PSIZE)[No];

  out_input_param << va_in_psize;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：頂点カラー　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_Color::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_color_No;
  CIVariable
    va_in_vtx_color =
      CPType(float4_) | CPName(kw_in_color)[No] | CPSemantic(COLOR)[No];

  out_input_param << va_in_vtx_color;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：テクスチャ座標　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_TexCoord::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_texcoord_No;
  CIVariable
    va_in_texcoord =
      CPType(float4_) | CPName(kw_in_texcoord)[No] | CPSemantic(TEXCOORD)[No];
    
  out_input_param << va_in_texcoord;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：接線　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_Tangent::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_tangent_No;
  CIVariable
    va_in_tangent =
      CPType(float4_) | CPName(kw_in_tangent)[No] | CPSemantic(TANGENT)[No];
    
  out_input_param << va_in_tangent;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：従法線　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_BiNormal::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_binormal_No;
  CIVariable
    va_in_binormal =
      CPType(float4_) | CPName(kw_in_binormal)[No] | CPSemantic(BINORMAL)[No];
    
  out_input_param << va_in_binormal;
}






// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：スクリーン座標　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_Position::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_out_position_No;
  CIVariable
    va_out_position =
      CPType(float4_) | CPName(kw_out_position)[No] | CPSemantic(SV_Position)[No];
    
  out_output_param << va_out_position;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：ポイントサイズ　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_PSize::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_out_psize_No;
  CIVariable
    va_out_psize =
      CPType(float_) | CPName(kw_out_psize)[No] | CPSemantic(PSIZE)[No];

  out_output_param << va_out_psize;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：フォグ　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_Fog::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_out_fog;
  CIVariable
    va_out_fog =
      CPType(float_) | CPName(kw_out_fog)[No] | CPSemantic(FOG)[No];

  out_output_param << va_out_fog;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：カラー　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_Color::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_out_color_No;
  CIVariable
    va_out_color =
      CPType(float4_) | CPName(kw_out_color)[No] | CPSemantic(COLOR)[No];

  out_output_param << va_out_color;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：テクスチャ座標　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_TexCoord::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_out_texcoord_No;
  CIVariable
    va_out_texcoord =
      CPType(float4_) | CPName(kw_out_texcoord)[No] | CPSemantic(TEXCOORD)[No];

  out_output_param << va_out_texcoord;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：テセレーション係数　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_TessFactor::On_SetupOutputParameter( rout<CIV_Output> out_input_param )
{
  const int No = m_out_tess_factor_No;
  CIVariable
    va_in_tess_factor(
      CPType(float_) | CPName(kw_out_tess_factor)[No] | CPSemantic(TESSFACTOR)[No] );

  out_input_param << va_in_tess_factor;
}



// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点トランスフォーム　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VertexTransform::VertexTransform( _in<int> in_input_pos_No, _in<int> in_output_pos_No )
  : Input_Position( in_input_pos_No )
  , Output_Position( in_output_pos_No )
{
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点トランスフォーム　グローバルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void VertexTransform::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  CIVariable
    va_g_mtx_view_proj =
      CPType(float4x4_) | CPName(kw_g_mtx_view_proj) | CPSemantic("ViewProjection"),
    va_g_mtx_world =
      CPType(float4x4_) | CPName(kw_g_mtx_world) | CPSemantic("JointWorld");

  out_global_param
    << va_g_mtx_view_proj
    << va_g_mtx_world;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点トランスフォーム　ローカルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void VertexTransform::On_SetupInitializer( CIV_Initializer& out_initialize_param )
{
  Local_Position::On_SetupInitializer( out_initialize_param );
  Local_Matrix::On_SetupInitializer( out_initialize_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点トランスフォーム　関数定義構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  VertexTransform::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数用変数
  CIVariable arg_out_sc_pos = CPInputModifier(out_)   | CPType(float4_)   | CPName("out_sc_pos");
  CIVariable arg_io_vtx_pos = CPInputModifier(inout_) | CPType(float4_)   | CPName("io_vtx_pos");
  CIVariable arg_in_matrix  = CPInputModifier(in_)    | CPType(float4x4_) | CPName("in_matrix");

  // 簡易化用
  css32
    out_sc_pos  ( arg_out_sc_pos.GetName() ),
    io_vtx_pos( arg_io_vtx_pos.GetName() ),
    in_matrix ( arg_in_matrix.GetName() ),
    g_mtx_view_proj( kw_g_mtx_view_proj );

  // ステートメント作成
  ss statement;
  statement,
    io_vtx_pos = mul( io_vtx_pos, in_matrix ),Ends,
    out_sc_pos = mul( io_vtx_pos, g_mtx_view_proj ),Ends;

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName(zzf_GetFunctionName() ) // 関数名
    << arg_out_sc_pos << arg_io_vtx_pos << arg_in_matrix // 引数
    << CPStatementBlock( statement );

  // 関数登録
  out_functions << func_item;
}



// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点トランスフォーム関数の呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  VertexTransform::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( COLOR ) );

  // 簡易化用
  css32
    out_sc_pos( output.member( sp_va_out_color->GetName() ) ),
    l_vtx_pos ( kw_l_position, m_pos_No ),
    l_matrix  ( kw_l_matrix, m_matrix_No );

  // ステートメント追記
  out_statement,
    zzf_GetFunctionName()( out_sc_pos, l_vtx_pos, l_matrix ), Ends;
}






// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マトリクスブレンディング　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MatrixBlending::MatrixBlending
( _in<U16> in_vtx_bweight_No
, _in<U16> in_vtx_bindex_No
, _in<int> in_blend_matrix_max
) : Input_Blend( in_vtx_bweight_No, in_vtx_bindex_No ),
    m_in_blend_matrix_max( in_blend_matrix_max )
{}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マトリクスブレンディング　グローバルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MatrixBlending::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  CIVariable
    g_va_mtx_blend(
      CPType(float4x4_) |
      CPName(kw_g_mtx_world) |
      CPSemantic("JointWorld") |
      CPNum( m_in_blend_matrix_max ) );

  out_global_param << g_va_mtx_blend;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マトリクスブレンディング　ローカルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void MatrixBlending::On_SetupInitializer( CIV_Initializer& out_initialize_param )
//{
//  //Input_Position::On_SetupInitializer( out_initialize_param );
//  //Input_Blend::On_SetupInitializer( out_initialize_param );
//  //Output_Position::On_SetupInitializer( out_initialize_param );
//
//  css f0("0.0f");
//  css f1("1.0f");
//  CIVariable va_l_matrix =
//    CPType(float4x4_) |
//    CPName(kw_l_matrix) |
//    CPSemantic("Matrix") |
//    CPInitialize(float4x4_(f1,f0,f0,f0, f0,f1,f0,f0, f0,f0,f1,f0, f0,f0,f0,f1));
//
//  // 変数登録
//  out_initialize_param << va_l_matrix;
//}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マトリクスブレンディング　関数設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  MatrixBlending::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数設定
  CIVariable
    arg_io_matrix   = CPInputModifier(inout_) | CPType(float4x4_) | CPName("io_matrix"),
    arg_in_bindex0  = CPInputModifier(in_)    | CPType(float_)    | CPName("in_bindex0"),
    arg_in_bweight0 = CPInputModifier(in_)    | CPType(float_)    | CPName("in_bweight0"),
    arg_in_bindex1  = CPInputModifier(in_)    | CPType(float_)    | CPName("in_bindex1");

  // 簡易化用
  css32
    io_matrix  ( arg_io_matrix.GetName() ),
    in_bindex0 ( arg_in_bindex0.GetName() ),
    in_bweight0( arg_in_bweight0.GetName() ),
    in_bindex1 ( arg_in_bindex1.GetName() ),
    g_mtx_blend( kw_g_mtx_world ),
    mtx( "mtx" );
      
  ss statement;
  // ************************* Make HLSL Code ***********************************
  statement,
    float4x4_,
      mtx = g_mtx_blend[ in_bindex0 ] * in_bweight0 + 
            g_mtx_blend[ in_bindex1 ] * &(css16("1.0f") - in_bweight0),Ends,
    io_matrix = mul(io_matrix, mtx),Ends;
  // *****************************************************************************

  //
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName(zzf_GetFunctionName())
    << arg_io_matrix << arg_in_bindex0 << arg_in_bweight0 << arg_in_bindex1
    << CPStatementBlock( statement );

  out_functions << func_item;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マトリクスブレンディング関数の呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  MatrixBlending::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター取得
  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
  sdptr<CIVariable>
    sp_va_in_vtx_bweight =
      sp_input_param->FindItem<CIVariable>( CPSemantic(BLENDWEIGHT)[m_in_vtx_bweight_No] ),
    sp_va_in_vtx_bindex =
      sp_input_param->FindItem<CIVariable>( CPSemantic(BLENDINDICES)[m_in_vtx_bindex_No] );

  // 簡易化用
  css32
    g_mtx_blend( kw_g_mtx_world ),
    l_matrix( kw_l_matrix ),
    in_bindex( input.member( sp_va_in_vtx_bindex->GetName() ) ),
    in_bweight( input.member( sp_va_in_vtx_bweight->GetName() ) );
  auto
    FuncMatrixBlending( zzf_GetFunctionName() );

  // ステートメント追記
  out_statement,
    FuncMatrixBlending(
      l_matrix,
      in_bindex.x(),
      in_bweight.x(),
      in_bindex.y() ), Ends;
}





// =============================================================================
// 法線トランスフォーム

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 法線トランスフォーム　ローカルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NormalTransform::On_SetupInitializer( CIV_Initializer& out_initialize_param )
{
  Local_Normal::On_SetupInitializer( out_initialize_param );
  Local_Matrix::On_SetupInitializer( out_initialize_param );
}

  
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 法線トランスフォーム　関数実装呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  NormalTransform::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数
  CIVariable arg_io_vtx_normal = CPInputModifier(inout_) | CPType(float4_) | CPName("io_vtx_normal");
  CIVariable arg_in_matrix     = CPInputModifier(in_) | CPType(float4x4_) | CPName("in_matrix");

  // 簡易化用文字列
  css32
    mtx_normal("mtx_normal"),
    io_vtx_normal( arg_io_vtx_normal.GetName() ),
    in_mtx( arg_in_matrix.GetName() ),
    f0("0.0f"), f1("1.0f");

  // 関数のブロックステートメントを構築
  ss statement;
  statement,
  // ************************* Make HLSL Code ***********************************
    // 法線回転用マトリクスの生成
    float4x4_, mtx_normal =
      float4x4_( in_mtx._11(), in_mtx._12(), in_mtx._13(), f0,
                 in_mtx._21(), in_mtx._22(), in_mtx._23(), f0,
                 in_mtx._31(), in_mtx._32(), in_mtx._33(), f0,
                 f0, f0, f0, f1 ), Ends,
    // 法線の変換
    io_vtx_normal = mul( io_vtx_normal, mtx_normal ), Ends;
  // *****************************************************************************

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << arg_io_vtx_normal << arg_in_matrix // 変数
    << CPStatementBlock( statement ); // ステートメント

  // 関数アイテム登録
  out_functions << func_item;
}

  
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 法線トランスフォーム　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  NormalTransform::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 簡易化用文字列
  css16
    l_vtx_normal( kw_l_normal ),
    l_matrix( kw_l_matrix );
  auto
    FuncNormalTransform( zzf_GetFunctionName() );

  // ステートメント追記
  out_statement,
    FuncNormalTransform( l_vtx_normal, l_matrix ), Ends;
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ビルボード　グローバルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void MatrixBillboard::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  CIVariable va_g_mtx_billboard =
    CPType(float4x4_) | CPName(kw_g_mtx_billboard) | CPSemantic("BillboardMatrix");
  //
  out_global_param << va_g_mtx_billboard;
}


  
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ビルボード　関数ブロック定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  MatrixBillboard::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数設定
  CIVariable arg_va_io_mtx = CPInputModifier(inout_) | CPType(float4x4_) | CPName("io_matrix");

  // 簡易化用文字列
  css16
    g_mtx_billboard( kw_g_mtx_billboard ),
    io_mtx( arg_va_io_mtx.GetName() );
  auto
    FuncMatrixBillboard( zzf_GetFunctionName() );

  // ステートメントブロック作成
  ss statement;
  statement,
    io_mtx = mul( io_mtx, g_mtx_billboard ), Ends;

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( FuncMatrixBillboard )
    << arg_va_io_mtx
    << CPStatementBlock( statement );
}

  
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ビルボード　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  MatrixBillboard::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 簡易化用文字列
  auto  FuncMatrixBillboard( zzf_GetFunctionName() );
  css16 l_matrix( kw_l_matrix );

  // ステートメント追記
  out_statement,
    FuncMatrixBillboard( l_matrix ), Ends;
}







// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　グローバルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  //
  auto str_PointLight( zzf_GetFunctionName() );
  CIVariable
    st_point_light =
      CPType(struct_) | CPName(str_PointLight);
  st_point_light
    << CIVariable( CPType(float4_) | CPName(kw_diffuse) )
    << CIVariable( CPType(float4_) | CPName(kw_specular) )
    << CIVariable( CPType(float4_) | CPName(kw_position) )
    << CIVariable( CPType(float4_) | CPName(kw_normal) );

  CIVariable
    va_g_point_light  = CPType(str_PointLight) | CPName(kw_g_point_light),
    va_g_eye_position = CPType(float4_) | CPName(kw_g_eye_position);

  // 
  out_global_param
    << va_g_point_light
    << va_g_eye_position;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　入力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Input_Position::On_SetupInputParameter( out_input_param );
  Input_Normal::On_SetupInputParameter( out_input_param );
  if( m_color_type )
  {
    Input_Color::On_SetupInputParameter( out_input_param );
  }
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライト計算関数の実装
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  PointLight::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数用変数作成
  CIVariable
    arg_out_color = CPInputModifier(out_) | CPType(float4_)   | CPName(kw_out_color),
    arg_in_pos    = CPInputModifier(in_)  | CPType(float4_)   | CPName("in_vtx_pos"),
    arg_in_normal = CPInputModifier(in_)  | CPType(float4_)   | CPName(kw_in_normal),
    arg_in_color  = CPInputModifier(in_)  | CPType(float4_)   | CPName(kw_in_color),
    arg_in_matrix = CPInputModifier(in_)  | CPType(float4x4_) | CPName("in_matrix");

  // 簡易化用      
  css32
    mtx_rot( "mtx_rot" ),
    pos    ( "pos" ),
    vec_nr ( "vec_nr" ),
    eye_nr ( "eye_nr" ),
    lit_nr ( "lit_nr" ),
    ref_nr ( "ref_nr" ),
    dif_pw ( "dif_pw" ),
    light_idx( "light_idx" );
  css32
    out_color    ( arg_out_color.GetName() ),
    in_vtx_pos   ( arg_in_pos.GetName() ),
    in_vtx_normal( arg_in_normal.GetName() ),
    in_vtx_color ( arg_in_color.GetName() ),
    in_matrix    ( arg_in_matrix.GetName() );
  css32
    g_eye_position( kw_g_eye_position ),
    g_point_light ( kw_g_point_light );
  css32
    g_light_position( kw_g_point_light[ light_idx ].member( kw_position ) ),
    g_light_normal  ( kw_g_point_light[ light_idx ].member( kw_normal ) );
  
  // 関数のブロックステートメントを構築
  ss statement;
  statement,
  // ************************* Make HLSL Code ***********************************
  // 回転マトリクスの抽出
    float3x3_, mtx_rot(
      in_matrix._11(), in_matrix._12(), in_matrix._13(),
      in_matrix._21(), in_matrix._22(), in_matrix._23(),
      in_matrix._31(), in_matrix._32(), in_matrix._33() ), Ends,
    
    float4_, pos   = mul( in_vtx_pos, in_matrix ), Ends,
    float4_, vec_nr = mul( in_vtx_normal, mtx_rot ), Ends,
    float4_, eye_nr = normalize( g_eye_position - pos.xyz() ), Ends,
    float4_, lit_nr, Ends,
    float4_, ref_nr, Ends,
    float_ , dif_pw, Ends,
    CPL_HLSL_LOOP( m_light_num, light_idx )
    {
      lit_nr = normalize( g_light_position[ light_idx ] - pos ), Ends,
      dif_pw = saturate( dot( vec_nr, lit_nr ) ), Ends,
      out_color.rgb() += g_light_normal[ light_idx ] * dif_pw, Ends
    },
    //out_color.rgb() += in_vtx_color.rgb() * g_light_ambient, Ends,
    saturate( out_color.rgb() ), Ends,
    out_color.a() = in_vtx_color.a(), Ends;
  // *****************************************************************************

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << arg_out_color
    << arg_in_pos
    << arg_in_normal
    << arg_in_color
    << arg_in_matrix
    << CPStatementBlock( statement );

}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  PointLight::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター検索
  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
  sdptr<CIVariable>
    sp_va_in_color  = sp_input_param->FindItem<CIVariable>( CPSemantic( COLOR ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( COLOR ) );

  // 簡易化用
  auto
    FuncLightPoint( zzf_GetFunctionName() );
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    in_vtx_color( input.member( sp_va_in_color->GetName() ) ),
    l_vtx_pos   ( kw_l_position ),
    l_vtx_normal( kw_l_normal ),
    l_matrix    ( kw_l_matrix );

  out_statement,
    FuncLightPoint(
      out_color, l_vtx_pos, l_vtx_normal, in_vtx_color, kw_l_matrix );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　初期設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupInitializer( CIV_Initializer& out_initialize_param )
{
  CIVariable
    va_l_position = CPType(float4_) | CPName(kw_l_position) | CPInitialize(kw_in_position),
    va_l_normal   = CPType(float4_) | CPName(kw_l_normal)   | CPInitialize(kw_in_normal);

  out_initialize_param
    << va_l_position
    << va_l_normal;

  Local_Matrix::On_SetupInitializer( out_initialize_param );
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ピクセルシェーダライティングのデータ設定コード　入力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SetupPixelShaderLighting::On_SetupInputParameter(
    rout<CIV_Input> out_input_param )
{
  Input_Position::On_SetupInputParameter( out_input_param );
  Input_Normal::On_SetupInputParameter( out_input_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ピクセルシェーダライティングのデータ設定コード　出力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SetupPixelShaderLighting::On_SetupOutputParameter(
    rout<CIV_Output> out_output_param )
{
  Output_TexCoordN<4>::On_SetupOutputParameter( out_output_param );
  Output_TexCoordN<4>::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ピクセルシェーダライティングのデータ設定コード　ローカルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SetupPixelShaderLighting::On_SetupInitializer( CIV_Initializer& out_initialize_param )
{
  Local_Position::On_SetupInitializer( out_initialize_param );
  Local_Normal::On_SetupInitializer( out_initialize_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ピクセルシェーダライティングのデータ設定コード　関数実装コードの生成
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SetupPixelShaderLighting::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 引数用変数作成
  CIVariable
    arg_out_texcoord4 = CPInputModifier(out_) | CPType(float4_) | CPName(kw_out_texcoord)[4],
    arg_out_texcoord5 = CPInputModifier(out_) | CPType(float4_) | CPName(kw_out_texcoord)[5],
    arg_in_position   = CPInputModifier(in_)  | CPType(float4_) | CPName(kw_in_position),
    arg_in_normal     = CPInputModifier(in_)  | CPType(float4_) | CPName(kw_in_normal);

  // 簡易化用
  css32
    out_tex4( arg_out_texcoord4.GetName() ),
    out_tex5( arg_out_texcoord5.GetName() ),
    in_position( arg_in_position.GetName() ),
    in_normal( arg_in_normal.GetName() );
  auto
    FuncSetupPixelShaderLighting( zzf_GetFunctionName() );

  // ステートメント
  ss statement;
  statement,
  // ************************* Make HLSL Code ***********************************
  // テクスチャ座標４に頂点座標、５に頂点法線を設定する。
    out_tex4       = in_position, Ends,
    out_tex5.xyz() = in_normal.xyz(), Ends,
    out_tex5.w()   = css16(1.0f), Ends;
  // *****************************************************************************

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( FuncSetupPixelShaderLighting )
    << arg_out_texcoord4 << arg_out_texcoord5 << arg_in_position << arg_in_normal
    << CPStatementBlock( statement );

  // 関数登録
  out_functions << func_item;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ピクセルシェーダライティングのデータ設定コード　呼び出しコード生成
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SetupPixelShaderLighting::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_tex4 = sp_output_param->FindItem<CIVariable>( CPSemantic( TEXCOORD )[4] ),
    sp_va_out_tex5 = sp_output_param->FindItem<CIVariable>( CPSemantic( TEXCOORD )[5] );

  auto
    FuncSetupPixelShaderLighting( zzf_GetFunctionName() );
  css32
    out_tex4( output.member( sp_va_out_tex4->GetName() ) ),
    out_tex5( output.member( sp_va_out_tex5->GetName() ) ),
    l_position( kw_l_position ),
    l_normal( kw_l_normal );
  
  out_statement,
    FuncSetupPixelShaderLighting( out_tex4, out_tex5, l_position, l_normal );
}




//// _____________________________________________________________________________
//// 頂点座標直接出力　コンストラクタ
//// _____________________________________________________________________________
//DirectInputPosition::DirectInputPosition(
//      int in_input_pos_No,
//      int in_output_pos_No )
//  : Input_Position( in_input_pos_No ),
//    Output_Position( in_output_pos_No )
//{}
//
//// _____________________________________________________________________________
//// 頂点座標直接出力　入力パラメーター設定
//// _____________________________________________________________________________
//void DirectInputPosition::On_SetupInputParameter( rout<CIV_Input> out_input_param )
//{
//  Input_Position ::On_SetupInputParameter( out_input_param );
//}
//
//// _____________________________________________________________________________
//// 頂点座標直接出力　出力パラメーター設定
//// _____________________________________________________________________________
//void DirectInputPosition::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
//{
//  Output_Position::On_SetupOutputParameter( out_output_param );
//}
//
//// _____________________________________________________________________________
//// 頂点座標出力　関数呼び出し
//// _____________________________________________________________________________
//void
//  DirectInputPosition::On_CallFunction(
//    ss&                out_statement,
//    CodeItemSet const& in_parameter )
//{
//  // 入力パラメーター検索
//  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
//  sdptr<CIVariable>
//    sp_va_in_pos =
//      sp_input_param->FindItem<CIVariable>( CPSemantic( POSITION ) );
//  // 出力パラメーター検索
//  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
//  sdptr<CIVariable>
//    sp_va_out_pos =
//      sp_output_param->FindItem<CIVariable>( CPSemantic( SV_Position ) );
//
//  // 簡易化用
//  css32
//    out_pos( output.member( sp_va_out_pos->GetName() ) ),
//    in_pos( input.member( sp_va_in_pos->GetName() ) );
//
//  // HLSLコード追記
//  out_statement,  out_pos = in_pos,Ends;
//}



// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 変換済み頂点座標直接出力　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ImmediateInputPositionT::ImmediateInputPositionT( int in_output_pos_No )
  : Output_Position( in_output_pos_No )
{}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 変換済み頂点座標直接出力　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateInputPositionT::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Input_PositionT::On_SetupInputParameter( out_input_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 変換済み頂点座標直接出力　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateInputPositionT::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Position::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点座標出力　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  ImmediateInputPositionT::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター検索
  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
  sdptr<CIVariable>
    sp_va_in_pos =
      sp_input_param->FindItem<CIVariable>( CPSemantic( POSITIONT ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_pos =
      sp_output_param->FindItem<CIVariable>( CPSemantic( SV_Position ) );

  // 簡易化用
  css32
    out_pos( output.member( sp_va_out_pos->GetName() ) ),
    in_pos( input.member( sp_va_in_pos->GetName() ) );

  // HLSLコード追記
  out_statement,  out_pos = in_pos,Ends;
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点カラー直接出力　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ImmediateInputColor::ImmediateInputColor(
      int in_input_color_No,
      int in_output_color_No )
  : Input_Color( in_input_color_No ),
    Output_Color( in_output_color_No )
{
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点カラー直接出力　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateInputColor::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Input_Color ::On_SetupInputParameter( out_input_param );
  Output_Color::On_SetupInputParameter( out_input_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点カラー直接出力　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateInputColor::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Input_Color ::On_SetupOutputParameter( out_output_param );
  Output_Color::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点カラー直接出力　処理呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  ImmediateInputColor::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター検索
  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
  sdptr<CIVariable>
    sp_va_in_color =
      sp_input_param->FindItem<CIVariable>( CPSemantic( COLOR ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( COLOR ) );

  // 簡易化用
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    in_color( input.member( sp_va_in_color->GetName() ) );

  //
  out_statement,
    out_color = in_color,Ends;
}






// _____________________________________________________________________________
/// @brief コンストラクタ
/// 
/// @param[in] in_input_texcoord_No : 入力テクスチャ座標の番号を指定します。
/// @param[in] in_output_texcoord_No : 出力入力テクスチャ座標の番号を指定します。
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ImmediateTextureCoord::ImmediateTextureCoord
( _in<int> in_input_texcoord_No
, _in<int> in_output_texcoord_No
) : Input_TexCoord( in_input_texcoord_No )
  , Output_TexCoord( in_output_texcoord_No ) 
{
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャ座標直接出力　入力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateTextureCoord::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Input_TexCoord ::On_SetupInputParameter( out_input_param );
  Output_TexCoord::On_SetupInputParameter( out_input_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャ座標直接出力　出力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateTextureCoord::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Input_TexCoord ::On_SetupOutputParameter( out_output_param );
  Output_TexCoord::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャ座標直接出力　処理記述
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  ImmediateTextureCoord::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター検索
  sdptr<CIV_Input> sp_input_param = in_parameter.FindItem<CIV_Input>();
  sdptr<CIVariable>
    sp_va_in_tex =
      sp_input_param->FindItem<CIVariable>( CPSemantic( TEXCOORD ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_tex =
    sp_output_param->FindItem<CIVariable>( CPSemantic( TEXCOORD ) );

  // 簡易化用
  css32
    out_texcoord( output.member( sp_va_out_tex->GetName() ) ),
    in_texcoord( input.member( sp_va_in_tex->GetName() ) );

  out_statement,
    out_texcoord = in_texcoord,Ends;
}





//// _____________________________________________________________________________
//// 入力パラメーター：頂点宣言　コンストラクタ（要素テーブル渡し）
//// _____________________________________________________________________________
//Input_Declaration::Input_Declaration( DX_IN_ELEMENT_DESC const* in_ptr_element_table )
//{
//  // 頂点宣言データをコピー
//  const D3DVERTEXELEMENT9 end = D3DDECL_Ends;
//  D3DVERTEXELEMENT9 const* pElement = in_ptr_element_table;
//  m_decl_num = 0;
//  while( memcmp(pElement, &end, sizeof(end)) )
//  {
//    this->m_decl_element[ m_decl_num ] = *pElement;
//    m_decl_num++;
//    pElement++;
//  }
//}

//// _____________________________________________________________________________
//// 入力パラメーター：頂点宣言　コンストラクタ（頂点宣言渡し）
//// _____________________________________________________________________________
//Input_Declaration::Input_Declaration( D3DInputLayout::ptr in_ptr_decl )
//{
//  in_ptr_decl->GetDeclaration( m_decl_element, &m_decl_num );
//  --m_decl_num;
//}


//// _____________________________________________________________________________
//// 入力パラメーター：頂点宣言　コンストラクタ（CPL::VertexLayout渡し）
//// _____________________________________________________________________________
//Input_Declaration::Input_Declaration( BufferLayout& in_vtx_layout )
//{
//  in_vtx_layout.GetDxDeclaration()->GetDeclaration(
//    m_decl_element,
//    &m_decl_num );
//  in_vtx_layout.
//  --m_decl_num;
//}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：頂点レイアウト渡し　コンストラクタ
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VertexLayout::VertexLayout( Layout::Buffer const& in_layout_buf )
  : Layout::Buffer( in_layout_buf )
{
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：頂点レイアウト渡し　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void VertexLayout::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Core::StringA  no;

  size_t element_num = this->m_element_table.GetNum();
  for( UINT i = 0; i < element_num; ++i )
  {
    CPType     type("");
    CPName     name("");
    CPSemantic semantic("");

    Core::StringA semantics = m_element_table[ i ].SemanticName;
    const int semantic_idx = m_element_table[ i ].SemanticIndex;
    
    if( ::strcmp( semantics, POSITIONT ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InPositionT::kw_in_positiont;
      semantic.m_str = POSITIONT;
    }
    else
    if( ::strncmp( semantics, POSITION, POSITION.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InPosition::kw_in_position;
      semantic.m_str = POSITION;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, BLENDWEIGHT, BLENDWEIGHT.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InBWeight::kw_in_bweight;
      semantic.m_str = BLENDWEIGHT;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, BLENDINDICES, BLENDINDICES.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InBIndex::kw_in_bindex;
      semantic.m_str = BLENDINDICES;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, NORMAL, NORMAL.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InNormal::kw_in_normal;
      semantic.m_str = NORMAL;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, PSIZE, PSIZE.GetLength() ) == 0 )
    {
      type.m_str = float_;
      name.m_str = CSF::KW_InPSize::kw_in_psize;
      semantic.m_str = PSIZE;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, TEXCOORD, TEXCOORD.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InTexCoord::kw_in_texcoord;
      semantic.m_str = TEXCOORD;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, TANGENT, TANGENT.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InTangent::kw_in_tangent;
      semantic.m_str = TANGENT;
      no = semantic_idx;
    }
    else
    if( ::strncmp( semantics, BINORMAL, BINORMAL.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InBiNormal::kw_in_binormal;
      semantic.m_str = BINORMAL;
      no = semantic_idx;
    }
    //ef( ::strncmp( semantics, TESSFACTOR, TESSFACTOR.GetLength() ) == 0 )
    //{
    //  type.m_str = float_;
    //  name.m_str = CSF::KW_InTessFactor::kw_in_tess_factor;
    //  semantic.m_str = TESSFACTOR;
    //}
    else
    if( ::strncmp( semantics, COLOR, COLOR.GetLength() ) == 0 )
    {
      type.m_str = float4_;
      name.m_str = CSF::KW_InColor::kw_in_color;
      semantic.m_str = COLOR;
      no = semantic_idx;
      //this->setColorType( ShaderCode::Vertex );
    }
    name.m_str += no;
    semantic.m_str += no;
    
    out_input_param << CIVariable( type | name | semantic );
  }
}



} // namespace VSF
} // namespace Shader
} // namespace DX
} // namespace CPL