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

Auteur Sujet: effet de lumière et sf::RenderTexture  (Lu 3146 fois)

0 Membres et 1 Invité sur ce sujet

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
effet de lumière et sf::RenderTexture
« le: Janvier 16, 2015, 11:35:05 am »
Bonjour .

J'ai implémenté un effet de lumière, basé sur sf::RenderTexture. SVP pouvez-vous me donner votre avis, si quelque chose ne va pas?
Ca marche, mais c'est assez gourmand, et donne un rendu qui n'est pas forcément souhaité (j'ai comme un légers assombrissement autour de ma lumière générée).
J'ai besoin de génerer un grand nombre de ces lumières, et quand j'arrive au bout d'une centaine, par exemple, ça commence a ralentir (et j'ai un ordi assez puissant ). J'aimerais donc savoir si ma façon de procéder pourrait être optimisé/doit être revue etc...

mon système est ainsi:

Les objets lumineux contiennent un petit objet "Lumiere", qui contiennent une position, une taille, une sf::Color.


class Lumiere
{
public:

    Lumiere();
    ~Lumiere();


    void                                        positionne(float x, float y);
    void                                        recoitTaille(int taille);
    void                                        changeTaille(int change);
    void                                        recoitCouleur(int rouge, int vert, int bleu, int alpha);

    sf::Vector2f                             renvoiPosition();
    sf::Color                                  renvoiCouleur();
    int                                            renvoiTaille();


private:

    float                                       m_x, m_y;
    sf::Color                                 m_couleur;
    int                                          m_taille;

};

 

Ils envoient aux objets de décor sur lequel ils se trouvent (a l'aide de collision ) l'adresse de leurs lumières.


class DecorModulaire
{
   ...
   private:

            vector<Lumiere*>                              m_LumiereVector;
    ...
}
 

void DecorModulaire::recoitLumiere()
{
...
        if(collisionne())
        {
              if(m_demarreLumiere)
             {
                     m_renderTexture = new sf::RenderTexture;
                     m_renderTexture->create( m_textureLumiere->getSize().x , m_textureLumiere->getSize().y );
                     m_demarreLumiere = false;
              }
              ...
              m_lumiereVector.push_back(m_objetQuiEnvoiLaLumiere->renvoiLumiere());
              ...//ici avec conditions pour que seul les lumières demandés soient envoyés au moment voulut
        }
...
}

 


Ceux ci vont alors utiliser sf::RenderTexture pour superposer le nombre de lumières qu'ils doivent mettre sur la texture de fond, à l'aide de la texture de lumière du même décor.


//utilisation des donnés de la lumière a imprimer, a un rytme comparable a celui de l'animation(16 frame/s )
    for(vector<Lumiere*>::iterator it = m_lumiereVector.begin() ; it != m_lumiereVector.end() ; it ++ )
    {

    m_x_lumiere = (*it)->renvoiPosition().x - m_x ;
    m_y_lumiere = (*it)->renvoiPosition().y - m_y ;
    m_tailleLumiere = (*it)->renvoiTaille();

//transformation de ces données en cercle avec dégradé

    sf::Vertex vertexCercle[36];
    vertexCercle[0] = sf::Vector2f( m_x_lumiere                                                                                                      , m_y_lumiere );
    vertexCercle[1] = sf::Vector2f( m_x_lumiere                                                                                                      , m_y_lumiere - m_tailleLumiere );
    vertexCercle[2] = sf::Vector2f( m_x_lumiere + m_tailleLumiere/2                                                                                  , m_y_lumiere - sqrt ( -( (m_tailleLumiere/2) * (m_tailleLumiere/2) ) + (m_tailleLumiere * m_tailleLumiere)  )
);

    vertexCercle[..] = ...
...

    vertexCercle[0].texCoords = sf::Vector2f( m_x_lumiere                                                                                                      , m_y_lumiere );
    vertexCercle[1].texCoords = sf::Vector2f( m_x_lumiere                                                                                                      , m_y_lumiere - m_tailleLumiere );
    vertexCercle[2].texCoords = sf::Vector2f( m_x_lumiere + m_tailleLumiere/2                                                                                  , m_y_lumiere - sqrt ( -( (m_tailleLumiere/2) * (m_tailleLumiere/2) ) + (m_tailleLumiere * m_tailleLumiere)  ) );

    vertexCercle[..].texCoords ...
...

    vertexCercle[0].color = sf::Color( (*it)->renvoiCouleur() );
    vertexCercle[1].color = sf::Color( 0 , 0 , 0 , 0 );
    vertexCercle[2].color = sf::Color( 0 , 0 , 0 , 0 );

    vertexCercle[..].color ...
...

//et ici la transformation de la texture


    EI eiTest; //EI pour EntiteImage
    eiTest.recoitTexture(m_textureLumiere);
        for(int compteur = 0; compteur < 36 ; compteur ++)
        {
            eiTest.recoitVertex(vertexCercle[compteur]);
        }
    m_renderTexture->draw(eiTest);
    }

    m_renderTexture->display();

        m_EI_lumiere.recoitTexture(m_renderTexture->getTexture());
    }

 

