W naszych grach próbujemy zwiększyć wydajność poprzez używanie mniej dokładnych modeli, tekstur, generowanie mipmap a także poprzez stosowanie przeróżnych algorytmów, które odrzucą nam trójkąty lub całe modele, które są niewidoczne lub też zasłonięte.
Jednak są momenty w których już nie da się bardziej pójść na kompromis między złożonością modeli a wydajnością i szukamy innych alternatywnych rozwiązań, które będą dla nas proste szybkie i zadawalające a także proste w implementacji.
Jednym z takich wyjść może okazać się zastosowanie pewnego rozszerzenia OpenGL-a o nazwie: ARB_point_sprite. Do czego może się ono nam przydać i co nam daje ? Otóż głównie może być nam ono pomocne przy wszelkiego rodzaju systemach cząsteczkowych generujących przeróżne efekty takie jak: dym, ogień, kurz itp. Gdy programujemy manadżer cząstek zwykle używamy quad-ów pokrytych teksturą. Przy takich modułach jak menadżery cząstek gdy wyświetlana ilość obiektów liczona jest w dziesiątkach, setkach czy nawet tysiącach warto jest postarać się o maksymalną wydajność zamieniając cząstki ze zwykłych quadów na pojedyńcze punkty, które będziemy w stanie także pokryć teksturą i zmienić ich rozmiar. Dzięki takiemu zabiegowi odrzucimy trochę geometrii a także zaoszczędzimy na obliczeniach ponieważ nie będziemy musieli obliczać przeróżnych rzeczy dla 4 wierzchołków każdej cząstki a wystarczy, że policzymy 1 punkt. Dodatkowymi plusami takiego rozwiązania jest to, że przy obliczeniach cząstek używając quad-ów musimy dodatkowo użyc metody billboardingu by sprawić, że będą one zawsze skierowane do kamery „twarzą”. Używając tego rozszerzenia takiego problemu już nie mamy xD
Przejdźmy może teraz do kodu, który będzie bardzo prosty. Na początek wrzućmy sobie parę stałych:
1 2 |
GL_POINT_SPRITE_ARB = $8861; GL_COORD_REPLACE_ARB = $8862; |
Jako, że rozszerzenie zostało zatwierdzone w 2003 roku jeszcze dobrą techniką będzie sprawdzenie czy nasza karta aby na pewno wspiera je dlatego zróbmy sobie funkcję, która będzie nam sprawdzać rozszerzenie i zwracać True/False w zależności czy jest obsługiwane.
1 2 3 4 5 6 7 8 9 10 |
Function SearchExt(extName : String) : Boolean; var ext : PChar; begin ext := PAnsiChar(glGetString(GL_EXTENSIONS)); if Pos(extName, ext) > 0 then result := True else result := False; end; |
a następnie gdzieś w kodzie wywołajmy ją następująco:
1 2 3 4 |
if SearchExt('ARB_point_sprite') = False then begin // Tu kod, który spowoduje wyjście lub coś innego. end; |
Teraz właściwy kod. Na początek aby móc używać rozszerzenia musimy wywołać:
1 |
glEnable(GL_POINT_SPRITE_ARB); |
analogicznie wyłączamy poprzez:
1 |
glDisable(GL_POINT_SPRITE_ARB); |
a następnie przed renderowaniem punktów wywołajmy:
1 2 |
glBindTexture(GL_TEXTURE_2D, obiekt_tekstury); glTexEnvf(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE); |
Pozwoli nam to na zbindowanie odpowiedniej tekstury i ustawienie jej. Dodatkowo może nam się przydać możliwość ustawienia rozmiaru cząstki robimy to znanym:
1 |
glPointSize(rozmiar); |
Teraz gdy wywołamy rysowanie pojedynczych punktów np. poprzez zwykłe:
1 2 3 |
glBegin(GL_POINTS); glVertex3f(0,0,0); glEnd(); |
Otrzymamy punkt, który będzie wyglądać niczym oteksturowany quad.
To chyba tyle, dokładne informacje można znaleźć na stronie: http://opengl.org/registry/specs/ARB/point_sprite.txt
Autor: 5corpio