/// ****************************************************************************
/// @file   
/// @author Dr.Neeton
/// @date   200X/X/X - 2016/12/08
/// 
/// @brief  ピクセルシェーダフラグメント
/// 
/// ****************************************************************************

#include "CPL_DX_Shader_PS_Fragment.h"

namespace CPL {
namespace DX {
namespace Shader {
/// @brief
/// PixelShaderFragment
namespace PSF {


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：カラー（ターゲット）　入力パラメーター構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void Input_SV_Target::On_SetupInputParameter( rout<CIV_Input> out_input_param )
//{
//  const int No = m_in_target;
//  CIVariable
//    va_in_sv_target =
//      CPType(float_) | CPName(kw_in_target)[No] | CPSemantic(SV_Target)[No];
//
//  out_input_param << va_in_sv_target;
//}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：ピクセル座標？　入力パラメーター構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_SV_Position::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_vpos;
  CIVariable
    va_in_vpos =
      CPType(float4_) | CPName(kw_in_svposition)[No] | CPSemantic(SV_Position)[No];

  out_input_param << va_in_vpos;
}



// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 入力パラメーター：プリミティブの方向　入力パラメーター構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Input_VFace::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  const int No = m_in_vface;
  CIVariable
    va_in_vface =
      CPType(int_) | CPName(kw_in_vface)[No] | CPSemantic(VFACE)[No];

  // 変数登録
  out_input_param << va_in_vface;
}




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：カラー？　出力パラメーター構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_Target::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_target_No;

  CIVariable
    va_out_target =
      CPType(float4_) | CPName(kw_out_target) | CPSemantic(SV_Target)[No];
  out_output_param << va_out_target;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 出力パラメーター：深度　出力パラメーター構築
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Output_Depth::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  const int No = m_depth_No;

  CIVariable
    va_out_depth =
      CPType(float_) | CPName(kw_out_depth)[No] | CPSemantic(DEPTH)[No];
  out_output_param << va_out_depth;
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャコード　グローバルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Texture::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  // グローバルパラメータからマテリアル変数を検索し、マテリアル変数が存在すれば
  // マテリアルカラーモードフラグを有効とする
  sdptr<CIVariable> sp_va_material =
    out_global_param.FindItem<CIVariable>( CPName(kw_g_material) );
  if( !sp_va_material )
  {
    m_color_type = 0; // 頂点カラーモード
  }
  else
  {
    m_color_type = 1; // マテリアルカラーモード

    Global_Material::On_SetupGlobalParameter( out_global_param );
  }

  // 定義済みパラメーター設定関数の呼び出し
  CSF::Global_Texture2D::On_SetupGlobalParameter( out_global_param );
  CSF::Global_SamplerState::On_SetupGlobalParameter( out_global_param );
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャコード　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Texture::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  if( m_color_type == 0 )
  {
    Input_Color::On_SetupInputParameter( out_input_param );
  }

