Hlavní navigace

OpenGL a Direct3D II

Knihovny jako OpenGL nebo DirectX nejsou pro uživatele až tak důležité, pro ně jsou to jenom dvě prázdná jména. Může jim být naprosto jedno, jak program uvnitř funguje. Návrh a hlavně celková použitelnost API je důležitá primárně pro programátory. Právě oni s ním pracují, nikdo jiný. V tomto dílu budeme porovnávat především délku kódu, který se musí napsat, aby program něco udělal.

Tweetni to Odměnte autora  Jak to funguje?

Programátorské hledisko

Na rozdíl od strukturovaného OpenGL je Direct3D objektově orientované. Jaký je mezi tím rozdíl? V případě OpenGL se na začátku programu vytvoří okno s jeho podporou a pak je možné odkudkoli volat jakékoli OpenGL specifické funkce. V případě Direct3D se musí vytvořit objekt Direct3D (IDirect3D9), s jeho pomocí zařízení Direct3D (IDirect3DDevice9) a přes volání jejich metod programátor pracuje. Objektově orientované programování sice preferuji také, ale v případě DirectX mi připadá hodně těžkopádné – alespoň v porovnání s OpenGL.

Jedním z nejdůležitějších charakteristik jakéhokoli API je pro programátora délka zdrojového kódu, který musí napsat, aby program něco udělal. John Carmack, autor her Quake, uvádí [3], že kód programu plnící stejnou funkci je v Direct3D i čtyřikrát delší než v OpenGL. Můžeme si to bez problémů ověřit. Z učebnice Direct3D [1], str. 180, 181 uvedu jednoduchou renderovací funkci, která na černém pozadí vykresluje jeden obarvený trojúhelník – bez textur, světel či jakýchkoli maticových operací (translace, rotace). Následně vše přepíši do OpenGL.

///////////////////////////////////////////
// Direct3D 9.0
///////////////////////////////////////////

struct VLASTNIVERTEX
{
  FLOAT x, y, z, rhw;
  DWORD barva;
}

void Vykresleni()
{
  VLASTNIVERTEX vrchTrojuhl[] =
  {
    {400.0, 180.0, 0.0, 1.0, D3DCOLOR_XRGB(255,0,0)},
    {500.0, 380.0, 0.0, 1.0, D3DCOLOR_XRGB(0,255,0)},
    {300.0, 380.0, 0.0, 1.0, D3DCOLOR_XRGB(0,0,255)},
  };

  IDirect3DVertexBuffer9* pVertexBuffer = NULL;
  HRESULT hVysledek = g_pZarizeniDirect3D->CreateVertexBuffer(
    3*sizeof(VLASTNIVERTEX), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE,
    D3DPOOL_DEFAULT, &pVertexBuffer, NULL);

  if (FAILED(hVysledek))
  {
    DXTRACE_ERR("Chyba při vytv. vertex bufferu.", hVysledek);
  }

  VOID* pVrcholy;
  hVysledek = pVertexBuffer->Lock(0, 0, (viod**)&pVrcholy, 0);
  if (FAILED(hVysledek))
  {
    DXTRACE_ERR("Chyba při zamyk. vertex bufferu.", hVysledek);
  }
  memcpy(pVrcholy, vrchTrojuhl, sizeof(vrchTrojuhl));
  pVertexBuffer->Unlock();

  g_pZarizeniDirect3D->Clear(0, NULL, D3DCLEAR_TARGET,
    D3DCOLOR_XRGB(0,0,0), 1.0, 0);
  g_pZarizeniDirect3D->SetStreamSource(0, pVertexBuffer, 0,
    sizeof(VLASTNI_VERTEX));
  g_pZarizeniDirect3D->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
  g_pZarizeniDirect3D->BeginScene();
  g_pZarizeniDirect3D->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
  g_pZarizeniDirect3D->EndScene();

  g_pZarizeniDirect3D->Present(NULL, NULL, NULL, NULL);

  if (pVertexbuffer)
    pVertexBuffer->Release();
} 

To samé v OpenGL…

///////////////////////////////////////////
// OpenGL
///////////////////////////////////////////

void Vykresleni()
{
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glLoadIdentity();

  glBegin(GL_TRIANGLES);
    glColor3ub(255,0,0); glVertex2i(400,480);
    glColor3ub(0,255,0); glVertex2i(500,380);
    glColor3ub(0,0,255); glVertex2i(300,380);
  glEnd();

  glFlush();
  SDL_GL_SwapBuffers();
} 

Pozn.: Při inicializaci se nesmí definovat perspektiva, ale pravoúhlá projekce (glOrtho()) o rozměrech 800×600. Funkce glClearColor() se obvykle dává také do inicializace, ve vykreslení je jen kvůli tomu, aby kód plně odpovídal Direct3D. Pokud provozujete OpenGL ve Win32 API, určitě používáte místo SDL_GL_SwapBuf­fers() funkci SwapBuffers(), SDL má tu výhodu, že lze kód bez větších problémů přenášet mezi Linuxem, Windows a dalšími operačními systémy.

RGB trojúhelník
Screenshot OpenGL verze programu

Vrátím se ještě k té délce kódu – v případě, že byste je chtěli porovnat číselně, pak D3D verze měla celkem 47 řádků, 108 slov a 1367 písmen, OpenGL pouze 14 řádků, 22 slov a 335 písmen. V poměru to činí u řádků 47 / 14 = 3.35, slov 108 / 22 = 4.9 a znaků 1367 / 335 = 4.08 …čtyřnásobná délka kódu tedy plus mínus platí. Zčásti je to i tím, že v D3D sekci byly použity dlouhé identifikátory, ale za to já nemůžu, jak jsem napsal výše, jedná se o doslovný přepis z učebnice D3D. Dokonce jsem identifikátor vrcholyTrojuhelniku musel zkrátit pouze na vrchTrojuhl, aby se kód vešel na řádek.

