Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Comment modifier un sprite pixel par pixel ?  (Lu 6032 fois)

0 Membres et 1 Invité sur ce sujet

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Comment modifier un sprite pixel par pixel ?
« le: Octobre 23, 2017, 03:50:54 pm »
Salut à tous ! :-]

Alors voilà, je désirerais modifier un sprite pixel par pixel car je travaille actuellement sur une projection de perspective de type Mode 7 ( dans le même principe que du floor casting, j'ai exploré plusieurs pistes qui étaient plus ou moins fonctionnelles mais toujours soumis à quelques problèmes particulièrement gênants.. ).

Si l'un d'entre vous pourrait m'expliquer comment procéder, j'aurais une excellente idée pour procéder à ma projection tant désirée une fois que j'aurais une idée sur la manière dont je pourrais procéder afin de modifier mes sprites dans les moindres détails.

Merci à vous ;-)
« Modifié: Octobre 23, 2017, 04:02:57 pm par Slash94 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #1 le: Octobre 23, 2017, 06:32:09 pm »
Première chose, les pixels sont stockés dans la texture, pas dans le sprite. C'est donc une texture qu'il faut modifier. Et ça se fait très facilement via la fonction Texture::update. En gros, tu travailles côté CPU dans un bête tableau de pixels (chaque pixel étant représenté par 4 composantes sf::Uint8) et quand tu a finis tu envoies le tout avec Texture::update pour mettre à jour l'affichage côté GPU.
« Modifié: Octobre 23, 2017, 06:33:53 pm par Laurent »
Laurent Gomila - SFML developer

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #2 le: Octobre 23, 2017, 09:37:30 pm »
Merci encore pour ton aide Laurent, néanmoins, penses-tu que sf::image me serait utile pour modifier une texture pixel par pixel ?
Car admettons que j'ai une texture qui fasse 80x80 et que je désire la modifier de manière à lui donner une forme de trapèze tout en prenant le soin de bien "resserrer" les pixels du haut et qui s'élargissent jusqu'en bas du trapèze , cette fonction me serait utile ou bien texture update me suffirait ?
 
( je pose cette question car je suis sur mon téléphone et au boulot donc pas encore pu tester la méthode de ta réponse ! )

Merci !

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #3 le: Octobre 23, 2017, 10:07:58 pm »
Citer
penses-tu que sf::image me serait utile pour modifier une texture pixel par pixel ?
sf::Image ne sert pas à grand chose dans ton cas. Ce sera un poil plus sympa à utiliser, mais beaucoup plus lent et au final tu n'auras pas gagné grand chose.

Citer
Car admettons que j'ai une texture qui fasse 80x80 et que je désire la modifier de manière à lui donner une forme de trapèze tout en prenant le soin de bien "resserrer" les pixels du haut et qui s'élargissent jusqu'en bas du trapèze
Là on parle de modifier une image pixel par pixel, donc après tu fais ce que tu veux : tu étires, tu resserres, tu fais du trapèze, du cercle, ou je ne sais quoi d'autre... ça ne changera vraiment pas grand chose ;)

Citer
je pose cette question car je suis sur mon téléphone et au boulot donc pas encore pu tester la méthode de ta réponse
Dans ce cas teste, et pose les questions après :P
Laurent Gomila - SFML developer

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #4 le: Octobre 24, 2017, 07:16:04 pm »
Salut à toi Laurent !
Je dois t'avouer que je suis un peu paumé... Si tu as du temps , tu pourrais me confectionner un mini exemple afin de jouer avec les pixels d'une rendertexture pour lui donner une autre forme ? ( exemple , faire une rotation de la texture ) ?

Je ne veux pas utiliser de sprite , c'est pour pouvoir dessiner un effet de perspective ensuite avec des lignes en faisant un scanline vertical  de mon écran par rapport aux pixels de la texture .. Merci :-)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #5 le: Octobre 24, 2017, 08:07:14 pm »
Qu'est-ce qui te pose problème exactement ? Tu coinces sur quoi ? Tu as déjà fait quoi ?
Laurent Gomila - SFML developer

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #6 le: Octobre 25, 2017, 01:15:55 pm »
Ben je n'arrive pas à comprendre le principe de la modification via un array de sf::Uint8..

J'aimerais vraiment avoir un exemple tangible, ça me ferait probablement un coup de déclic :-)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #7 le: Octobre 25, 2017, 01:23:40 pm »
// on crée une texture de taille 2x2 pixels
sf::Texture texture;
texture.create(2, 2);

// on déclare un tableau de pixels bruts de 2x2
sf::Uint8 pixels[2 * 2 * 4];

