123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- # include <iostream>
- # include <vector>
- # include <SDL/SDL.h>
- # undef main
- # include <SDL/SDL_gfxPrimitives.h>
- struct Contact
- {
- float temp ;
- Uint32 y ;
- Uint32 x ;
- };
- int main(int argc, char const *argv[])
- {
- /// [0] Requête des informations
- std::cout << "LANCEMENT DIFFUSION CHALEUR" << std::endl << std::endl;
- // [0.1] Dimensions de la fenêtre
- bool changement(false);
- Uint32 w_cmd(400), h_cmd(300);
- float lambda( 0.2495 );
- unsigned int iteration( 1 );
- std::cout << "Changer les valeurs par défaut ? (0:non, 1:oui)" << std::endl << ">>>";
- std::cin >> changement;
- if ( changement )
- {
- std::cout << "Hauteur de la fenêtre ?" << std::endl << ">>>";
- std::cin >> h_cmd;
- std::cout << "Longueur de la fenêtre ?" << std::endl << ">>>";
- std::cin >> w_cmd;
- std::cout << "Conductivité thermique ?" << std::endl << ">>>";
- std::cin >> lambda;
- std::cout << "Nombre d'itérations par frame ?" << std::endl << ">>>";
- std::cin >> iteration;
- }
- const Uint32 w( w_cmd );
- const Uint32 h( h_cmd );
- /// [1] SDL
- // [1.1] Démarrages SDL
- if ( SDL_Init( SDL_INIT_VIDEO ) < 0)
- {
- std::cout << "Impossible d'initialiser la SDL: " << SDL_GetError() << std::endl;
- return 1;
- }
- // [1.2] Préparation de fermeture
- atexit(SDL_Quit);
- // [1.3] Para-fenêtre
- SDL_WM_SetCaption("Diffusion Chaleur", 0);
- /// [2] Préparation des composants SDL
- // [2.1] Préparation de la fenêtre
- SDL_Surface* screen = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
- if ( !screen )
- {
- std::cout << "Bug à l'initialisation: " << SDL_GetError() << std::endl;
- return 1;
- }
- // [2.2] Préparation variables
- SDL_Rect mouse({ 400, 200, 0, 0 });
- // [2.3] Préparation surfaces
- // [2.4] Préparation du temps
- Uint32 frameRate( 60 );
- Uint32 tprev(0), twait( 1000 / frameRate ), total_frame(0);
- bool pause( false );
- // [2.5] Préparation des messages
- std::string msg("Victor");
- /// [3] Préparation de la chaleur
- // [3.1] Préparation des buffers
- float buffer[2][h][w]; // entre 0.0f et 1.0f
- int current_buffer(0), next_buffer(1);
- // [3.2] Liste des conditions aux limites
- std::vector<Contact> limiteur;
- bool trigger( false );
- float temp( 1.0f );
- // [3.3] Conditions initiales
- for ( int k(0); k < 2; k++ )
- for ( Uint32 i(0); i < h; i ++ )
- for ( Uint32 j(0); j < w; j ++ )
- {
- buffer[k][i][j] = 0.0f;
- }
- /// [4] Boucle principale
- bool done( false );
- SDL_Event event;
- while (!done)
- {
- // [4.1] Gestion évènements
- while (SDL_PollEvent(&event))
- {
- switch (event.type)
- {
- case SDL_QUIT:
- done = true;
- break;
- case SDL_KEYDOWN:
- switch( event.key.keysym.sym )
- {
- case SDLK_ESCAPE :
- done = true;
- break;
- case SDLK_BACKSPACE :
- std::cout << std::endl << "Destruction des points de contact." << std::endl << std::endl;
- limiteur.clear();
- break;
- case SDLK_SPACE :
- std::cout << std::endl << "Reinscription du cas initial." << std::endl << std::endl;
- for ( Uint32 i(0); i < h; i ++ )
- for ( Uint32 j(0); j < w; j ++ )
- {
- buffer[current_buffer][i][j] = 0.0f;
- };
- break;
- case SDLK_a :
- temp = 1.0f ;
- break;
- case SDLK_z :
- temp = 0.5f ;
- break;
- case SDLK_e :
- temp = 0.0f ;
- break;
- }
- break;
- case SDL_KEYUP:
- switch( event.key.keysym.sym )
- {
- case SDLK_LEFT :
- case SDLK_RIGHT :
- case SDLK_DOWN :
- break;
- }
- break;
- case SDL_MOUSEMOTION:
- mouse.x = event.motion.x ;
- mouse.y = event.motion.y ;
- if ( trigger )
- limiteur.push_back( { temp, mouse.y, mouse.x } );
- break;
- case SDL_MOUSEBUTTONDOWN:
- trigger = true ;
- break;
- case SDL_MOUSEBUTTONUP:
- trigger = false ;
- break;
- } // end switch event type
- } // end of message processing
- // [4.2] Calculs
- if ( !pause )
- {
- for ( unsigned int c(0); c < iteration ; c++ )
- {
- // Conditions initiales
- for ( unsigned int k(0); k < limiteur.size(); k++ )
- buffer[current_buffer][ limiteur[k].y ][ limiteur[k].x ] = limiteur[k].temp ;
- // Calcul
- for ( Uint32 i(1); i < h - 1; i ++ )
- for ( Uint32 j(1); j < w - 1; j ++ )
- {
- buffer[next_buffer][i][j] = lambda * buffer[current_buffer][i + 1][j]
- + lambda * buffer[current_buffer][i][j + 1]
- + lambda * buffer[current_buffer][i - 1][j]
- + lambda * buffer[current_buffer][i][j - 1]
- + (1.0f - 4.0f * lambda ) * buffer[current_buffer][i][j] ;
- if ( buffer[current_buffer][i][j] > 1.0f )
- buffer[current_buffer][i][j] = 1.0f ;
- else if ( buffer[current_buffer][i][j] < 0.0f )
- buffer[current_buffer][i][j] = 0.0f ;
- }
- // Changement de buffer
- current_buffer = next_buffer ;
- next_buffer = 1 - current_buffer ;
- }
- }
- // [4.3] Affichage
- if ( !pause )
- {
- // Calcul
- for ( Uint32 i(1); i < h - 1; i ++ )
- for ( Uint32 j(1); j < w - 1; j ++ )
- pixelRGBA( screen, j, i, (Uint8)( buffer[current_buffer][i][j] * 255 ), 0, 0, 255 );
- }
- SDL_Flip(screen);
- // [4.4] Temps
- total_frame ++;
- while( SDL_GetTicks() - tprev < twait )
- {
- if ( SDL_GetTicks() - tprev < twait/2 )
- SDL_Delay( twait/3 );
- }
- tprev = SDL_GetTicks();
- } //fin bcl principale
- ///[5] Destruction des composants
- SDL_FreeSurface( screen );
- ///[6] Affichage puissance de calcul
- std::cout << "Performances : " << std::endl;
- std::cout << "> Nombre de pixels : " << w*h << std::endl;
- std::cout << "> Nombre total d'images : " << total_frame << std::endl;
- std::cout << "> Temps total : " << SDL_GetTicks() << "ms." << std::endl;
- std::cout << "> Moyenne par frame : " << (float)SDL_GetTicks() / total_frame << std::endl;
- std::cout << "> Moyenne par frame et par pixel : " << (float)SDL_GetTicks() / total_frame / w / h << std::endl;
- ///[7] Tableau
- /*for ( Uint32 i(1); i < h - 1; i ++ )
- {
- for ( Uint32 j(1); j < w - 1; j ++ )
- {
- std::cout << (int)(buffer[next_buffer][i][j] * 255) << ":";
- }
- std::cout << std::endl;
- }*/
- return 0;
- }
|