[woq@localhost tmp]$ wc *txt
  47  108 1367 dx.txt
  14   22  335 gl.txt

Uživatele programu zdrojové kódy absolutně nezajímají a hlavně jim nerozumí, takže nepředpokládám, že jste předchozí výpisy zkoumali podrobně. Jenom tak jimi v rychlosti prolétněte a zkuste říci, který z nich je přehlednější. Dále si všimněte v D3D sekci kódu řádku if(FAILED(hVys­ledek)), který se provede při chybě ve vytváření/zamykání vertex bufferu. V OpenGL se toto dělat nemusí/nelze, a to ani při použití vertex arrays, které více odpovídají D3D stylu programování.

Nic podobného, jako je samostatné volání funkcí glVertex*(), Direct3D neumí. Vertex arrays jsou sice výhodnější při renderování velkých množství souvisejících vertexů, které jsou vždy na konstantní pozici (3D světy, výškové mapy, 3D modely ap.), protože odpadají ztráty na výkonu při mnoha volání funkcí, nicméně u pohyblivých nesouvisejících trojúhelníků, kde často ani nebývá dopředu znám jejich počet (typicky částicové systémy), bývá použití vertex arrays těžkopádné a spíše méně vhodné, navíc se zbytečně alokuje systémová paměť. V OpenGL si může programátor zvolit, co považuje za výhodnější. Pokud je chytrý a používá extensiony, může všechna data dokonce uložit v paměti grafické karty jako tzv. VBO, tím se eliminuje vliv „délky drátů“ při posílání dat na grafickou kartu. To ale pravděpodobně jde i v D3D.

Literatura

Michal Turek

Autor studuje první ročník FEL ČVUT Praha, baví ho vše kolem počítačů, zvláště programování v jazycích PHP a C/C++ včetně počítačové grafiky pod knihovnou OpenGL.

Ohodnoťte jako ve škole:
Průměrná známka 3,00
Tweetni to Odměnte autora  Jak to funguje?

Školení: Obsahová strategie a content marketing

DW - Školeny webcopywritingu
  • Proč je obsahový marketing výrazným trendem
  • Jak navrhnout užitečnou obsahovou strategii
  • Jaký obsah využít a které nástroje vám pomohou
  • Jak zlepšit workflow a výsledky copywritingu

Detailní informace o školení content strategy »

       

Přehled názorů

Porovnávání délky kódu
Martin Čížek 11. 8. 2004 02:51
Nový
o co tu jde?
jezeq 11. 8. 2004 05:48
Nový
OpenGL a kontrola chyb
Pavel Tisnovsky 11. 8. 2004 08:56
Nový
└ 
Re: OpenGL a kontrola chyb
deda.jabko 11. 8. 2004 10:21
Nový
 
└ 
Re: OpenGL a kontrola chyb
Pavel Tisnovsky 11. 8. 2004 13:07
Nový
Objektovy DX?
Petr 11. 8. 2004 10:02
Nový
├ 
Re: Objektovy DX?
hkmaly 11. 8. 2004 15:38
Nový
└ 
Re: Objektovy DX?
Pavel 11. 8. 2004 22:11
Nový
dx vs opengl
petr 11. 8. 2004 12:04
Nový
├ 
Re: dx vs opengl
tomm 11. 8. 2004 12:17
Nový
├ 
Re: dx vs opengl
Ladislav Thon 11. 8. 2004 12:19
Nový
│
└ 
Re: dx vs opengl
mikeson 11. 8. 2004 13:12
Nový
│
 
└ 
Re: dx vs opengl
Ladislav Thon 11. 8. 2004 13:26
Nový
│
 
 
└ 
Re: dx vs opengl
jarda 11. 8. 2004 16:42
Nový
└ 
Re: dx vs opengl
Diagon Swarm 12. 8. 2004 20:13
Nový
moc mi neni jasny smysl clanku....
<head> 11. 8. 2004 13:50
Nový
└ 
Re: moc mi neni jasny smysl clanku....
KKING 11. 8. 2004 14:03
Nový
STOP!
Mormegil 11. 8. 2004 14:45
Nový
└ 
Re: STOP!
lubos 24. 8. 2004 17:11
Nový
 
└ 
Re: STOP!
Mormegil 2. 9. 2004 10:44
Nový
to je tak lacine :)))
jarda 11. 8. 2004 15:35
Nový
└ 
Re: to je tak lacine :)))
Jirka bianco Vagner 12. 8. 2004 12:28
Nový
bez titulku
Skogen 11. 8. 2004 19:35
Nový
Minimální zdroják zobrazující vertex buffer
Jmeno 11. 8. 2004 22:32
Nový
└ 
Re: Minimální zdroják zobrazující vertex buffer
Mormegil 12. 8. 2004 13:31
Nový
Tak to dopadá....
Jmeno 11. 8. 2004 22:40
Nový
Ještě srovnání DX v IDE
Kania 18. 8. 2004 04:13
Nový
└ 
Re: Ještě srovnání DX v IDE
limuhob 20. 8. 2004 11:35
Nový
       

Tento text je již více než dva měsíce starý. Chcete-li na něj reagovat v diskusi, pravděpodobně vám již nikdo neodpoví. Pro řešení aktuálních problémů doporučujeme využít naše diskusní fórum.

Zasílat nově přidané příspěvky e-mailem