et enfin voici, dans mon EI, ce qui se passe quand je lui envoie des vertexs :

...

public:

    void recoitVertex(sf::Vertex vertex2)
    {
        m_vectorVertex.push_back(vertex2);
    }



private:

virtual void draw(sf::RenderTarget& cible, sf::RenderStates states) const
{
    if (m_actif && m_vectorVertex.empty())
    {
            states.texture = m_texture;
            cible.draw(m_tableauVertex,4,sf::Quads,states);
    }
    if(!m_vectorVertex.empty())
    {
        cible.draw(&m_vectorVertex[0], m_vectorVertex.size(), sf::Triangles, m_texture);
    }
}

...
    vector<sf::Vertex>  m_vectorVertex;


 




Comme je le disais, ca marche mais c'est assez lourd. Si je ne met que quelques dizaines de lumières, ca tourne sans problème, mais dès que j'en génère quelques centaines, en me baladant dans l'environnement, ca commence a ramer....

Donc, svp, si vous pouvez m'aider, j'aimerais savoir si :

a ce stade , c'est normal que ca rame, avec le sf::RenderTexture, pour ce qui est demandé...

si cette facon de programmer vous semble "propre"...
 
comment faire pour éviter cette zonne sombre autour de la lumière ? utiliser un blend pourrait résoudre le pb? ou cela vient des vertexs?

Merci si vous pouvez m'aider  :D

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #1 le: Janvier 16, 2015, 01:36:45 pm »
Si j'ai bien compris ce que tu fais (pas sûr à 100%), ce que tu fais est incroyablement lourd. En gros, tu as besoin d'une unique render-texture, de la taille de la fenêtre, et dans laquelle tu vas dessiner toutes tes lumières. Ensuite tu dessines le résultat de cette render-texture sur ta scène normale, avec un sf::blend::Multiply. Fini.

PS : 100 lumières c'est énorme... j'ai du mal à imaginer la gueule de ta scène :P
PPS : tu devrais mettre encore plus d'espaces dans la définition de ta classe, on voit encore le nom des fonctions
PPPS : m_vectorVertex et m_tableauVertex dans la même classe... t'es sérieux ? et puis sans déconner, passe à l'anglais comme tout le monde, à chaque fois que tu postes ici ça pique les yeux ;)
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #2 le: Janvier 16, 2015, 02:58:48 pm »
OK. Merci pour ta réponse  ;)

Citer

En gros, tu as besoin d'une unique render-texture, de la taille de la fenêtre, et dans laquelle tu vas dessiner toutes tes lumières


En effet, ca parrait logique...Je vais voir comment je vais pouvoir mettre ca en place. Merci  :D

 
Citer

PS : 100 lumières c'est énorme... j'ai du mal à imaginer la gueule de ta scène :P


Oui, après, on ne voit jamais les 100 en même temps...C'est dans l’ensemble du niveau. (avec ma methode ca rame un peut, mais fonctionne tout de même)..


Citer
m_vectorVertex et m_tableauVertex dans la même classe... t'es sérieux ?

Alors là je me doutais que c'était pas le top...
serait-il mieux dans mon cas de faire une autre EntiteImage pour ca ? (type EI_Lumiere )



