Big Tuto SFML 2 : Rabidja v. 3.0

Annexe 4 : Soyons flous !

Tutoriel présenté par : Skrool
Relecture et corrections : Jérémie F. Bellanger (Jay81)

Date d'écriture : 5 avril 2015
Date de révision : 20 mars 2016

      Introduction

   Eh oui ! Vous l'aurez remarqué : nos lumières apparaissent d'un coup lorsqu'elles sont chargées, et c'est pas très beau ! Du coup, on va remédier à cela grâce à notre belle variable m_targetIntensityangel

   Et on est reparti ! wink

 

   Tout d'abord, dans les fonctions create() et createDirectionalLight() du fichier lightEntity.cpp, on va remplacer:   

Fichier : lightEntity.cpp, remplacer :

//Dans create() et createDirectionalLight(), remplacer :
m_intensity = intensity;
 
//Par :
m_intensity = 0;
m_targetIntensity = intensity;

   La variable m_targetIntensity fonctionnera un peu comme la variable m_targetColor : elle servira de "modèle" pour la vraie variable. wink

   Et cela, on va le définir dans la fonction lightEntity::update() pour voir les lumières apparaitre progressivement :

Fichier : lightEntity.cpp, remplacer la fonction précédente par :

void lightEntity::update(Map &map)
{
//On anime la lumière selon son type
switch (m_type)
{
case 1: //Aucun effet
break;
 
case 2: // On crée un effet de balancement à la lumière directionnelle
if (m_timer < 30)
m_angle += 3;
else if (m_timer < 60)
m_angle -= 3;
else m_timer = 0;
break;
 
case 3: // On crée fait tourner la lumière directionnelle
m_angle += 4;
break;
 
}
 
// On incrémente le timer
m_timer++;
 
// On change m_intensity pour qu'il se rapproche de m_targetIntensity
// Si la différence est trop grande, on augmente beaucoup.
if (m_targetIntensity - m_intensity > 20)
m_intensity += 15;
 
if (m_intensity < m_targetIntensity)
m_intensity++;
else if (m_intensity > m_targetIntensity)
m_intensity--;
 
Generate(map);
}

   Mais pourquoi tu as mis la variable m_type de certaines lumière à 2 ou à 3 et le reste à 1 ? surprise

   Eh bien, cette variable va (enfin ! indecision) nous servir à animer nos lumières, comme vous pouvez le voir dans le code ci-dessus ! 

   C'est d'une simplicité déconcertante, mais d'une efficacité qui n'est plus à prouver. wink

   Voilà ! angel Vous avez votre système de lumières, implémenté avec vos tiles. Bien sûr, je vous encourage fortement à créer vos propres tiles de lumières, par exemple des tiles de lumières colorées, des lumières qui se déplacent, etc...

   Les possibilités sont illimitées ! cool

 

      C'est plutôt flou tout ça...

   Vous vous souvenez quand j'ai parlé d'ajouter un shader ? blush Eh bien, nous allons faire cela maintenant ! angel

   Comme les shaders sont des notions très complexes, nous allons juste voir comment les implanter. Ici, notre shader servira à créer un flou avec nos lumières. Cela sera beaucoup plus agréable à l'oeil. wink

   Commencez donc par copier le fichier blur.frag dans un nouveau dossier shader, que vous créerez dans le répertoire de votre projet. Pour rappel, ce fichier est disponible en téléchargement avec l'archive ci-dessus.

   Maintenant que c'est fait, créons une nouvelle variable dans notre gestionnaire de lumières :

Fichier : light.h : Rajouter :

//Effet de flou avec le shader
sf::Shader BlurEffect;

   Puis, initialisons notre shader dans le constructeur :

Fichier : light.cpp : Modifier le constructeur :

Light::Light(void)
{
 
//Création de notre renderTexture à la taille de notre fenêtre
m_shadowTexture.create(800, 600);
 
//Initialisation de notre couleur à 250 partout, ce qui correspond au blanc, donc à rien
m_shadowColor = sf::Color(250, 250, 250);
m_targetShadowColor = sf::Color(250, 250, 250);
 
// Chargement du shader de flou
BlurEffect.loadFromFile("/shader/blur.frag", sf::Shader::Fragment);
BlurEffect.setParameter("texture", sf::Shader::CurrentTexture);
 
};

   Et enfin, utilisons notre shader dans la fonction draw() :

Fichier : light.cpp : Remplacer le code précédent par :

void Light::draw(sf::RenderWindow &window)
{
// On crée un RenderStates avec le mode de rendu multiply, il nous sera indispensable pour la suite
sf::RenderStates render(sf::BlendMultiply);
 
// On associe notre shader à notre render state
render.shader = &BlurEffect;
 
// Et on règle ses paramètres
BlurEffect.setParameter("offset", 0.001);
 
// On vide notre render texture et la remplit de la couleur de l'ombre
m_shadowTexture.clear(m_shadowColor);
 
for (unsigned int i = 0; i < m_light.size(); i++) //On boucle sur nos lumières pour les afficher une à une
{
//Attention ! La fonction lightEntity::draw prend comme paramètre un render target.
//Nous allons en effet envoyer notre render texture d'ombre pour afficher les lumières dessus, et
//ensuite les afficher sur notre fenêtre
m_light[i].Draw(m_shadowTexture);
}
 
//On affiche les lumières se trouvant sur notre render texture
m_shadowTexture.display();
 
// On affiche notre render texture avec le mode multiply
window.draw(sf::Sprite(m_shadowTexture.getTexture()), render);
}

   Et voilà, on a un effet de flou avec notre lumière ! angel

   Fiouuuu ! C'était un gros morceau, jusque là ! indecision Notre troisième niveau devrait être un petit peu plus simple maintenant, non ? wink

   On pourrait s'arrêter là, mais ce serait dommage de ne pas s'occuper de la gestion des collisions murs/lumières ! angel Allez, au prochain chapitre, on s'occupe du plus dur : nos lumières réagiront comme de vraies lumières ! wink

   @ bientôt pour l'annexe 5 ! angel

                                          Skrool 

 

 
 
 
 
 

This site uses cookies to enable you to log in. We do not store or sell any personal data. By continuing to use this website, you agree to their use. Thanks!