  CPL_LOOP2( m_stage_num, stage_idx )
  {
    m_in_texcoord_No = stage_idx;

    Input_TexCoord::On_SetupInputParameter( out_input_param );
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャコード　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Texture::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 関数定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  Texture::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 簡易化用
  css32
    in_texture ( "in_texture" ),
    in_color   ( "in_color" ),
    in_texcoord( "in_texcoord" ),
    in_sampler ( "in_sampler" );

  // ステートメント文字列の構築
  ss statement;
  int blend_type = 0;

  switch( blend_type )
  {
  case 0: statement,  return_, in_color * in_texture.Sample( in_sampler, in_texcoord.xy() ), Ends; break; // 乗算
  case 1: statement,  return_, in_color + in_texture.Sample( in_sampler, in_texcoord.xy() ), Ends; break; // 加算
  case 2: statement,  return_, in_color - in_texture.Sample( in_sampler, in_texcoord.xy() ), Ends; break; // 減算
  }

  // 引数アイテム作成
  CIVariable arg_in_color    = CPInputModifier(in_) | CPType(float4_) | CPName(in_color);
  CIVariable arg_in_texcoord = CPInputModifier(in_) | CPType(float4_) | CPName(in_texcoord);
  CIVariable arg_in_sampler  = CPInputModifier(in_) | CPType(SamplerState) | CPName(in_sampler);
  CIVariable arg_in_texture  = CPInputModifier(in_) | CPType(Texture2D) | CPName(in_texture);
  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(float4_) // 戻り値
    << CPName( zzf_GetFunctionName() ) // 関数名
    << arg_in_color << arg_in_texcoord << arg_in_sampler << arg_in_texture // 引数
    << CPStatementBlock( statement );  // 関数の実装

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

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 関数呼び出しコード作成
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  Texture::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // 入力パラメーター検索
  auto sp_input_param = in_parameter.FindItem<CIV_Input>();
  // 出力パラメーター検索
  auto sp_output_param = in_parameter.FindItem<CIV_Output>();
  auto
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( SV_Target ) );

  // 名前
  css32
    g_sampler( kw_g_sampler ),
    g_texture( kw_g_texture ),
    out_color( output.member( sp_va_out_color->GetName() ) );
  css128
    TextureFunction( zzf_GetFunctionName() );
  // ステートメント追記
  CPL_LOOP2( m_stage_num, stage_idx )
  {
    auto
      sp_va_in_texcoord =
        sp_input_param->FindItem<CIVariable>( CPSemantic( TEXCOORD )[ stage_idx ] );
    css32 in_texcoord( input.member( sp_va_in_texcoord->GetName() ) );

    if( m_stage_num > 1 )
    {
      out_statement,
        out_color =
          TextureFunction
            ( out_color
            , in_texcoord
            , g_sampler[stage_idx]
            , g_texture
            ), Ends;
    }
    else
    {
      out_statement,
        out_color =
          TextureFunction
            ( out_color
            , in_texcoord
            , g_sampler
            , g_texture
            ), Ends;
    }
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャコード　前処理設定
// カラー用の一時変数を用意し、入力カラーもしくはマテリアルカラーを設定する
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void Texture::On_SetupInitializer( rout<CIV_Initializer> out_initialize_param )
{
  // 処理内容を変数名として変数を設定
  if( m_color_type == 0 ) // vertex color mode
  {
    ss tmp_code0
    { output.member( kw_out_target ) = input.member( kw_in_color, m_in_color_No )
    , Ends
    };
    CIVariable
      init_out_color = CPName( tmp_code0, false ); // トークンとして扱ってはいけない
    out_initialize_param << init_out_color;
  }
  else // material color mode
  {
    ss tmp_code0
    { output.member( kw_out_target ) = kw_g_material.member( kw_diffuse )
    , Ends
    };
    CIVariable
      set_l_color = CPName( tmp_code0, false ); // トークンとして扱ってはいけない
    out_initialize_param << set_l_color;
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// テクスチャコード　後処理
// カラー用一時変数の値を、出力パラメーターに設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void Texture::On_SetupFinalizer( CIV_Finalizer& out_finalizer_param )
//{
//  // 処理内容を変数名として変数を設定
//  CIVariable set_out_color =
//    CPName( (output.member(kw_out_target) = kw_l_color,Ends) );
//
//  out_finalizer_param << set_out_color;
//}






// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// カラー直接指定フラグメント　グローバルパラメータの設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SetColor::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  CSF::Global_PixelColor::On_SetupGlobalParameter( out_global_param );
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// カラー直接指定フラグメント　出力パラメータの設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SetColor::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// カラー直接指定フラグメント　関数呼び出し、ではなく直接カラー設定する
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SetColor::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( SV_Target ) );

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

  //
  if( m_color == float4(1.0f,1.0f,1.0f,0.0f) )
  {
    css32 g_pixel_color( kw_g_pixel_color );

    // ステートメント追記
    out_statement,
      out_color = g_pixel_color, Ends;
  }
  else
  {
    // ステートメント追記
    out_statement,
      out_color.r() = m_color.x, Ends,
      out_color.g() = m_color.y, Ends,
      out_color.b() = m_color.z, Ends,
      out_color.a() = m_color.w, Ends;
  }
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライトコード　グローバルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AmbientLight::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  // カラータイプ判定
  m_color_type = CheckColorMode( out_global_param );

  // 変数設定
  CIVariable va_g_ambient_light =
    CPType(float4_) | CPName( kw_g_ambient_light ) | CPSemantic( "AMBIENT_LIGHT" );

  // 変数登録
  out_global_param << va_g_ambient_light;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライトコード　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AmbientLight::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  Input_Color::On_SetupInputParameter( out_input_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライトコード　出力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AmbientLight::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライトコード　関数定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  AmbientLight::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 簡易化用に変数名を定義
  css32
    out_color( kw_out_target ),
    in_color( kw_in_color ),
    g_ambient_diffuse( kw_g_ambient_light.member(kw_diffuse) );

  // ステートメント文字列の構築
  ss statement;
  statement,
    out_color.rgb() = in_color.rgb() * g_ambient_diffuse, Ends,
    out_color.a()   = in_color.a(), Ends;
    

  // 引数設定
  CIVariable va_out_color = CPInputModifier(out_) | CPType(float4_) | CPName(out_color);
  CIVariable va_in_color  = CPInputModifier(in_)  | CPType(float4_) | CPName(in_color);

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << va_out_color
    << va_in_color
    << CPStatementBlock( statement );

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

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライトコード　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  AmbientLight::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( SV_Target ) );

  // 簡易化用名前定義
  auto
    FuncAmbientLight( zzf_GetFunctionName() );
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    in_color;
  if( m_color_type == 0 ) // 頂点カラーモード
  {
    in_color.Reset( input.member( sp_va_in_color->GetName() ) );
  }
  else // マテリアルカラーモード
  {
    in_color.Reset( kw_g_material.member( kw_diffuse, 0 ) );
  }

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

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// アンビエントライト　初期化設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void AmbientLight::On_SetupInitializer( rout<CIV_Initializer> out_initialize_param )
{
  // 処理内容を変数名として変数を設定
  if( m_color_type == 0 ) // vertex color mode
  {
    ss   tmp_code0 = (output.member( kw_out_target ) = kw_in_color);
    auto tmp_code1 = (tmp_code0, Ends);
    CIVariable init_out_color = CPName( tmp_code0, false ); // トークンとして扱ってはいけない。
    out_initialize_param << init_out_color;
  }
  else // material color mode
  {
    ss tmp_code0
    { output.member( kw_out_target ) = kw_g_material.member( kw_diffuse )
    , Ends
    };
    CIVariable set_l_color =
      CPName( tmp_code0
            , false
            );
    out_initialize_param << set_l_color;
  }
}






// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ディレクショナルライトコード　グローバルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DirectionalLight::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  // カラータイプ判定
  m_color_type = CheckColorMode( out_global_param );

  // 簡易化用
  CPName
    g_directional_light( kw_g_directional_light ),
    m_light_diffuse ( kw_diffuse ),
    m_light_specular( kw_specular ),
    m_light_normal  ( kw_normal ),
    m_light_power   ( kw_power ),
    stDirectionalLight( zzf_GetStructName() );

  // ライトのメンバ変数アイテム作成
  CIVariable va_light_diffuse  = CPType(float4_) | m_light_diffuse  | CPSemantic("LIGHT_DIFFUSE");
  CIVariable va_light_specular = CPType(float4_) | m_light_specular | CPSemantic("LIGHT_SPECULAR");
  CIVariable va_light_normal   = CPType(float4_) | m_light_normal   | CPSemantic("LIGHT_NORMAL");
  CIVariable va_light_power    = CPType(float_)  | m_light_power    | CPSemantic("LIGHT_POWER");
  // ライト構造体定義
  CIVariable
    st_directional_light = CPType(struct_) | stDirectionalLight;
  st_directional_light // メンバ変数登録
    << va_light_diffuse
    << va_light_specular
    << va_light_normal
    << va_light_power;

  // ライト変数定義
  CIVariable va_directional_light =
    CPType(stDirectionalLight) | CPName(g_directional_light) | CPNum(m_light_num);

  // 変数登録
  out_global_param
    << st_directional_light
    << va_directional_light;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ディレクショナルライトコード　入力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DirectionalLight::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  CIVariable va_vtx_pos =
    CPType(float4_) | CPName( kw_in_position ) | CPSemantic(TEXCOORD)[4];
  CIVariable va_vtx_normal =
    CPType(float4_) | CPName( kw_in_normal ) | CPSemantic(TEXCOORD)[5];

  out_input_param << va_vtx_pos << va_vtx_normal;

  if( this->m_color_type == 0 ) // vertex color
  {
    CIVariable va_color =
      CPType(float4_) | CPName( kw_in_color )[0] | CPSemantic(COLOR)[0];
    out_input_param << va_color;
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ディレクショナルライトコード　出力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DirectionalLight::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ディレクショナルライトコード　実装関数定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  DirectionalLight::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 名前簡易化用
  css32
    io_color("io_color"),
    in_vtx_pos("in_vtx_pos"),
    in_vtx_normal("in_vtx_normal"),
    in_color("in_color"),
    g_directional_light( kw_g_directional_light );
  css32
    litPwr("litPwr"), light_idx("light_idx");
  css32
    g_light_normal ( g_directional_light[light_idx].member(kw_normal) ),
    g_light_diffuse( g_directional_light[light_idx].member(kw_diffuse) );
  auto
    stDirectionalLight( zzf_GetStructName() );

  // ステートメント設定
  ss statement;
  // ****************************** HLSL Code ***********************************
  statement,
    CPL_HLSL_LOOP( m_light_num, light_idx )
    {
      float_, litPwr = dot( in_vtx_normal, g_light_normal ), Ends,
      io_color.rgb() +=
        g_light_diffuse * saturate( litPwr ) * &(in_color.rgb() - io_color.rgb()), Ends
    };
  // *****************************************************************************

  // 引数設定
  CIVariable
    arg_io_color      = CPInputModifier(inout_) | CPType(float4_) | CPName( io_color )  ,// | CPSemantic(SV_Target),
    arg_in_vtx_pos    = CPInputModifier(in_) | CPType(float4_) | CPName( in_vtx_pos )   ,// | CPSemantic( "VERTEX_POSITION" ),
    arg_in_vtx_normal = CPInputModifier(in_) | CPType(float4_) | CPName( in_vtx_normal ),// | CPSemantic( "VERTEX_NORMAL" ),
    arg_in_color      = CPInputModifier(in_) | CPType(float4_) | CPName( in_color )     ;// | CPSemantic(SV_Target);

  // 関数アイテム作成
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << arg_io_color
    << arg_in_vtx_pos
    << arg_in_vtx_normal
    << arg_in_color
    << CPStatementBlock( statement );
  // 関数アイテム登録
  out_functions << func_item;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ディレクショナルライトコード　呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  DirectionalLight::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 ) ),
    sp_va_in_pos    = sp_input_param->FindItem<CIVariable>( CPSemantic( POSITION ) ),
    sp_va_in_normal = sp_input_param->FindItem<CIVariable>( CPSemantic( NORMAL ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( SV_Target ) );

  //int light_no = 0; // 今のところ仮に。

  // 簡易化用名前
  css32
    in_color     ( input.member( sp_va_in_color->GetName() ) ),
    in_vtx_pos   ( input.member( sp_va_in_pos->GetName() ) ),
    in_vtx_normal( input.member( sp_va_in_normal->GetName() ) ),
    out_color    ( output.member( sp_va_out_color->GetName() ) ),
    g_mtrl_color ( kw_g_material );
  auto
    DirectionalLightFunction( zzf_GetFunctionName() );

  if( m_color_type == 0 ) // vertex color
  {
    out_statement,
      DirectionalLightFunction
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        , in_color
        ), Ends;
  }
  else // material color
  {
    out_statement,
      DirectionalLightFunction
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        , g_mtrl_color
        ), Ends;
  }
}




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　グローバルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  // カラータイプ判定
  m_color_type = CheckColorMode( out_global_param );

  // パラメーター簡易化用定義
  ss    stPointLight( zzf_GetStructName() );
  CPNum light_num( m_light_num );
  // ポイントライト構造体設定
  CIVariable st_point_light = CPType(struct_) | CPName(stPointLight);
  st_point_light
    << CIVariable( CPType(float4_) | CPName( kw_diffuse )  | CPSemantic( "LIGHT_COLOR" ) )
    << CIVariable( CPType(float4_) | CPName( kw_position ) | CPSemantic( "LIGHT_POSITION" ) )
    << CIVariable( CPType(float4_) | CPName( kw_normal )   | CPSemantic( "LIGHT_NORMAL" ) )
    << CIVariable( CPType(float_)  | CPName( kw_power )    | CPSemantic( "LIGHT_POWER" ) );

  // ポイントライト変数設定
  CIVariable va_point_light =
    CPType(stPointLight) | CPName(kw_g_point_light) | light_num;

  // 変数登録
  out_global_param << st_point_light << va_point_light;
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　入力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  // 変数設定
  CIVariable va_in_vtx_pos =
    CPInputModifier(in_) | CPType(float4_) | CPName( kw_in_position ) | CPSemantic(TEXCOORD)[4];
  CIVariable va_in_vtx_normal =
    CPInputModifier(in_) | CPType(float4_) | CPName( kw_in_normal ) | CPSemantic(TEXCOORD)[5];