// on bidouille autant qu'on veut dans le tableau de pixels...
// là par exemple on remplit tout de pixels verts semi-transparents
for (int x = 0; x < 2; ++x)
    for (int y = 0; y < 2; ++y)
    {
        pixels[(x + y * 2) * 4 + 0] = 0;   // composante rouge
        pixels[(x + y * 2) * 4 + 1] = 255; // composante verte
        pixels[(x + y * 2) * 4 + 2] = 0;   // composante rouge
        pixels[(x + y * 2) * 4 + 3] = 128; // composante alpha
    }

// le tableau de pixels est prêt : on met à jour la texture
texture.update(pixels);

// plus tard, on affiche par exemple cette texture via un sprite
window.draw(sf::Sprite(texture));
 
Laurent Gomila - SFML developer

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #8 le: Octobre 25, 2017, 05:19:13 pm »
Merci beaucoup Laurent, tu es un homme fantastique !

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #9 le: Octobre 26, 2017, 05:41:13 pm »
Grâce à toi je commence à avoir un rendu mais l'affichage est saturé lorsque je suis trop près... si je galère encore d'ici quelques heures, je te solliciterais à nouveau avec mon code source.. :-D

https://gyazo.com/c177f8c8abef90d185ea366dcc733f84

Je balance un rayon la largeur de mon FOV ( donc 800 rayons sur un champ de 60 degrés car ma fenêtre de rendu est en 800*600 ) et dés que mon rayon est dans la texture, je récupère le pixel et l'affiche, malheureusement, plus la texture est grande plus c'est slow... donc si tu connais une méthode plus optimisée que ça pour faire un Mode 7-like, je suis preneur ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #10 le: Octobre 26, 2017, 08:05:31 pm »
Je n'ai jamais étudié les techniques pour faire ce genre de rendu, désolé. Mais j'imagine que tu peux facilement trouver des articles et/ou des projets qui expliquent ça très bien :)
Laurent Gomila - SFML developer

Slash94

  • Jr. Member
  • **
  • Messages: 89
    • Voir le profil
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #11 le: Octobre 27, 2017, 02:52:42 pm »
Salut l'ami,

J'ai réussi à faire ce que je voulais faire ! Récupérer les pixels un par un selon l'orientation d'un rayon qui parcourt un scanline ! :-D

https://gyazo.com/792b4c053fe375425900b7316cb9fbab

Le GIF est de mauvaise qualité mais je te laisse voir le résultat sur le screenshot ici, on voit bien mieux :

https://image.noelshack.com/fichiers/2017/43/5/1509108663-yes.png

En gros je récupère pixel par pixel le long du parcours du rayon :

        ///RECUPERATION DU TRAIT DE PIXELS AU FUR ET A MESURE///
        if (line[1].position.x >= 0 && line[1].position.x <= texture.getSize().x &&
            line[1].position.y >= 0 && line[1].position.y <= texture.getSize().y)
        {
            redLine[1].position = {line[1].position.x, line[1].position.y};
            sf::Color c = sf ::Color(img.getPixel((int)line[1].position.x, (int)line[1].position.y).r,
                                     img.getPixel((int)line[1].position.x, (int)line[1].position.y).g,
                                     img.getPixel((int)line[1].position.x, (int)line[1].position.y).b);
            vecColors.push_back(c);
        }

Et ensuite ma fonction d'assignation des pixels :

            texStripe.create(1, vecColors.size());

            sf::Uint8 pixels[vecColors.size()*4];

            stripe[0].texCoords = {0,0};
            stripe[1].texCoords = {0, vecColors.size()};
            stripe[1].position = {stripe[0].position.x, vecColors.size()};

            for (unsigned int i = 0 ; i < vecColors.size() ; i++)
            {
                pixels[(i)*4+0] = vecColors[i].r;
                pixels[(i)*4+1] = vecColors[i].g;
                pixels[(i)*4+2] = vecColors[i].b;
                pixels[(i)*4+3] = vecColors[i].a;
            }

            texStripe.update(pixels);

Merci infiniment à toi !!

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Comment modifier un sprite pixel par pixel ?
« Réponse #12 le: Octobre 27, 2017, 03:27:27 pm »
Citer
            sf::Color c = sf ::Color(img.getPixel((int)line[1].position.x, (int)line[1].position.y).r,
                                     img.getPixel((int)line[1].position.x, (int)line[1].position.y).g,
                                     img.getPixel((int)line[1].position.x, (int)line[1].position.y).b);
Pourquoi pas juste
sf::Color c = img.getPixel((int)line[1].position.x, (int)line[1].position.y);
??
Laurent Gomila - SFML developer