C++ & C# Programming page
 

 

# Úvod
# Tvůrci
# C++
# C#
# Linky





Mini-seriál o grafice - 1. díl

Jak mi jeden ze čtenářů řekl, chtěl by nějaké články o grafice v C++. V tomto díle pojednám o grafice trochu teoreticky a přidám jeden zdrojový kód, ve kterém se budou vykreslovat čáry. No a aby to nebyly jen tak čáry, vykreslíme si pěknou sinusoidu :-)

 

Trochu málo o grafice

Grafika sama o sobě je neodmyslitelná součást aplikací. Ať už jde o nadupaný grafický editor nebo instalátor, kde se na pozadí vykreslí obrázek. Ale to asi víte, když tento text čtete :)
Pojem GRAFIKA v programování může mít více významů.
a ) GDI (nebo i GDI+) - 2D grafika, používaná na jednoduché vykreslování do okna
b ) OpenGL - oblíbený 3D grafický ovladač, zdarma použivatelný. Jedna z hlavních výhod je velký počet tutoriálů a návodů na internetu
c ) DirectX - podobný 3D grafický ovladač jako OpenGL, tentokrát od Micro$oftů. Avšak narozdíl od OpenGL je podporovanější, (snad zastánce OpenGL neurazím)  podle mého názoru má lepší vybavení, poměrně jistou budoucnost a podobně. Do DirectX patří:
        DirectPlay - síťová TCP podpora, kterou není těžké používat
        DirectDraw - vykreslování 2D grafiky do okna, ne tak jednoduché jako u GDI, zato rychlejší
        DirectShow - přehrávání/nahrávání videa atd
        DirectSound - jednoduchý engine na přehrávání 3D zvuku
        DirectMusic - složitější přehrávání zvuku a hudby
        DirectInput - rychlý přístup na herní zařízení jako jsou joysticky
        Direct3D - a konečně samotný 3D engine, s každou verzí lepší a lepší :)

Volba grafického ovladače je důležítá, tak jako spousta dalšího v programování. Ttak jako nemůžete jít s granátem na blechy, nedá se používat GDI na pořádnou 3D grafiku :)
Stejně tak by bylo mrhání výkonu procesoru na primitivní jednorázové vykreslení mrňavého obrázku hned používat 3D grafiku.
Při vykreslování v GDI stačí vytvořit kontext zařízení, do něj neco vykreslit, kontext uzavřít a grafika je hotova. Jedna ze zajímavých možností je vykreslovat přímo do okna programu, neboli neklientské oblasti. To znamená lišta, postranní ohraničení okna a podobně. Při práci s GDI se však často člověk setká s problémem překreslování. Zaprvé je třeba donutit systém k překreslení aplikace po nějakém intervalu, nejčastěji při WM_TIMER zprávě. Není možná takový problém obnovit okno, jako zamezit nežádoucímu problikávání a podobně, ale o tom až později.
O DirectX jsem se zmíníl jen okrajově. Sice jsem s ním pracoval, ale není to tak jednoduché na vysvětlení. Možná v jiném seriálu za delší dobu.
Ještě poznámka na závěr: při programování v GDI se často stává i těm nejlepším expertům, že dojde k takzvanému memory-leakingu, neboli úniku paměti. Program totiž stále dokola vytváří prostředky, jenže je nemaže a tak se hltí paměť. Vyústí to buď v pád aplikace, zamrznutí počítače nebo porušení funkčnosti programu.

 

Ukázková aplikace

Pro jednoduchou ukázku GDI grafiky, jsem si vybral vykreslení čar. A jak jsem napsal na začátku, samotné čáry jsou přece jen nuda, tak jsem je zakomponoval do složité sinusoidy.

void DrawLine(HDC hdc, int X1, int Y1, int X2, int Y2)
{
MoveToEx(hdc, X1, Y1, NULL);
LineTo(hdc, X2, Y2);
}

Deklarace vlastní GDI vykreslovací funkce. Ulehčuje nutnost použití MoveToEx a LineTo do jedné funkce.
Předpokládám, že smysl funkcí neznáte: MoveToEx je rozšíření staré funkce MoveTo (uvidíte to dost často, např u CreateWindowEx). Je to "moderní" vymoženost 32-bit systémů windows. Tato funkce se objevila ve win 3.1
Její účel je nastavit "aktuální" bod na nějakou pozici. Jelikož funkce LineTo se ptá jen na 2 čísla, lépe řečeno 1 bod, neví, odkud má být čárá vedena. Ví jen kam. Startovní pozici získává z onoho MoveToEx. A protože je to celkově podivné a zmatené, raději jsem si vytvořil funkci DrawLine :-)

void OnPaint(HDC hdc)
{
   HPEN pero = CreatePen(0, 2, 0x0000FF00);  // ZELENA
   SelectObject(hdc, pero); 
   float y = 0; 
   int yOLD = 0; 
   int xOLD = 10; 
   bool Dolu = false;
    for(float x=10; x<950; x+=1) 
   { 
      if(Dolu) 
      { 
         y+= 0.001f; 
         if(y >= 1.0f) 
         { 
            Dolu = false; 
         } 
      } else { 
         y-= 0.001f; 
         if(y <= -1.0f)
         { 
            Dolu = true;
          } 
      } 
   DrawLine(hdc, xOLD, yOLD, x, 210 + sin(x / 60)*200); 
   xOLD = x; 
   yOLD = 210 + sin(x)*200; // VYBARVENI 
   //yOLD = 210 + sin(x/60)*200; // CARA
  }
}

Tato funkce je volaná při každém překreslení. Umístil jsem ji do reakce na WM_PAINT zprávu. Na začátku se vytvoří pero, nastaví se mu zelená barva a poté se vybere.
Následující smyčka FOR obsahuje opakující se postup, vykreslující sinusoidu. K němu není moc co říct, snad je vše jasné. Jen v poslední části mám zapoznámkovaný jeden příkaz. Pokud ho povolíte a naopak zapoznámkujete předešlý, který se mu silně podobá, z krásné vybarvené sinusoidy se stane křivka. Není to sice pěkné jako vybarvená, ale je praktičtější :)

Dál je zdrojový kód složen jen ze základních částí, které generuje Visual Studio 2003 .NET
A co se týká dalších dílů, předpokládám, že budu používat stejný projekt jako tento, jen zapoznámkuji staré vykreslování a přidám nové, tudíž bude vše pěkně pohromadě. Ale na to je ještě času dost.

Zdrojové kódy: [ TADY ]



Správce sekce: Dejvino



14.2 2005

C++: pridano par odkazu na clanky o OpenGL, IRC, POP3 a BMP
14.8 2004

C++: přidán klient pro Internet Relay Chat (IRC)
11.7 2004

C++: opravil jsem zdrojak WebServeru, byla tam navic jedna funkce kterou jsem nepridal a mnoho zacatecniku by si s tim nemuselo vedet rady...
27.6 2004

Vytvořen IRC kanál #c-prog na serveru Quakenet
10.6 2004

C++: přidán program WebServer, stojí za prohlédnutí!
5.6 2004

C++: přidán článek o CheckBoxu
29.5 2004

C++: přidán program WinSock Mail
28.5 2004

C#: přidán program DNStoIP
Vaše IP je 54.80.236.48
Stránka byla načtena za 0.01529 sekund.