Bah si t'as la solution donne la. :p
En fait, c'est pas dur !
Admettons que tu as deux textures :
On va dire ici que la texture de base de ton terrain (La principale) est l'herbe, et que tu veux mettre des bouts de sable un peu partout.
Pour réaliser ça, il te faut ce qu'on appelle une
alpha map (En fait ça a genre plein de noms), qui va permettre, en nuances de gris, de représenter la répartition de la-dite texture, avec comme base : Noir = Rien, Blanc = Ta texture, Gris = Mix
Par exemple, pour un terrain 200x200, on va dire que, pour la texture de sable, j'ai cette alpha map :
Donc, tu vois, au final, je suis sensé avoir de l'herbe sur ton mon terrain, sauf vers le centre où on doit avoir un banc de sable.
Pour réaliser cette effet, donc, il faut les objets SFML suivants :
Deux sf::Texture pour l'herbe et le sable.
Deux autres, une pour l'alpha-map, une autre pour son inverse (J'expliquerai plus loin).
Quatre sf::RectangleShape (ou sf::Sprite) pour représenter les calques de terrain (Un contiendra seulement l'herbe, l'autre seulement le sable), les alpha-map.
Deux sf::Sprite pour avoir le calque du sable final, et le sol texturé final à afficher.
Deux sf::RenderTexture pour composer avec ces différents objets via sf::BlendMode.
Voyons du côté du code :
sf::Texture t_herbe, t_sable, t_alphamap, t_alphamap_inv;
sf::RenderTexture r_sol, r_sable;
sf::RectangleShape herbe, sable, alphamap, alphamap_inv;
sf::Sprite sable_final, sol_final;
Ensuite, tu fais tes chargements de fichiers :
t_herbe.loadFromFile("herbe.png");
t_herbe.setRepeated(true);
t_sable.loadFromFile("sable.png");
t_sable.setRepeated(true);
t_alphamap.loadFromFile("alpha.png");
t_alphamap_inv.loadFromFile("alpha_inv.png");
Puis tu fais les réglages sur les sf::RenderTexture :
r_sol.create(200, 200);
r_sol.clear(sf::Color::White);
r_sable.create(200, 200);
r_sable.clear(sf::Color::White);
et sur les sf::RectangleShape :
herbe.setSize(sf::Vector2f(200, 200));
herbe.setTexture(&t_herbe);
/* (IDEM pour les autres) */
Et puis maintenant, on se met au boulot !
D'abord, tu fais le rendu de ta texture de base (ici, l'herbe), en entier.
r_sol.draw(herbe, sf::BlendMultiply);
Puis tu dégages toutes les parties où le sable doit être (C'est là qu'intervient l'alpha-map inversée, en gros ça te fais du masking), avec de la multiplication de texture (Le noir efface, le blanc conserve).
r_sol.draw(alphamap_inv, sf::BlendMultiply);
Tu actualises la sf::RenderTexture (Pour éviter les inversions d'axe) :
r_sol.display();
Avec mon exemple, ma sf::RenderTexture contient, à présent, quelque chose comme ça :
Ensuite, tu fais la même chose pour le sable :
r_sable.draw(sable, sf::BlendMultiply);
r_sable.draw(alphamap, sf::BlendMultiply);
r_sable.display();
Ce qui te donne quelque chose comme ça :
Maintenant, il reste plus qu'à composer, via les sf::Sprite.
sable_final.setTexture(r_sable.getTexture());
sol_final.setTexture(r_sol.getTexture())
r_sol.draw(sable_final, sf::BlendAdd);
r_sol.display();
Et puis bah il te reste plus qu'à afficher le tout dans ta boucle principale, c'est-à-dire seulement le
sf::Sprite sol_final !
Tu as donc :
Et voilà !
Après, c'est peut-être bordélique, et puis j'explique pas bien, et si c'est pas très optimisé, je remercie d'avance les personnes qui pourraient aider à l'amélioration de la chose !
P.S. : Tu peux très bien faire ça avec plus de deux textures, il suffit à chaque fois de faire du masking sur les textures selon laquelle superpose laquelle.
P.S. 2 : Au lieu de charger une autre alpha-map pré-inversée, tu peux l'inverser dans le programme, j'imagine que c'est possible avec la SFML sans aucun problème.