Bonsoir,
Je rencontre actuellement un problème avec XNA, dans l'optique de faire une classe qui servira de base pour l'héritage, j'ai une classe Sprite dont dérive une classe Player.
Pour dessiner l'image j'utilise cette surcharge de méthode ![]()
public void Draw (
Texture2D texture,
Vector2 position,
Nullable<Rectangle> sourceRectangle,
Color color,
float rotation,
Vector2 origin,
float scale,
SpriteEffects effects,
float layerDepth
)
http://msdn.microsoft.com/fr-fr/library/ff433988%28v=xnagamestudio.40%29.aspx
Cependant je rencontre un petit problème lors de l'affichage ![]()
![]()
Le sprite parait flouté et surtout déborde sur le prochain sprite de la ligne, alors que la hauteur/largeur affichée est correcte (10x30).
Après quelques recherches, notamment sur Stackoverflow, j'ai trouvé ce sujet : http://stackoverflow.com/questions/14821400/sprite-becomes-blurred
En gros, si mon vecteur position est à X : 115,6 et Y : 67,8, physiquement on ne peut afficher une couleur A et B différente sur un pixel (vous m'aurez compris).
Il faut donc que j'arrondisse la valeur mon vecteur au supérieur ou inférieur, chose faîte mais toujours le même soucis ...
this.position.X = Convert.ToInt32(Math.Ceiling(this.position.X));
this.position.Y = Convert.ToInt32(Math.Ceiling(this.position.Y));
Du coup quand j'utilise la surcharge de méthode qui prends pas en compte un Vector2 position mais un rectangle, je peux faire new Rectangle(100, 100, 10, 30); et mon image s'affiche comme je veux, sans floutage ou débordement ...
Du coup j'aimerai savoir comment résoudre ce petit soucis concernant l'utilisateur de l'objet Vector2, d'autant que quand je passe en débogage voici la valeur de mon objet Vector2 : {X:100 Y:100} aucune virgule ...
Merci par avance désolé du pavé. ![]()
J'ai jamais fait de XNA mais je vais essayer de te répondre car ce sont des problèmes assez courants
Pour le soucis de débordement si t'utilise une image qui a plusieurs sprites, en opengl du moins y'a une technique courante qui est de rajouter du padding entre les sprites
D'après l'image là il y a un filtre linéaire d'appliqué non ? Tu as essayé de le retirer ? D'après google c'est le filtre de base et tu peux le retirer assez facilement http://gamedev.stackexchange.com/questions/6820/how-do-i-disable-texture-filtering-for-sprite-scaling-in-xna-4-0
Là normalement ton image ne sera plus du tout floue
Devoir caster manuellement en int à chaque fois que tu veux dessiner un truc ça me semble être pas top comme contournement
Enfin après je laisse les gens habitués au XNA répondre plus précisément ![]()
J'ai déjà essayé, aucun changement ...
Sur d'autres projet j'ai pas ce soucis, dès que j'utilise un Rectangle à la place du Vector2 aussi. Du coup je suis un peu 'perdu'.
Mais merci de la réponse. ![]()
J'ai eu une réponse sur developpez.net entre temps à propos de ça, en gros comme je disais ça arrive lorsque qu'on essaye de desinner sur un demi-pixel, voici la réponse dancingmad sur leur forum ![]()
Pour le flou, il s'agit bien d'un problème d'interpolation comme c'est expliqué dans le lien que tu as posté : lorsque une image est affichée avec une position qui n'est pas nombre rond, le shader va par défaut interpoler les pixels pour "atténuer" le tout.
Du coup j'ai pu corriger en spécifiant le paramètre SamplerState dans la méthode Begin() de SpriteBatch ![]()
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, null);
Sauf que la plupart des autres paramètres (4 et 5 pour ma part) sont un petit peu technique et je n'ai pas tout compris, du coup je continue quand même à comprendre mon problème d'affichage sans cette solution (afin de pas rester bête
).
Vu que j'affiche le sprite sur une position constituée d'entiers, logiquement il ne devrait pas y avoir ce problème ... ![]()
C'est bien ça, c'est le filtrage de la texture qui faisait le débordement. Faudrait que la dimension du sprite colle a la dimension en pixel de la texture pour éviter ce genre de problème. Et mettre en PointClamp n'est pas une mauvaise idée.
Bah dans mon cas le sprite fait 10x30 sur Photoshop, et 10x30 est bien affiché ici, c'est juste qu'avec ce Vector2 au lieu d'un Rectangle bah ... Ca foire un peu ...
"et 10x30 est bien affiché ici"
Non, il me semble que le sprite est affiché en bien plus grand, sur ta capture d'écran...
Donc étirement des pixels, donc filtre bilinéaire d'appliqué si on n'en spécifie pas un autre en paramètre... ![]()
C'est juste le param-tre scale que j'ai mis en x4 pour montrer le problème, même à échelle 1 donc taille réelle le problème est présent.
"C'est juste le param-tre scale que j'ai mis en x4 pour montrer le problème"
On ne voit pas le problème de base, puisque tu en rajoutes un autre avec ce facteur d'étirement...
Sinon, vérifie si ta texture est compressée ou non, s'il va pas la redimentionner automatiquement en puissance de 2, et utilise plutôt la fonction floor() plutôt que ceil() ![]()
Bon bon bon ... Sans le scale je n'ai plus le problème comparé à avant, et en gros je n'ai rien changé ... J'ai juste essayé la surcharge du SpriteBatch et j'ai remis ensuite la surcharge avec zéro paramètres et certaines textures n'ont plus le soucis alors qu'avant oui avec un simple Begin() ...
Merci pour le Floot, j'avais pas vraiment utilisé cette classe jusqu'à maintenant j'avais pas fait attention à cette méthode. ![]()
Bonsoir,
Pour ma part...
J ai pas mal bossé sous le framework XNA.
La plupart de mes ennuies concernant le render d'une texture sur un draw tou bete vennait du fait que la doc du framework n'est pas conforme à l'execution. Exemple le point d'origine de la texture par rapport au scale appliqué.
A mon avis, utilise le draw texture de base, c'est a dire Texture and Position. Pas de rotation et encore plus de scale cumulé sauf si tu souhaite débuguer le framework, etcs...
Pour ma part, et je le regrette j'ai abandonné cette techcno. Plus de support, plus de portabilité sous la one. Le seul truc qui va rester et qui me semble positif, c'est la gratuité de visual studio et de ce framework meme méga buggué mais gratos qui encapsule le directX.
Il existe par contre une alternative au framework de krossoft, sans rien changer à ton code tout va fonctionner comme tu le souhaites.
http://monogame.codeplex.com/
Te souhaitant bonne réussite.
Re,
Me suis relut et finalement me suis dit que je marquais les mêmes messages que les autres, a savoir du genre le texel x25 dans ta matrice 12 ben c'est pas bon, t'a pas compris moi je sais...
Comme précisé auparavant, le framework Xna n'est pas dénué de certains bugs, et aussi et surtout parfois prête à confusion à son interpretation.
Je vais donc tenter de te rappeler les différentes méthodes d'affichage d'une texture sous ce framework, à toi d'utiliser la bonne.
1 - SpriteBatch.Draw (Texture2D, Rectangle, Color)
La tu as juste à spécifier la texture 2D à afficher, Son rectangle de destination (c'est a dire sa position écran pixel et largeur et hauteur, ainsi que la couleur éventuelle en over. White n'ajoutant aucune teinte supplémentaire).
Le rectangle de destination correspond a la position et a la taille d'affichage que tu souhaite. Donc rectangle.width = Texture2D.width && rectangle.height = Texture2D.height, ton image est a la position rectangle.x && rectangle.y avec sa taille d'origine.
// A utiliser sans modération cela marche à tous les coups
2 - SpriteBatch.Draw (Texture2D, RectangleDestination, Nullable<RectangleSource>, Color)
La c'est deja plus sympa, on te permet de spécifier la portion d'image que tu veut afficher par RectangleSource et aussi la position et la taille que tu veut restituer à l'écran par RectangleDestination.
Si RectangleSource == null ben cela prends simplement toutes les données de Texture2D.
// A utiliser sans modération cela marche à tous les coups
3 - SpriteBatch.Draw (Texture2D, RectangleDestination, Nullable<RectangleSource>, Color, Rotation, (Center)Vector2, SpriteEffects, LevelLayer)
Aille cela se complique hein.
Ce qui change par rapport au point 2, tu peut donner un angle de rotation à ta texture (en radian) et tu précise ou ce situ le centre de rotation. Pour le spriteEffects me souvient plus, LevelLayer corresponds à l'ordre empilement du render d'affichage de ta texture par rapport aux autres.
// Alors là attention, pour obtenir un rendu correct, il faut bien maîtriser et mentionner le centre de ta texture ainsi que son angle de rotation, autrement tu va galérer...
Mais ya quand même plus simple hein
4 - SpriteBatch.Draw (Texture2D, Vector2, Color)
La je pense que tu as compris... Ta texture, ta position et eventuellement une petite couleur d'appoint.
Pour résumer car je vais pas faire un roman, tu as choisi la méthode de render la plus contraignante et la plus difficile à maitriser.
Il me semble normal (quoi que purée de bug Xna) que si tu utilise une méthode qui permet ta modification d'echelle, de ta texture, sa rotation en fonction d'un centre xy, ects, qu'il t'arrive des renders incohérents pour une utilisation de base.
Le draw d'une texture possède de multiples méthodes, je n'en n'ais mentionné que quelques unes. Quand on utilise un framework le plus dur chemin c'est de l'apprendre et surtout de le comprendre.
Je reste a ta disposition pour te filer un coups de main au cas ou.
Tout d'abord, merci de tout ces détails.
Je sais que cette méthode est la plus contraignante, je réalise en fait une classe Sprite générique qui me servira de 'base' pour l'héirate d'autres classes. J'ai utilisé cette méthode Draw car bien qu'elle soit contraignante, c'est la plus modulable à mon sens pour le rendu du sprite.
Actuellement je n'ai plus de problème de rendu après avoir modifiés quelques paramètres de la méthode Begin()
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.Default, null);
A la place du vecteur position, si je mettais un objet Rectangle ( 3ième surcharge ici : http://msdn.microsoft.com/fr-fr/library/microsoft.xna.framework.graphics.spritebatch.draw%28v=xnagamestudio.40%29.aspx ) Je n'avais pas ce problème d'interpollation car la position du Rectangle était bien un entier.
Pourtant en faisant bien attention de placer des entiers dans la position X/Y de mon vecteur -pour la surcharge la plus contraignante-, cela faisait ce problème.
Du coup cela paraissait illogique pour ma part qu'un problème qui doit normalement survenir lorsqu'on tente d'afficher à la coordonnée X : 100.304 Y : 204.5853 (car il est impossible de diviser la coloration d'un pixel), survenait aussi lorsque la position était bien constituée d'entiers.
Voilà voilà. ^^
En fait ce qu'il faut que tu comprenne, comme te l'ai dit c'est que Xna sur certaines fonction est bugué.
Le fait de ne pas mettre par exemple de valeur de rotation != de zéro n’empêche pas par exemple que la procédure de traitement d'une rotation soit effectivement effectué en interne, ainsi que toutes les autres qui en découlent. Cela n'arrange pas ton cas non plus d'utiliser un sprite qui n'est pas en modulo 2. En gros on te fait une rotate de 360 degre sur un pivot de rotation incertain.
Si les codeur de Xna avait eu la bonne idée de faire un test sur tes paramètres afin d'executer ou non les routines appropriées tu n'aurais certainement pas eu d'ennuies.
D'un autre coté, si une méthode équivalente à ce que tu désire faire existe difficile de les incriminer.
Alors bugs ou incohérence dans leur doc du framework, à toi de trancher.
Bonne continuation.
J'essaierai du coté de Monogame, tu disais que je n'aurai aucune adaptation de code à faire (enfin sûrement 1/2 paramètres à changer par-ci, par-là) pour voir le rendu.
Je verrai ce que ça donne, j'ai juste entendu de nom, jamais essayé ..
Fait un test, la mise en oeuvre est simple. De plus tu sera muti-plateforme. Le support est tres tres bon. Le seul truc que je n'ais pas vraiment testé à fond avec ce framework c'est sont utilisation avec le moteur physique "Farseer Physics Engine".