XNA Tutorial 4 : Les matrices

Retourner au sommaire des cours  

Le précédent programme que nous avons réalisé était rudimentaire : nous n'affichions qu'un triangle... Il faut bien avouer que nous pourrions obtenir le même résultat sous PowerPoint ou en Winform. L'objet de ce tutorial va nous repositionner pleinement dans le monde 3D. Nous continuerons à afficher un triangle mais cette fois-ci nous utiliserons les matrices afin de l'animer.

Nous seront donc amené à étudier un peu de géométrie dans l'espace, les matrices et la caméra.

Repère 3D

Le monde de jeu se trouve dans un espace 3D orthonormé. A l'intérieur de celui-ci tout point est situé par l'intermédiaire de trois composantes : sa position par rapport à l'abscisse X, sa position par rapport à l'ordonnée Y, sa position par rapport à la côte Z. En repère 2D X et Y sont facilement identifiables : l'axe X est horizontal et Y vertical. En 3D "XNA" son se base plutot par rapport à un repère dit de "main droite". L'image ci-dessous montre un repère main droite.

Ce nom vient du fait que vous pouvez reproduire ce repère à l'aide de votre main droite. Le pouce représente l'axe X, l'index l'axe Y et le majeure l'axe Z. A l'intérieur du  monde de jeu ou World Space nous placerons désormais nos objets en utilisant des coordonnées 3D liées à cette représentation. Ainsi Z croît lorsqu'il se rapproche de l'observateur. L'axe X est orienté vers la droite, enfin l'axe Y croît avec la hauteur. Ainsi nous pourrions définir les vecteurs cardinaux Up, Down, Foarward, Backward, Left, Right de cette manière :

up = new Vector3(0f, 1f, 0f);
down = new Vector3(0f, -1f, 0f);
right = new Vector3(1f, 0f, 0f);
left = new Vector3(-1f, 0f, 0f);
forward = new Vector3(0f, 0f, -1f);
backward = new Vector3(0f, 0f, 1f);

Notre programme

Comme à l'accoutumé le programme du tutorial précédent va être repris et évolué pour prendre en compte les nouveautés de ce chapitre. Il sera renommé en "TroisièmeProjet".

Le but de cet article est donc de faire tourner le triangle sur lui-même. Là encore c'est les matrices qui vont nous aider. Nous allons faire coincider le taux de rotation du triangle en fonction du temps écoulé depuis la dernière frame affichée. De cette façon le triangle tournera toujours à la même vitesse, quelque soit la puissance de la machine où l'activité de son CPU. Nous avons vu précédemment que c'est la matrice World qui s'occupe de "réaliser" les transformations à effectuer sur un objet. Par transformation nous entendons translation, scale et ... rotation. Ecrire "à la main" une matrice pour qu'elle réalise une transformation n'est pas forcement très simple. Heureusement la classe Matrix possède un ensemble de membre statique (comme nous l'avons déjà vu) qui permettent de créer des instances très facilement.

Remplacez l'instruction d'affectation de la matrice World de l'effet à l'intérieur de la méthode Draw par cette ligne :

 this.effect.Parameters["World"].SetValue(Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds));

Nous appellons ici la méthode statique CreateRotationY qui renvoie une matrice configurée pour réaliser une rotation autour de l'axe Y. Le fichier effet auquel nous donnons la matrice va multiplier celle-ci par tous les vertices présent dans le flux envoyé à la carte graphique par l'intermédiaire de la méthode Draw. Les vertices ainsi multipliés vont voir leur position modifiée et vont donner l'impression d'être en rotation. Tout objet affiché entre les méthode Begin et End de l'effet seront ainsi soumis à cette transformation. Nous donnons à la méthode CreateRotationY le temps total écoulé depuis le lancement du jeu. Nous aurions pu donner une valeur constante type PI/4. Mais le triangle n'aurait pas été animé. Il aurait juste été legerement pivoté. Le fait d'utiliser le temps total écouté fait que notre triangle tourne à vitesse constante.

A l'exécution nous l'allons le voir tourner effectivement sur lui-même. Pourtant le programme comporte un problème : régulièrement le triangle disparait. Ce problème qui n'en est pas un est du au "back face culling". 

Backface Culling

 Le back face culling est un algorithme intelligent sur lequel repose la carte graphique pour réaliser ses rendu. Il permet d'enelver de l'affichage les faces (triangles) qui ne sont pas visible depuis la position de la caméra parceque situées dernière l'objet. Si vous regardez quelqu'un dans les yeux, nous ne voyez pas l'arrière de sa tête. Ici c'est le même principe. Comment la carte graphique sait-elle qu'une face n'est pas visible ? En fait c'est le développeur qui le lui indique au moment ou il créé le tableau de vertices. Si un triangle doit être affiché par l'intermédiaire de trois vertices placé dans l'ordre des aiguilles d'une montre alors il est visible, dans le cas contraire XNA ne l'affiche pas. Reciproquement si un triangle ne s'affiche pas c'est que les vertices qui le forment sont lus dans le sens inverse des aiguilles d'une montre. Auquel cas si vous placez la caméra de l'autre coté du triangle celui-ci sera visible. Nous n'allons évidemment pas déplacer continuellement la caméra. Il est plus simple de désactiver le culling. Ajoutez le code suivant à la méthode Initialize :

this.graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;

Le device possède un membre RenderState qui gère les propriétés d'affichage 3D dynamiques et notamment le culling employé. L'énumération CullMode permet d'indiquer si nous ne voulons pas de culling (None), si nous voulons cachée les faces dont le svertices sont lu dans le sens des aiguilles d'une montre (CullClockwiseFace) ou bien dans le sens inverse (CullCounterClockwiseFace).

Amélioration du code

Nous plaçons à l'intérieur de la méthode Draw des instructions qui ne sont pas directement liées à l'affichage : les trois affectations des matrices World, View et Projection. Déplacez ainsi les instructions : 

this.effect.Parameters["World"].SetValue(Matrix.CreateRotationY( (float)gameTime.TotalGameTime.TotalSeconds));

A l'intérieur de la méthode Update et les deux instructions :

this.effect.Parameters["View"].SetValue(Matrix.CreateLookAt(new Vector3(0, 0, -2), Vector3.Zero, Vector3.Up));

this.effect.Parameters["Projection"].SetValue(Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.GraphicsDevice.Viewport.AspectRatio, 0.1f, 2.1f));

dans Load.

Tout simplement parceque la matrice World doit être mise à jour à chaque frame alors que les propriétés et caractéristiques de la caméra ne changent pas. 

Pour terminer, et pour améliorer notre culture, modifiez le farPlaneDistance (dernier paramètre de la méthode CreatePerspectiveFieldOfView) qui définit la distance au delà de laquelle un objet n'est plus visible. Il est pour l'heure de 100f. Changez la valeur a 2.1f. Nous voyons à l'exécution notre triangle tourner complètement mais du fait de sa rotation, les vertices de sa base s'éloignent, et disparaissent au gré de la rotation (voir image ci-dessous).

 Le triangle est coupé 

 Ceci est du à notre far plane. Le triangle lorsqu'il est tourné de 90 dégré dépasse en profondeur la distance maximale de vision que nous avons indiqué dans la matrice de Projection. Remettez la valeur 100 pour que le programme marche parfaitement.

Autre élément important : modifiez la taille de la fenêtre affichant le triangle. Après cette action vous devriez à nouveau être soumis au back-face culling. Ceci est simplement du au fait que le device a été reinitialité lors de cette action. Il reprend donc ses valeurs par défaut. Il est donc nécessaire de lui respecifier le culling à appliquer. A ce niveau de nos connaissances nous pourrions parer ce problème qu'en mettant l'instruction concernée dans la méthode Update qui est appellée à chaque frame. Ce ne serait pas très propre ni optimisé... Heureusement le device offre un ensemble d'evenements qui permettent de parer àc ette eventualité. Enregistrez vous sur l'événement reset dans le constructeur de cette manière :

graphics.DeviceReset += new EventHandler(graphics_DeviceReset);

On mettre alors à l'intérieur de la méthode graphics_DeviceReset tout ce qui est nécessaire à la configuration du device :

void graphics_DeviceReset(object sender, EventArgs e)
{
     this.graphics.GraphicsDevice.RenderState.CullMode = CullMode.None;
}

Conclusion

