Generování ohně - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:



C/C++

Generování ohně

27. února 2002, 00.00 | Máte rádi jednoduché prográmky, které generují líbivé grafické efekty? Já taky. Nedávno jsem si stáhl jeden, který generoval oheň a mně se zalíbil. Měl jednu vadu, byl strašně pomalý. Tento tutoriál vám ukáže jak vytvořit dva druhy ohně.

 

Máte rádi jednoduché prográmky, které generují líbivé grafické efekty? Já taky. Nedávno jsem si stáhl jeden, který generoval oheň a mně se zalíbil. Měl jednu vadu, byl strašně pomalý. Tento tutoriál vám ukáže jak vytvořit dva druhy ohně. Zdrojový kód si můžete stáhnout ZDE.

 

Nejdřív teorie, jak to vůbec funguje. Jedeme řádek po řádku a výsledná barva pixelu se spočítá jako průměr barev 3 sousedních pixelů o řádek níže + jednoho o dva níže. Mohlo by to vypadat asi takhle: pixel[x][y]=(pixel[x-1][y+1]+pixel[x][y+1]+pixel[x+1][y+1]+pixel[x][y+2]) /4. Na obrázku to je dobře vidět: P1=(P2+P3+P4+P5)/4.

 

 

Pokud ste již zkoušeli dělat něco s pixelama pomocí funkcí GetPixel(..) a SetPixel(..), tak ste zjistili, že to je neskutečně pomalé, proto jsem použil paletu a buffer ve kterém mám uloženy indexy barev. Tento buffer zkopíruji do surfacu a ten zobrazím.

 

Výsledný efekt závisí na použité paletě barev. Já použil přechod z černé přes červenou až do žluté, ale pokud si chcete vytvořit plamen modrý, tak není problém a paletu si vytvoříme podobnou, akurát s použitím modré barvy místo žluté a červené. Používám paletu uloženou jako bitmapu, protože se tak jednoduše načítá a dobře se upravuje pokud nejsme spokojeni s výsledkem.

 

Dvě důležité proměnné jsou: WORD Paleta[256] - sem se uloží pod index jednotlivé barvy

                                           WORD buffer[vyska+1][sirka+1] - použijeme ho pro výpočty

 

Vytvoření palety:

void CreatePalette()//vytvori paletu pomoci bitmapy
{
  DDSURFACEDESC   ddsd;
  ddsd.dwSize = sizeof( ddsd );
  WORD color;

  Palette->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL);
    //lockneme surface pro praci
  WORD *pixels = (WORD *)ddsd.lpSurface;
    //ukazatel na surface v pameti	
	
  for(int p=0;p<256;p++)
   //ber pixel po pixelu a podle toho jaka je barva,
   //tak vytvor paletu
   {		
    color = pixels[p];
    Paleta[p]=color;
   }	
	
   Palette->Unlock(NULL);//uvolni surface
   Palette->Release();
    //surface uz nebudeme potrebovat, tak po sobe uklidime
}

 

Nejprve si na poslední dva řádky dáme náhodně pixlíky, které nám poslouží jako palivo pro ohýnek. Po vypočtení indexů barev v surfacu zkopírujeme buffer do surfacu.

 

Výpočet dalšího framu:

void ComputeBuffer()//vypocitej dalsi frame
{
  WORD pomoc;
  int x,y;
  for(int xx=0;xx<sirka;xx++)
   //nejprve si nahodne dole vygenerujeme pixliky, 
   //aby se nam ohen trochu menil(palivo:))
    {
     x=rand()%2;
     y=rand()%2;
     if(x==1)
       buffer[vyska][xx]=255;
      else
       buffer[vyska][xx]=0;

     if(y==1)
       buffer[vyska-1][xx]=255;
      else
       buffer[vyska-1][xx]=0;
    }	

    if(typohne)//podle tybu ohne zapisujeme do bufferu..
     {
     for(int yy=400;yy<vyska-1;yy++)
      //zhora - plameny plapolaji 
      {
       for(int xx=10;xx<sirka-10;xx++)
        {	
         pomoc=buffer[yy+1][xx-1]+buffer[yy+1][xx]+
                buffer[yy+1][xx+1]+buffer[yy+2][xx];
         buffer[yy][xx]=pomoc>>2;
         if(buffer[yy][xx]>1)
          //zde snížim hodnotu, aby plamen nebyl prilis dlouhy
            buffer[yy][xx]-=2;
...

 

Počítání indexů a kopírování do surfacu provádíme ve smyčce a na obrazovce nám hoří krásný ohýnek.


Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: