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

Auteur Sujet: Problème avec les Threads !  (Lu 1512 fois)

0 Membres et 2 Invités sur ce sujet

lion24

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
Problème avec les Threads !
« le: Février 24, 2014, 04:44:35 pm »
Bonjour à tous et à toutes ;)

Voilà j'ai un petit souci avec les threads de SFML. Le plus simple est de vous passer tout le code :
// MandelBrot_Fractal.cpp : définit le point d'entrée pour l'application console.
//

#include "stdafx.h"
#include <iostream>
#include <SFML\Graphics.hpp>
#include <SFML\System\Thread.hpp>


using namespace std;

sf::Mutex mutex;
bool threadRun;

class Render
{
public:
        Render(sf::Image** _im, unsigned int _zoom, unsigned int _max_iter, bool _inColor = false)
                : m_thread(&Render::Run, this)
        {
                *_im = &im;
                inColor = _inColor;
                x1 = -2.1;
                x2 = 0.6;
                y1 = -1.2;
                y2 = 1.2;
                zoom = _zoom;
                max_iter = _max_iter;

                image_x = static_cast<unsigned int>((x2 - x1) * zoom);
                image_y = static_cast<unsigned int>((y2 - y1) * zoom);

                cout << "image size : " << image_x << ";" << image_y << ";" << endl;

                im.create(image_x, image_y, sf::Color::Black); //On cree une image vide (noire)


                threadRun = true;

        }
private:
        void Run(){
                cout << "test";
                for (unsigned int x = 0; x < image_x && threadRun; x++){
                        for (unsigned int y = 0; y < image_y && threadRun; y++){
                                double c_r = x / static_cast<double>(zoom)+x1;
                                double c_i = y / static_cast<double>(zoom)+y1;
                                double z_r = 0;
                                double z_i = 0;
                                double i = 0;

                                do{
                                        double tmp = z_r;
                                        z_r = z_r*z_r - z_i*z_i + c_r;
                                        z_i = 2 * z_i*tmp + c_i;
                                        ++i;
                                } while (z_r*z_r + z_i*z_i<4 && i<max_iter && threadRun);

                                if (threadRun){
                                        mutex.lock(); //On verouille l'image afin que les deux threads ne rentrent pas en collision
                                        if (inColor){
                                                if (i != max_iter)
                                                        im.setPixel(x, y, sf::Color(0, 0, static_cast<int>(i * 255 / max_iter)));
                                        }
                                        else{
                                                if (i == max_iter)
                                                        im.setPixel(x, y, sf::Color::White);
                                        }
                                        mutex.unlock();
                                }
                        }
                }
                if (threadRun){
                        cout << "Render is over (" << elapsed.getElapsedTime().asSeconds() << "s) ! Saving..." << endl;
                        im.saveToFile("Fractal.png");
                        cout << "Saved in \"Fractal.png\"" << endl;
                }
                else{
                        cout << "Rendering aborded." << endl;
                }
        }

        sf::Thread m_thread;

        double x1;
        double x2;
        double y1;
        double y2;

        unsigned int zoom;
        unsigned int max_iter;

        unsigned int image_x;
        unsigned int image_y;
        sf::Clock elapsed;
        bool inColor;
        sf::Image im;
};


int main(int argc, char* argv[])
{
        //On crée la fenetre, on prepare le sprite et l'image...
        const unsigned int RESO_X = 800;
        const unsigned int RESO_Y = 600;
        sf::RenderWindow App(sf::VideoMode(RESO_X, RESO_Y, 32), "Fractales");
        App.setFramerateLimit(60);
        sf::Image* ima = NULL;

        Render rend(&ima, 2500, 500, true);
        sf::Texture texture;
        sf::Sprite spr;
        texture.loadFromImage(*ima);
        spr.setTexture(texture);

        //Objet permettant de limiter l'acces aux fonctions d'affichage, qui bloquent le thread de rendu à cause des mutexes
        sf::Clock clock;
        const unsigned int time = 250;

        //zoom vue, postition camera, ...
        sf::View view(sf::Vector2f(((float)ima->getSize().x / 2), ((float)ima->getSize().y / 2)), sf::Vector2f(RESO_X / 2, RESO_Y / 2));
        App.setView(view);

        while (App.isOpen())
        {
                sf::Event Event;
                while (App.pollEvent(Event))
                {
                        if (Event.type == sf::Event::Closed){
                                App.close();
                        }
                        //zoom / dezoom avec les molettes
                        else if (Event.type == sf::Event::MouseWheelMoved){
                                if (Event.mouseWheel.delta > 0)
                                        view.zoom(1.5);
                                else
                                        view.zoom(0.75f);
                        }
                        //deplacement
                        else if (Event.type == sf::Event::KeyPressed){
                                if (Event.key.code == sf::Keyboard::Left)
                                        view.move(-10, 0);
                                else if (Event.key.code == sf::Keyboard::Right)
                                        view.move(10, 0);
                                else if (Event.key.code == sf::Keyboard::Up)
                                        view.move(0, -10);
                                else if (Event.key.code == sf::Keyboard::Down)
                                        view.move(0, 10);
                        }
                }

                //Si suffisament de temps s'est déroulé depuis le dernier affichage
                if (clock.getElapsedTime().asMilliseconds() > time){
                        clock.restart();
                        mutex.lock(); //On verouille l'image
                        App.draw(spr); //On l'affiche
                        App.display(); //On raffraichi l'écran
                        mutex.unlock(); //On rend la main au thread de rendu
                }
        }

        threadRun = false;
        return 0;
}
 

Il s'agit d'un code permettant de dessiner la fractal de Mandelbrot. La classe Render est la classe de rendu qui se charge donc du rendu de l'image dans la fenêtre.
Cette classe est donc bien entendu "threadée" pour éviter le freeze de la fenêtre. Cependant, le programme ne rentre jamais dans ma fonction "Run()" "test" ne s'affiche pas, or j'ai bien suivi la doc sur les Threads mais ça ne marche pas..  :-\

Pour info, j'utilise la version 2.1 de SFML. Je suis nouveau dans SFML donc soyez indulgent si j'ai fait une grosse boulette :D

Merci à vous.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Problème avec les Threads !
« Réponse #1 le: Février 24, 2014, 05:06:30 pm »
Où est m_thread.launch() ?
Laurent Gomila - SFML developer

 

anything