Nos sommes maintenant prets à aborder les choses sérieuses. A partir de là nos connaissances sont suffisantes pour répondre à un grand nombre de problématiques : nous savons afficher des formes, les déplacer et placer une caméra. Essayez comme exercice de positionner la caméra à un autre endroit de la scène. De même, essayez d'autres transformations (faites un redimensionnement, une translation, les deux ...).

Le prochain article sera consacré aux indices, un type de reliaison de vertices très performants.

telecharger Vous pouvez télécharger le sample ici.   

A bientôt sur ce Blog !

Valentin Billotte

Retourner au sommaire des cours 

 

Comments

# re: XNA Tutorial 4 : Les matrices

Monday, January 15, 2007 3:51 AM by benm

Merci pour ce trés bon tutorial, ca serait sympa que tu le soumette dans http://tutmarks.com :)

# re: XNA Tutorial 4 : Les matrices

Monday, January 15, 2007 7:33 AM by valentin

de rien :)

merci à toi.

il est sur tutmark :)

# Merci

Wednesday, January 17, 2007 7:51 AM by Zorglub

Merci pour ces 4 tutoriaux. Ce sont les plus explicites que j'ai trouvés jusque maintenant.

Félicitations.... et on attend les suivants avec impatience.

# re: XNA Tutorial 4 : Les matrices

Wednesday, January 17, 2007 9:54 AM by valentin

marrant tu as posté ca quand je publiais un nouveau tutorial :)

# re: XNA Tutorial 4 : Les matrices

Friday, March 02, 2007 9:19 AM by SangJun

Très bon tutoriaux.

Pour pinailler, je noterai juste les petites fautes

"La première instruction rappatrie la valeur de la variable xWorld (de type matrice) du fichier effet . Elle la multiplie par une matrice effectuant une rotation sur l'axe Y. Nous effectuons une rotation d'un angle de Pi/1000 que nous multiplions PAR le temps écoulé depuis le dernier affichage."

"Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 0f, -40f), new Vector3(0, 0, 0), new Vector3(0, 1, 0));

Matrix projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.Window.ClientBounds.Width / this.Window.ClientBounds.Height, 1.0f, 45.0f);

Ici nous créons deux matrices nommées viewMatrix et projectionMatrix.

La première matrice va contenir une information à propos de la position de la caméra, le point vers lequel elle regarde et enfin l'angle qu'elle effectue avec l'horizontale. La méthode CreateLookAtstatic de la classe Matrix permet cela. Le premier paramètre correspond à la position. Nous nous plaçons à une hauteur de 10 unités (Y = 10), en et nous reculons de 40 unités (Z = 40). Le second paramètre correspond au point vers lequel regarde la caméra (ici vers l'origine (0, 0, 0)). Enfin la caméra est tenue droite (le Y = 1 indique que la perpendiculaire de la caméra se confond avec l'axe Y)."

donc ce serait plutôt :

Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 10f, 40f), new Vector3(0, 0, 0), new Vector3(0, 1, 0));

Voilà, loin de moi l'idée de vouloir mettre le doigt sur les problèmes, c'est juste pour aider que je note ça

# re: XNA Tutorial 4 : Les matrices

Saturday, March 03, 2007 11:01 AM by valentin

ah non au contraire, pinaille pinaille j'adore

ca permet d'améliorer les cours :)

merci à toi pour l'info je corrige de suite :)

# re: XNA Tutorial 4 : Les matrices

Sunday, April 08, 2007 9:13 PM by Aniketos

Cool}Cool!

# re: XNA Tutorial 4 : Les matrices

Friday, June 01, 2007 1:17 PM by Romain

Mais moi je vais encore pinailler lol. Enfaite la correction est fausse enfin pour moi SangJun à mit "donc ce serait plutôt :

Matrix viewMatrix = Matrix.CreateLookAt(new Vector3(0, 10f, 40f), new Vector3(0, 0, 0), new Vector3(0, 1, 0));"

Mais c'est là qu'il y a eureur il a fait une bonne est mauvaise correction le "-40" qui devient "40" c'est juste mais il a laissé le "10" comme il était avant alors que c'est sensé être "0" (en tout cas dans le téléchargement).

Voilas pour l'info.

# re: XNA Tutorial 4 : Les matrices

Wednesday, June 06, 2007 6:36 AM by Math

Salut !

Je suis actuellement tes tutoriaux, et, en arrivant sur celui-ci, j'ai une erreur à la compilation :

The method call is invalid.

Sur la méthode

this.graphics.GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, vertices, 0, 1);

dans Draw.

Y'a-t-il une erreur dans le code, ou je n'ai pas bien compris quelque chose ?

# re: XNA Tutorial 4 : Les matrices

Wednesday, June 06, 2007 9:16 AM by valentin

bonjour

tu reprend mon code tel quel ou tu as modifié qq chose ?

# re: XNA Tutorial 4 : Les matrices

Tuesday, July 24, 2007 12:54 PM by LuCiFeR

Salut,

tu as laissé -40 et new Vector3(0, 0, 1) au lieu de new Vector3(0, 0, 1). De plus l'image du début laisse supposer que y correspond à la profondeur, pour moi c'est Z non ? Qui croire ? :p

# re: XNA Tutorial 4 : Les matrices

Thursday, July 26, 2007 5:56 AM by @NOTIZ@

Bonjour,

J'ai 13 ans et je te remercie énormement pour ces tutoriaux qui mon permis d'apprendre plein de chose !

Bien que j'avais fait un peu de C++ (vraiment un peu) je suis content de pouvoir faire sa...

Mais j'aurais une petite question:

XNA est également fait pour Xbox, alors est-ce qu'il y a une différence de programmation pour Xbox ou pas ?

J'aimerais être éclairé, avoir plus de détail sur sa (quelque nuance du langage ?, faut-il refaire un

autre code, ...)

Bref peut être bête comme question,

Merci d'avance.

@NOTIZ@

# re: XNA Tutorial 4 : Les matrices

Wednesday, October 17, 2007 10:43 AM by valentin

Merci Lucifer, pour le -40 j'ai pas trop compris si tu peux m'expliquer :)

Pour la main, c'est à toi de voir les axes comme tu le veux, si je pivote la main, y devient la hauteur et Z la profondeur :)

Salut Notiz

il n'y a pas de différence dans la manière de développer entre une appli Xna sous Windows et une appli Xna sous XBox : c'est le même langage.

Seules une petite partie des fonctionnalités seront différentes (pour certains appels de méthodes des paramètres sont facultatifs/nécessaire suivant la plateforme (je pense à la spécification de résolution qui est propre au monde fenêtre et donc Windows). De même sous Windows tu as accès a des fonctionnalités qui n'existent pas ou partiellement sous Xna (System.Windows.Form, System.Thread ...)

Les projets Xna Xbox ou Xna Windows de VS Express limitent heureusement le choix des assembly que tu peux utiliser pour t'éviter tout probleme.

# re: XNA Tutorial 4 : Les matrices

Wednesday, January 21, 2009 12:45 PM by Vishnu

Qu est ce que t as technique "colored" ?? Le debut de ce tuto est pas du tout clair , je pense qu il me manque cette nouvelle technique dans mon fichier effect.fx ou alors elle est ailleurs .

# re: XNA Tutorial 4 : Les matrices

Thursday, January 22, 2009 2:21 AM by valentin

oui, je dois mettre à jour l'article rapidement pour le faire correspondre au Xna 3.0 ...

Désolé

# re: XNA Tutorial 4 : Les matrices

Saturday, April 18, 2009 8:03 AM by valentin

les images de ton sites ne s'affichent pas, pourquoi ?

j'aimerai connaître d'utiliser tout les effects de fichier .fx

en fait, quand on multiplient une matrice dans autre matrice via la fonction mul ou autre ... qu'est ce qu'on vois comme résultat?

pourquoi on multiplient ses matrices, on peut fixé le caméra sur le cois qu'on veut et c'est tout le role et jouer !!! pas besoin de casser la tete avec les multiplication dont je pige rien, non ?

merci d'avoir nous explique, et d'avoir nous donnes encore et encore des tutorial en francais sur le fichier .fx

# re: XNA Tutorial 4 : Les matrices

Saturday, April 18, 2009 10:56 AM by valentin

Il faut trois matrices pour réaliser un affichage :

La matrice World

La matrice View

La matrice Projection

World permet de placer un objet dans l'espace 3D (Par place j'entend Translation, Rotation, Scale).

View precise les propriétés de la "caméra" avec laquelle on visionne la scène (position de la caméra, l'endroit vers lequel on regarde ...)

Projection spécifié les caractéristiques de l'affichage (ration de l'écran, distance maximale de visibilité, angle d'ouverture, etc.)

Ces trois matrices permettent de passer d'un monde en 3 dimensions à un écran en deux dimensions. Inutile pour cela de réaliser un enchainement de milliers de calculs mathématique. Il existe une boite noire, nommée Matrix qui permet de réaliser facilemetn et rapidement ce genre de calculs.

Voilà pourquoi on les multiplie entre elles.

Un vertex multiplié par ces trois matrices devient une position 2D à l'écran de ton ordinateur.

# re: XNA Tutorial 4 : Les matrices

Thursday, June 11, 2009 12:28 PM by demandeuranonyme

Bonjour,

Je voudrais juste savoir à partir de quand les images seront mit à jour ?

Parce qu'il est difficile de savoir si nous avons la bonne chose à l'écran !

Merci

# re: XNA Tutorial 4 : Les matrices

Thursday, June 11, 2009 5:30 PM by valentin

ça vient ça vient :)

# re: XNA Tutorial 4 : Les matrices

Saturday, June 13, 2009 5:55 PM by demandeuranonyme

Merci beaucoup !

# re: XNA Tutorial 4 : Les matrices

Sunday, June 14, 2009 2:50 PM by demandeuranonyme

Salut, j'ai un problème (hey oui...)

Après avoir changé les coordonnés dans la méthode initialize j'ai essayé de démarrer la fenêtre d'affichage du projet, mais ça plante et ça m'indique un erreur sur cette ligne

this.effect.CurrentTechnique = effect.Techniques["Colored"];

qui dit :"This method does not accept null for this parameter.

Nom du paramètre : value"

Je n'ai aucune idée de ce que ça veut dire j'ai suivit ce début de tuto à la lettre(bah, faut croire que non finalement lol).

Autres choses: Fallait-il enlevé les lignes matrices (view, world et projection)qu'on avait placé dans le précédent tutoriel pour que ça fonctionne (J'ai essayé, mais même chose) ?

En cherchant pourquoi cet erreur j'ai trouvé ceci:

vertices[1].Position = new Vector3(7, 8f, 10f);

Or, il manque à la première coordonné (X je crois) un "f" après le 7, c'est normal ?

C'est tout je crois.

# re: XNA Tutorial 4 : Les matrices

Sunday, June 14, 2009 6:33 PM by demandeuranonyme

Salut !

j'ai un message d'erreur lorsque je lance la fenêtre d'affichage : "This method does not accept null for this parameter.

Nom du paramètre : value"

Cette ligne: "this.effect.CurrentTechnique = effect.Techniques["Colored"];"

est encadré en jaune

J'en suis à l'étape juste avant l'introduction aux matrices où je suis supposé voir un écran bleu.

Merci

# re: XNA Tutorial 4 : Les matrices

Sunday, June 14, 2009 7:34 PM by valentin

je reviens de vacances, je regarde ça demain ou mercredi :)

# re: XNA Tutorial 4 : Les matrices

Monday, June 15, 2009 7:03 PM by demandeuranonyme

ok oublie le dernier message, je croyais ça ne fonctionnais pas (apparemment y'a un délai d'une journée avant que les messages apparaissent). Merci.

# re: XNA Tutorial 4 : Les matrices

Tuesday, June 16, 2009 11:25 AM by DeadBarney

Pour demandeuranonyme, j'ai le même problème, c'est normal puisque nous sommes en XNA 3.0 (si j'ai bien compris) on va devoir attendre l'update le l'article...

# re: XNA Tutorial 4 : Les matrices

Tuesday, June 16, 2009 1:16 PM by valentin

Oui, j'espère l'update pret pour demain

J'ai terminé aujourd'hui la mise à jour des trois premiers pour la sortie de la 3.1.

# re: XNA Tutorial 4 : Les matrices

Wednesday, June 17, 2009 4:59 AM by valentin

voila l'article est à jour

# Tutoriaux Xna Game Studio : sommaire général

Monday, July 20, 2009 7:59 AM by Graphic Stream

(Tutoriaux adaptés au Xna Game Studio 3.1) Première partie : Apprentissage XNA Tutorial

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Powered by Community Server (Commercial Edition), by Telligent Systems