  out_input_param << va_in_vtx_pos << va_in_vtx_normal;

  if( this->m_color_type == 0 )
  {
    CIVariable va_in_color =
      CPInputModifier(in_) | CPType(float4_) | CPName( kw_in_color ) | CPSemantic(COLOR);
    out_input_param << va_in_color;
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　出力パラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void PointLight::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　ローカルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void PointLight::On_SetupInitializer( rout<CIV_Initializer> out_initialize_param )
//{
//  // 変数設定
//  CIVariable va_out_color =
//      CPType(float4_) |
//      CPName( kw_out_Color,0 ) |
//      CPInitialize( float4_("0","0","0","0") );
//  // 変数登録
//  out_initialize_param << va_out_color;
//}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　関数定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  PointLight::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // パラメータ簡易定義用
  css16
    lit_vec("lit_vec"), lit_len("lit_len"), lit_nor("lit_nor"), lit_pwr("lit_pwr");
  css32
    io_color     ( "io_color" ),
    in_vtx_pos   ( "in_vtx_pos" ),
    in_vtx_normal( "in_vtx_normal" ),
    g_point_light( kw_g_point_light ),
    light_idx    ( "light_idx" );
  css64
    color
    { (m_color_type == 0)
        ? (char_cptr)kw_in_color
        : (char_cptr)kw_g_material[ light_idx ].member( kw_diffuse )
    };
  css64
    g_light_diffuse( g_point_light[ light_idx ].member( kw_diffuse ) ),
    g_light_pos    ( g_point_light[ light_idx ].member( kw_position ) ),
    g_light_normal ( g_point_light[ light_idx ].member( kw_normal ) ),
    g_light_power  ( g_point_light[ light_idx ].member( kw_power ) );
  // ステートメント構築
  ss statement;
  // ****************************** HLSL Code ***********************************
  statement,
    CPL_HLSL_LOOP( m_light_num, light_idx )
    {
      float4_, lit_vec = g_light_pos - in_vtx_pos, Ends,   // 光源へのベクトル
      float4_, lit_nor = normalize( lit_vec ), Ends,            // 光源への単位ベクトル
      float_,  lit_len = length( lit_vec ), Ends,               // ライトまでの距離
      float_,  lit_pwr = g_light_power * dot( in_vtx_normal, lit_nor ) / lit_len, Ends,
      io_color.rgb() += g_light_diffuse * saturate( lit_pwr ) * &(color.rgb() - io_color.rgb()), Ends
    };
  // *****************************************************************************
    
  // 引数設定
  CIVariable arg_io_color      = CPInputModifier(inout_) + CPType(float4_) + CPName( io_color );
  CIVariable arg_in_vtx_pos    = CPInputModifier(in_) + CPType(float4_) + CPName( in_vtx_pos );
  CIVariable arg_in_vtx_normal = CPInputModifier(in_) + CPType(float4_) + CPName( in_vtx_normal );

  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << arg_io_color
    << arg_in_vtx_pos
    << arg_in_vtx_normal
    << CPStatementBlock( statement );
  if( m_color_type == 0 ) // 頂点カラーモードなら、カラー引数を追加
  {
    func_item << CIVariable( CPInputModifier(in_) + CPType(float4_) + CPName( kw_in_color ) );
  }

  out_functions << func_item;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ポイントライトコード　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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_pos    = sp_input_param->FindItem<CIVariable>( CPSemantic( POSITION ) ),
    sp_va_in_normal = sp_input_param->FindItem<CIVariable>( CPSemantic( NORMAL ) );
  // 出力パラメーター検索
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_out_color =
      sp_output_param->FindItem<CIVariable>( CPSemantic( SV_Target ) );
  //
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    in_vtx_pos( input.member( sp_va_in_pos->GetName() ) ),
    in_vtx_normal( input.member( sp_va_in_normal->GetName() ) );
  auto
    FuncPointLight( zzf_GetFunctionName() );

  if( m_color_type == 0 )
  {
    out_statement,
      FuncPointLight
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        , kw_in_color
        ), Ends;
  }
  else
  {
    out_statement,
      FuncPointLight
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        ), Ends;
  }
}





// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコード　グローバルパラメータ設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SpotLight::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  // カラータイプ判定
  m_color_type = CheckColorMode( out_global_param );

  // パラメータ定義簡易化用
  CPNum light_num( m_light_num );
  auto  stSpotLight( zzf_GetStructName() );

  // スポットライト構造体設定
  CIVariable st_spot_light = CPType(struct_) | CPName( stSpotLight );
  st_spot_light
    << CIVariable( CPType(float4_) | CPName(kw_diffuse ) | CPSemantic( "LIGHT_DIFFUSE" ) )
    << CIVariable( CPType(float4_) | CPName(kw_position) | CPSemantic( "LIGHT_POSITION" ) )
    << CIVariable( CPType(float4_) | CPName(kw_normal  ) | CPSemantic( "LIGHT_NORMAL" ) )
    << CIVariable( CPType(float_)  | CPName(kw_power   ) | CPSemantic( "LIGHT_POWER" ) )
    << CIVariable( CPType(float_)  | CPName(kw_theta   ) | CPSemantic( "LIGHT_THETA" ) )
    << CIVariable( CPType(float_)  | CPName(kw_phi     ) | CPSemantic( "LIGHT_PHI" ) );
  // スポットライト宣言
  CIVariable va_spot_light = CPType( stSpotLight ) | CPName(kw_g_spot_light) | light_num;

  // アイテム登録
  out_global_param
    << st_spot_light  // マテリアル構造体定義
    << va_spot_light; // マテリアル変数定義
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコード　入力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SpotLight::On_SetupInputParameter( rout<CIV_Input> out_input_param )
{
  // 変数設定
  CIVariable va_in_vtx_pos =
    CPType(float4_) | CPName(kw_in_position) | CPSemantic(TEXCOORD)[4];
  CIVariable va_in_vtx_normal =
    CPType(float4_) | CPName(kw_in_normal)   | CPSemantic(TEXCOORD)[5];

  // 変数登録
  out_input_param << va_in_vtx_pos << va_in_vtx_normal;
  if( this->m_color_type == 0 ) // vertex color
  {
    // 頂点カラー仕様の場合、入力カラーを追加
    CIVariable va_in_color =
      CPType(float4_) | CPName(kw_in_color) | CPSemantic(COLOR);
    out_input_param << va_in_color;
  }
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコード　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void SpotLight::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコード　ローカルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//void SpotLight::On_SetupInitializer( rout<CIV_Initializer> out_initialize_param )
//{
//  // 変数アイテム作成
//  CIVariable va_out_color =
//    CPType(float4_) + CPName( kw_out_Color,0 ) + CPInitialize( float4_("0","0","0","0") );
//  // 変数登録
//  out_initialize_param << va_out_color;
//}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコード　関数定義
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SpotLight::On_SetupFunction
    ( rout<CIFunctionSet> out_functions
    , _in <CIV_Global   > in_global_param
    )
{
  // 簡易化用
  css32
    io_color     ( "io_color" ),
    in_vtx_pos   ( "in_vtx_pos" ),
    in_vtx_normal( "in_vtx_normal" ),
    in_color     ( "in_color" ),
    g_spot_light ( kw_g_spot_light );
  css16
    range("range"), light_idx("light_idx");
  css16
    lit_vec("lit_vec"),
    lit_nor("lit_nor"),
    lit_len("lit_len"),
    lit_pwr("lit_pwr"),
    lit_nLL("lit_nLL");
  css32
    g_light_pos    ( g_spot_light[light_idx].member( kw_position ) ),
    g_light_diffuse( g_spot_light[light_idx].member( kw_diffuse ) ),
    g_light_normal ( g_spot_light[light_idx].member( kw_normal ) ),
    g_light_power  ( g_spot_light[light_idx].member( kw_power ) ),
    g_light_theta  ( g_spot_light[light_idx].member( kw_theta ) ),
    g_light_phi    ( g_spot_light[light_idx].member( kw_phi ) );

  // ステートメント
  ss statement;
  // ****************************** HLSL Code ***********************************
  statement,
    CPL_HLSL_LOOP( m_light_num, light_idx )
    {
      float4_, lit_vec = g_light_pos - in_vtx_pos,                                Ends, // 光源へのベクトル
      float4_, lit_nor = normalize( lit_vec ),                                    Ends, // 光源への単位ベクトル
      float_,  lit_len = length( lit_vec ),                                       Ends, // ライトまでの距離
      float_,  range   = g_light_phi - g_light_theta[light_idx],                  Ends, // スポットライトの幅
      float_,  lit_nLL = dot( g_light_normal, lit_nor ),                          Ends, // ライトのベクトルとライトへのベクトル間の角度(cos)を取得
      float_,  lit_pwr = g_light_power * dot( in_vtx_normal, lit_nor ) / lit_len, Ends,
      lit_pwr *= saturate(&(lit_nLL - cos(g_light_phi)) / range),                 Ends,
    //  lit_pwr = range, Ends,
      io_color.rgb() +=
          g_light_diffuse * saturate( lit_pwr ) * &(in_color.rgb() - io_color.rgb()), Ends
    };
  // *****************************************************************************
    
  // 引数用変数作成
  CIVariable arg_io_color      = CPInputModifier(inout_) | CPType(float4_) | CPName(io_color     );
  CIVariable arg_in_vtx_pos    = CPInputModifier(in_) | CPType(float4_) | CPName(in_vtx_pos   );
  CIVariable arg_in_vtx_normal = CPInputModifier(in_) | CPType(float4_) | CPName(in_vtx_normal);

  // 関数設定
  CIFunction func_item;
  func_item
    << CPType(void_)
    << CPName( zzf_GetFunctionName() )
    << CPStatementBlock( statement )
    << arg_io_color
    << arg_in_vtx_pos
    << arg_in_vtx_normal;
  if( m_color_type == 0 )
  {
    CIVariable arg_in_color = CPInputModifier(in_) | CPType(float4_) | CPName(in_color);
    func_item << arg_in_color;
  }

  // 関数アイテム追加
  out_functions << func_item;
}


// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// スポットライトコードの呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  SpotLight::On_CallFunction
    ( rout<ss         > out_statement
    , _in <CodeItemSet> in_parameter
    )
{
  // パラメータ取得
  sdptr<CIV_Global> sp_global_param = in_parameter.FindItem<CIV_Global>();
  sdptr<CIV_Input>  sp_input_param  = in_parameter.FindItem<CIV_Input>();
  sdptr<CIV_Output> sp_output_param = in_parameter.FindItem<CIV_Output>();
  sdptr<CIVariable>
    sp_va_in_vtx_pos    = sp_input_param ->FindItem<CIVariable>( CPSemantic(TEXCOORD)[4] ),
    sp_va_in_vtx_normal = sp_input_param ->FindItem<CIVariable>( CPSemantic(TEXCOORD)[5] ),
    sp_va_out_color     = sp_output_param->FindItem<CIVariable>( CPSemantic(SV_Target) );
  sdptr<CIVariable>
    sp_va_in_color =
      (m_color_type == 0)
        ? sp_input_param ->FindItem<CIVariable>( CPSemantic(COLOR) )
        : sp_global_param->FindItem<CIVariable>( CPSemantic("MATERIAL") );
  // 簡易化用
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    in_color( input.member( sp_va_in_color->GetName() ) ),
    in_vtx_pos( input.member( sp_va_in_vtx_pos->GetName() ) ),
    in_vtx_normal( input.member( sp_va_in_vtx_normal->GetName() ) );
  auto
    FuncSpotLight( zzf_GetFunctionName() );

  if( m_color_type == 0 ) // vertex color
  {
    out_statement,
      FuncSpotLight
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        , in_color
        ), Ends;
  }
  else // material color
  {
    out_statement,
      FuncSpotLight
        ( out_color
        , in_vtx_pos
        , in_vtx_normal
        ), Ends;
  }
}




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

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// 頂点カラー　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ImmediateInputColor::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::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( SV_Target ) );

  css32
    in_color ( input.member( sp_va_in_color->GetName() ) ),
    out_color( output.member( sp_va_out_color->GetName() ) );

  // ステートメント追記
  out_statement,
    out_color = min( in_color, ss(1.0f) ), Ends;
}




// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マテリアルカラー　グローバルパラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DirectMaterialColor::On_SetupGlobalParameter( rout<CIV_Global> out_global_param )
{
  CSF::Global_Material::On_SetupGlobalParameter( out_global_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マテリアルカラー　出力パラメーター設定
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void DirectMaterialColor::On_SetupOutputParameter( rout<CIV_Output> out_output_param )
{
  Output_Target::On_SetupOutputParameter( out_output_param );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// マテリアルカラー　関数呼び出し
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void
  DirectMaterialColor::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( SV_Target ) );

  //
  css32
    out_color( output.member( sp_va_out_color->GetName() ) ),
    g_mtrl_color( kw_g_material.member( kw_diffuse ) );

  out_statement,
    out_color = g_mtrl_color,Ends;
}




} // namespace PSF
} // namespace Shader
} // namespace DX
} // namespace CPL