ps: pour l'anglais, ca va être difficile, car ca m'écorcherait un peut le coeur...  ;D
mais bon, pour le forum je ferais un effort ;) je vous doit bien ca  ;)

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #3 le: Janvier 16, 2015, 03:30:50 pm »
Ne change pas tes conventions de nommage juste pour ce forum. Je te donnais ce conseil car n'importe quel développeur un peu sérieux utilise des noms anglais. Si tu as l'intention de continuer le développement après ce projet, tu vas heurter des murs si tes noms restent en français. Il n'y a rien de pire que des noms "traduits" dans du code source, crois-en un développeur expérimenté ;)

Bref c'était juste un conseil.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #4 le: Janvier 16, 2015, 06:16:53 pm »
Ok, merci pour le conseil.

Pour mon prochain programme, je prendrais surement ce reflex,  faut pas être borné  ;).

J'essaye d'implémenter le sf::RenderTexture dans mon Afficheur afin de ne rendre les lumières seulement dans la fenetre. C'est, il me semble, ce que tu disais.
C'est surement bête, mais j'arrive pas a convertir les coordonnés du "worldPos" aux coordonnés de la fenêtre, pour rendre les lumières au bon endroit. (ce qui fait que mes lumières bougent par raport a la fenêtre et non au jeu)...

Cela donne ca :



        m_renderTexture->create(m_fenetre->getSize().x , m_fenetre->getSize().y);

        ...


    sf::Vector2f worldPos;
    worldPos.x = m_vue.renvoiVue()->getViewport().left;
    worldPos.y = m_vue.renvoiVue()->getViewport().top;

    m_renderTexture->mapCoordsToPixel(worldPos);

    const sf::Color color(0,0,0,0);
    m_renderTexture->clear(color);

    for(vector<EI_Lumiere*>::iterator it = m_EI_Lumiere.begin() ; it != m_EI_Lumiere.end() ; it ++)
    {
        m_renderTexture->draw( *(*it) );
    }
    m_renderTexture->display();
    sf::Sprite sprite(m_renderTexture->getTexture());
    m_fenetre->draw( sprite);



 

 C'est un peut flou, tout ca, pour moi, alors j'ai essayé aussi en inversant "mapCoordsToPixel" par "mapPixelToCoord" mais ca ne change rien. la lumière apparait bien, mais sur la fenetre "DefaultView" et non de la "Wordl View "...si je puis dire...

En fait je cherche simplement a changer l'emplacement de ma sf::RenderTexture, mais j'ai pas trouvé comment faire...

Suis-je sur la bonne voie, ou cette fonction n'est pas approprié ici ?


« Modifié: Janvier 16, 2015, 06:20:57 pm par mazertys17 »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #5 le: Janvier 16, 2015, 06:22:53 pm »
Il faut que tu dessines dans ta render-texture comme si tu dessinais dans ta scène (même vue, mêmes positions). Donc normalement il n'y a aucune conversion à faire.
Laurent Gomila - SFML developer

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #6 le: Janvier 16, 2015, 06:32:51 pm »
Merci,

En fait, je viens de trouver...En effet c'était simple :
J'aivais déjà essayé, mais sans remettre la fenetre au defaultView, donc ca ne marchait pas...


    m_renderTexture->setView(*m_vue.renvoiVue());

 

Et ca marche.

Merci en tout cas pour ton aide  :D

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #7 le: Janvier 16, 2015, 07:29:49 pm »
Juste une dernière chose, après je devrais me tenir tranquille ;) 

Comment utiliser un sf::Blend::Multiply ?
(j'ai pas trouvé )

Merci  :D

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : effet de lumière et sf::RenderTexture
« Réponse #8 le: Janvier 16, 2015, 08:54:48 pm »
window.draw(sprite, sf::BlendMultiply);

mazertys17

  • Full Member
  • ***
  • Messages: 123
    • Voir le profil
    • E-mail
Re : effet de lumière et sf::RenderTexture
« Réponse #9 le: Janvier 16, 2015, 09:24:40 pm »
yes.

Merci.  :D