PDA

Voir la version complète : Optimisation du FPS des conseils pour débutant...


CPPTryer
20/11/2005, 00h03
Salut,
Heu je voulais savoir si vous connaissiez des tutos qui expliquent ou alors si vous savez, comment faire pour optimiser un maximum son FPS avec C#/Direct3D. Car la j'affiche à peu près heu 900 Sprites de direct3d, et quand je les fais bouger en modifiant leurs coordonnées, ça ram beaucoup...
Bon ptet que 900 c'est trop, je sais pas, mais ptet qu'il faut activer certains paramètres pour lui dire de pas afficher ce qui n'est pas à l'écran par exemple... Fin voila quoi ce sont des conseils, merci d'avance^^
@++

Ruffi
20/11/2005, 02h31
Le meilleur moyen de pas afficher ce qui n'est pas à l'ecran, c'est de ne pas l'afficher ! Il n'y a (malheureusement) pas des paramettres qui feront tout à ta place.

Je ne sais pas comment tu gere ton jeu, mais si c'est en 2D (vu que t'utilise des sprites), tu devrait facilement savoir si l'objet est ou non dans l'ecran.
Si c'est en 3D, un fustrum culling sera sans doute necessaire.
Ca devrait deja te faire gagner un paquet de FPS.

Apres, regarde ce qui prends le plus de temps de calcul : ton affichage ou la mise a jours de tes données. Si c'est l'affichage, regarde deja à n'afficher que ce qui est necessaire (comme dit juste avant).
Si c'est la mise a jour de tes données, regardes tes algorithmes et essaye de voir où ça ralentit et comment faire pour ameliorer ça. Mais sur cette partie, c'est tres dependant de ton programme et je ne peux pas t'aider beaucoup plus que ça.

CPPTryer
20/11/2005, 10h38
Ok je vois, sinon je voulais savoir, est-ce que de passer des références a la place de l'objet lui même, lors de paramètre d'une fonction par exemple l'objet Device, ça peut faire gagner un tit peu globalement de perfs ?

Lenolian
20/11/2005, 12h31
En C#, il y a deux types d'objets : type de valeur (structure et types prédéfinis : int, float... string) et type de référence (classe).

Pour les types de références on ne peut manipuler que des pointeurs sur ces objets. Donc passer par ref un type de référence n'apporte rien à moins que tu ne veuilles modifier l'adresse pointée par ce paramêtre.

L'exemple donné par msdn :

class PassingRefByVal
{
static void Change(int[] pArray)
{
pArray[0] = 888; // This change affects the original element.
pArray = new int[5] {-3, -1, -2, -3, -4}; // This change is local.
System.Console.WriteLine("Inside the method, the first element is: {0}", pArray[0]);
}

static void Main()
{
int[] arr = {1, 4, 5};
System.Console.WriteLine("Inside Main, before calling the method, the first element is: {0}", arr [0]);

Change(arr);
System.Console.WriteLine("Inside Main, after calling the method, the first element is: {0}", arr [0]);
}
}

Ce qui produit :

Inside Main, before calling the method, the first element is: 1

Inside the method, the first element is: -3

Inside Main, after calling the method, the first element is: 888

Comme tu le voit le paramêtre n'est pas passé par référence, mais les modifications faites au données pointées afffectent bien l'objet. Par contre quand tu essayes de changer l'adresse pointée avec le new, alors la modification n'est que locale à la fonction.

Par contre pour les types de valeur c'est différents, chaque paramêtre de ce type d'une fonction sont copié et donc les modifications ne peuvent affecter l'objet original. La il faut bien passé l'objet par référence si on veut le modifier.

Le mor cle ref n'améliore les perfs que sur les structures (types de valeurs qui contiennent plusieurs autres types de valeurs) car elles permettent de ne pas passer de temps à copier les objets. Par contre sur un type de référence cela ne change pas grand chose (juste la copie d'un pointeur).

Le device étant un type de référence je ne pense qu'il y ait beaucoup à gagner à le passer avec ref.

Edit : le lien (http://www.games-creators.org/wiki/C_sharp) vers le wiki ou tu trouveras quelques informations sur le fonctionnement de dotnet et de C#. Ca te permettra je pense de mieux comprendre ce qui se passe lros de l'éxécution du code.

CPPTryer
20/11/2005, 12h58
Oki, merci comme je viens du C++ je savais pas trop si il passé un pointeur ou si il copié^^ Par contre d'après que ce que j'ai vu sur le net, la classe Microsoft.DirectX.Direct3D.Sprite à la réputation d'ètre lente:00000010:
C'est peut ètre ça qui explique pourquoi c'est si lent à l'éxécution...
Je dois dire que je suis un peu déçu...
Bonne aprem à tous

Lightness1024!
21/11/2005, 01h07
moi j'ai fait ma propre classe à base de quads.
mais c'etait avant que D3DXSprite soit devenue correcte ! (y'avais pas de mode billboarding en coordonnées 3D par exemple, juste du rhw lol)

bon, tout ca pour dire que ma classe à 1800 sprites boum, 3 FPS.
il faut remarquer cependant:

chaque sprite a sa propre orientation face au joueur et non une orthogonale à la direction de vision.
chaque sprite cast un rayon entre son centre et la caméra et vérifie la collision avec le monde.
le ZBuffer n'est pas acceptable pour ce probleme car il pourrait afficher le bord du sprite représentant un halo derriere un mur alors qu'on n'est pas ébloui par la lampe encore.

seuls les moteurs de particules peuvent afficher rapidement plus de 1000 sprites.
le tutoriel de directX affiche 2000 arbres de maniere assez fluide car il utilise le Zbuffer et un unique calcul d'orientation par frame !!!!
il s'apparente donc à un moteur de particule. (la différence est maigre je l'avoue)