[Cg] Comment marchent les unsized arrays?

Comment marchent les unsized arrays? [Cg] - C++ - Programmation

Marsh Posté le 29-05-2007 à 20:50:27    

Bonjour à tous,
 
J'utilise Cg (v.1.5) comme langage de shaders et j'essaie en vain d'utliser la fonction cgSetArraySize()...
 
Ce que j'essaie de faire, c'est de passer en paramètre d'un pixel shader un tableau de lumières à dimension variable, de manière à ne faire qu'une passe pour un nombre [0,n] de lumières dans ma scène.
 
Le code du fragment shader est donc:
 

Code :
  1. half4 main ( FragmentInput IN, uniform SpotLight lights[], ... ) : COLOR
  2.   {
  3.   half4 lighting = float3 ( 0, 0, 0 );
  4.  
  5.   for ( int i = 0; i < lights.length; ++i )  lighting += lights[i].illuminate ( ... );
  6.   ...
  7.   return lighting;
  8.   }


 
 
 
Allez hop, le code C++ maintenant:
 

Code :
  1. CGparameter myCgFragmentParam_lightsArray = cgGetNamedProgramParameter(myCgFragmentProgram, CG_PROGRAM, "lights" );
  2. cgSetArraySize(myCgFragmentParam_lightsArray,1);


 
 
Problème: après cela, Cg me renvoie le code d'erreur suivant: CG_INVALID_PARAM_HANDLE_ERROR.
 
Quest-ce qui ne va pas?


Message édité par akalash47 le 31-05-2007 à 14:28:00
Reply

Marsh Posté le 29-05-2007 à 20:50:27   

Reply

Marsh Posté le 30-05-2007 à 02:12:44    

Salut,
 
Après quelques petites recherche, il faut apparemment utiliser cgGetNamedStructParameter pour obtenir un handle vers un type que tu as défini ;)

Reply

Marsh Posté le 31-05-2007 à 13:41:27    

heu...ya même pas un exemple dans le manuel Cg, comment on utilise cette fonction?!

Reply

Marsh Posté le 31-05-2007 à 14:16:04    

Oui ok je vois ce que tu voulais dire mais il ya d'autres moyens pour changer la valeur d'une des propriétés de la structure...dans mons cas, je fais
cgGetNamedParameter(myCgFragmentProgram, "lights[0].property" ) pour changer celle de la lumière n°0. Ca marche parfaitement avec un tableau fixe.
Seulement voilà ce que j'ai maintenant:
 

Code :
  1. myCgFragmentParam_lightsArray = cgGetNamedParameter(myCgFragmentProgram, "lights" );
  2.   cgSetArraySize(myCgFragmentParam_lightsArray,1);
  3. assert ( cgGetArraySize(myCgFragmentParam_lightsArray,0)==1 ); // ok
  4.   myCgFragmentParam_lightDiffuse = cgGetNamedParameter(myCgFragmentProgram, "lights[0].diffuse" );
  5.   checkForCgError("could not get 'light.diffuse' parameter" ); // ok
  6.   float lightDiffuse[3] = { 0.95f, 0.95f, 0.95f };
  7.   cgSetParameter3fv(myCgFragmentParam_lightDiffuse, lightDiffuse);
  8. // ...pareil pour les autres propriétés de la lumière
  9.   float test[3];
  10.   cgGetParameterValuefc ( myCgFragmentParam_lightDiffuse, 3, test);


 
Résultat, en débug j'ai bien test = { 0.95f, 0.95f, 0.95f };
 
Donc tout est ok : le tableau est bien redimensionné, les valeurs passées sont correctes; et pourtant ma scène est quasi noire à l'affichage, preuve que le shader n'entre pas dans la boucle...étrange non?
 
Pour info, j'ai une Radeon X1950 Pro, qui bizarrement ne semble supporter que le profil CG_PROFILE_ARBFP1...Est-ce qu'elle ne supporterait pas cette technique?


Message édité par akalash47 le 31-05-2007 à 14:23:16
Reply

Marsh Posté le 31-05-2007 à 15:07:47    

Désolé, je ne connais pas l'API C de Cg, c'est juste que l'erreur m'a fait penser que cette fonction était une solution possible :(

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed