XNA – Dessiner des quads (et des primitives) dans le bon ordre

Je connais assez bien la 3D dans XNA et, malheureusement, j’ai rencontré un problème pour lequel je ne trouve pas la solution. (Je ne sais même pas quel est le problème).

Pour faire court: je dessine des quads dans mon jeu en utilisant:

effect.World = Masortingx.Identity * Masortingx.CreateRotationX(Rotation.X) * Masortingx.CreateRotationY(Rotation.Y) * Masortingx.CreateRotationZ(Rotation.Z) * Masortingx.CreateTranslation(Position); // Apply camera-masortingxes effect.View = viewMasortingx; effect.Projection = projectionMasortingx; graphics.VertexDeclaration = vertDec; // Begin effect drawing effect.Begin(); foreach (EffectPass pass in effect.CurrentTechnique.Passes) { pass.Begin(); graphics.DrawUserIndexedPrimitives ( PrimitiveType.TriangleList, quad.Vertices, 0, 4, quad.Indexes, 0, 2); pass.End(); } effect.End(); 

Mon effet a aussi ces propriétés:

  this.effect.TextureEnabled = true; this.effect.Texture = texture; 

Et il fonctionne. Mon quad est bien dessiné et moi je suis heureux. Cependant, il y a un petit problème. Si un quad est derrière un autre quad ou un modèle régulier, l’ordre dans lequel je les dessine est déterminé par celui qui est tracé en haut.

Disons que je dessine le quadrilatère A avant le quadrilatère B, alors B sera affiché au-dessus du quadrilatère A même s’il est inférieur de 40 unités dans l’axe des Z. Cela semble très déroutant, je dois dire! 😉

Maintenant, je n’ai eu aucun problème comme celui-ci avec mes mailles habituelles, c’est quand les primitives sont impliquées que les choses se compliquent. Le même problème se pose pour tracer des lignes régulières:

  graphics.DrawUserIndexedPrimitives( PrimitiveType.LineSsortingp, pointList, 0, // vertex buffer offset to add to each element of the index buffer 6, // number of vertices in pointList new short[] { 0, 1 }, // the index buffer 0, // first index element to read 1 // number of primitives to draw 

Donc, ce que je demande vraiment, c’est:

A) Est-ce normal? Devrais-je construire un moteur spécial qui décide quand dessiner quoi? Je peux facilement contourner ce problème dans mon projet en dessinant des éléments au bon moment, mais je peux imaginer un jeu où je ne pourrais pas. Un fps par exemple ne pourrait pas dessiner ses panneaux publicitaires partout! 😉

B) Si ce n’est pas normal, quelle pourrait en être la cause et quelle serait une solution / un bon moyen de déboguer l’erreur.

J’apprécierais toute aide pour résoudre ce problème! 🙂

On dirait que le tampon de profondeur est désactivé. Peut-être dessinez-vous des sprites? (L’utilisation de SpriteBatch modifiera les différents états de rendu nécessaires pour un dessin 3D normal.)

Essayez d’append cette ligne de code avant de dessiner des objects 3D:

 GraphicsDevice.RenderState.DepthBufferEnable = true; 

Liens connexes:

  • SpriteBatch et rendus (pour XNA 3.1)
  • SpriteBatch et renderstates dans XNA Game Studio 4.0
  • Propriété RenderState.DepthBufferEnable

Pour une explication du tampon de profondeur (ou “Z-buffer”), vous pouvez consulter l’ article de Wikipédia .

Pour décrire brièvement le tampon de profondeur: Il s’agit essentiellement d’une image bitmap de votre scène qui stocke la distance entre chaque pixel dans l’écran (la profondeur). Lorsque vous allez dessiner votre deuxième object, il calcule d’abord la “profondeur” de chaque pixel qu’il va dessiner – et dans les zones où se trouve déjà un object “devant” (pixels avec une valeur de profondeur plus proche) dans profondeur tampon, il sera tout simplement ignorer le dessin pour ces pixels.

(La raison pour laquelle vous n’avez pas de problèmes avec vos maillages habituels est probablement due au retrait de la face arrière et à l’absence de “bits qui se chevauchent” dans vos maillages.)

En ce qui concerne un bon moyen de déboguer ce type d’erreur (problèmes étranges de tampon de profondeur, états de rendu incorrects et la plupart des autres cas dans lesquels la sortie restituée n’est pas celle que vous attendez), je recommande fortement d’installer le Kit de développement logiciel DirectX et d’ apprendre à utiliser PIX .

Merci de répondre à cette question! Juste un suivi pour quiconque veut savoir sur cette réponse. Dans xna 4.0, cela a un peu changé.

Certains objects de mosaïque 3D étaient transparents par rapport à d’autres objects 3D. Cela était dû à la suppression de:

 GraphicsDevice.RenderState.DepthBufferEnable = true; 

Dans XNA 4, ceci a été remplacé par:

 DepthStencilState depthBufferState = new DepthStencilState(); depthBufferState.DepthBufferEnable = true; GraphicsDevice.DepthStencilState = depthBufferState; 

Tiré de cette source: http://www.hexworld.co.uk/blog/?cat=9