//------------------------------------------------------------------;
//
//------------------------------------------------------------------;

int c_fx::m_set_fx ( void ) {

   // build matrix

   D3DXMATRIX l_trans;
   D3DXMATRIX l_rotate;

   D3DXMatrixTranslation          ( &l_trans, 0.0f, 0.0f, 5.0f );
   D3DXMatrixRotationYawPitchRoll ( &l_rotate,
		                    D3DXToRadian(e_d3d->l_spin_x),
		                    D3DXToRadian(e_d3d->l_spin_y),
		                    0.0f );

   e_d3d->l_mat_world = l_rotate * l_trans;

   D3DXMatrixIdentity( &e_d3d->l_mat_view ); //!view/matrix

   // matrix : verts : world-space->clip-space
   D3DXMATRIX l_w_view_proj = e_d3d->l_mat_world * e_d3d->l_mat_view * e_d3d->l_mat_proj;
   D3DXMatrixTranspose        ( &l_w_view_proj, &l_w_view_proj );

   // matrix : normals : model-space->view-space
   D3DXMATRIX l_w_view_inv = e_d3d->l_mat_world * e_d3d->l_mat_view;
   D3DXMatrixInverse          ( &l_w_view_inv, NULL, &l_w_view_inv );

/**
ex : dx9/ref/D3DXMatrixPerspectiveFovLH
   w       0       0               0
   0       h       0               0
   0       0       zf/(zf-zn)      1
   0       0       -zn*zf/(zf-zn)  0
   where:
   h is the view space height. It is calculated from 
   h = cot(fovY/2);
   w is the view space width. It is calculated from
   w = h / Aspect.
**/

// c_v j l_w_view_inv = e_d3d->l_mat_world * e_d3d->l_mat_view;
    
   D3DXMATRIX l_world = e_d3d->l_mat_world;
   D3DXMatrixTranspose        ( &l_world, &l_world );
/**
   c_v a;
   c_v b  = e_d3d->l_mat_world;
   a.m_identity  ();
   a.m_transpose (b);
**/

   c_v m2;
   m2.v4           ( 1.0f, 0.0f, -1.0f, 0.0f );
   m2.m4_normalize ();
   m2.v3           ( 0.0f, 0.0f, 0.0f );

   cgD3D9SetUniformMatrix ( e_d3d->l_cgparam_wvproj, &l_w_view_proj );
   cgD3D9SetUniformMatrix ( e_d3d->l_cgparam_wvinv, &l_w_view_inv );
   cgD3D9SetUniformMatrix ( e_d3d->l_cgparam_w, &l_world );
   cgD3D9SetUniform       ( e_d3d->l_cgparam_l_vect, &m2.v_4 );
   cgD3D9SetUniform       ( e_d3d->l_cgparam_e_vect, &m2.v_3 );

   return 1;
}

//------------------------------------------------------------------;
//
//------------------------------------------------------------------;

int c_fx::m_init_fx ( void ) {

   e_d3d->l_cg_context = cgCreateContext(); // context()
   cgD3D9SetDevice( e_d3d->l_d3d_device );

   CGprofile l_vertex_profile = cgD3D9GetLatestVertexProfile(); // vertex profile

   // optimal options for(profiles)

   const char** l_vertex_options[] = 
   {
      cgD3D9GetOptimalOptions(l_vertex_profile), 0 
   };

   // create()

   e_d3d->l_cg_program = cgCreateProgramFromFile( e_d3d->l_cg_context,
                                                 CG_SOURCE,
		                                 "fx/fx_cg_anisotropic.cg",
	                                         l_vertex_profile,
                                                 "main",
                                                 (const char**)l_vertex_options );

   // bindings.

   const D3DVERTEXELEMENT9 declaration[] = 
   {
      { 0, 0 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_POSITION, 0 },
      { 0, 3 * sizeof(float),D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT,D3DDECLUSAGE_NORMAL,   0 },
      D3DDECL_END()
   };

   // compatibility.

   assert(cgD3D9ValidateVertexDeclaration( e_d3d->l_cg_program, declaration ));

   e_d3d->l_d3d_device->CreateVertexDeclaration( declaration, &e_d3d->l_vertex_declare );
	
   // load

   cgD3D9LoadProgram( e_d3d->l_cg_program, TRUE, 0 );

   // bind/parms

   e_d3d->l_cgparam_wvproj  = cgGetNamedParameter( e_d3d->l_cg_program, "worldViewProj" );
   e_d3d->l_cgparam_wvinv   = cgGetNamedParameter( e_d3d->l_cg_program, "worldViewInv" );
   e_d3d->l_cgparam_w       = cgGetNamedParameter( e_d3d->l_cg_program, "world" );
   e_d3d->l_cgparam_l_vect  = cgGetNamedParameter( e_d3d->l_cg_program, "lightVector" );
   e_d3d->l_cgparam_e_vect  = cgGetNamedParameter( e_d3d->l_cg_program, "eyePosition" );

   // check/size

   assert(cgD3D9TypeToSize(cgGetParameterType(e_d3d->l_cgparam_wvproj)) == 16 );
   assert(cgD3D9TypeToSize(cgGetParameterType(e_d3d->l_cgparam_wvinv))  == 9 );
   assert(cgD3D9TypeToSize(cgGetParameterType(e_d3d->l_cgparam_w))      == 12 );
   assert(cgD3D9TypeToSize(cgGetParameterType(e_d3d->l_cgparam_l_vect)) == 3 );
   assert(cgD3D9TypeToSize(cgGetParameterType(e_d3d->l_cgparam_e_vect)) == 3 );

   return 1;
}
