GUI: Sposób na rysowanie
grudzień 1, 2007 — morituriusPodczas pisania obsługi eventów wpadła mi do głowy pewna myśl. Mianowicie, zastanowiłem się po co rysować w każdej klatce całe GUI skoro i tak rzadko kiedy coś się tam zmienia.
A może by tak zrenderować GUI do tekstury i wyświetlać tylko teksturę? Takie rozwiązanie znacznie zwiększyłoby wydajność rysowania takiego GUI. Nawet idąc na łatwiznę i odrysowując całe GUI gdy tylko jeden przycisk zmieni swój kolor bo myszka jest akurat nad nim zyskujemy całą masę przebiegów, w których jednak nic ciekawego się nie dzieje.
Pokombinuję z tym trochę i pochwalę się efektami bądź ich brakiem ^^
grudzień 1, 2007 @ 2:00 pm
Ciekawy pomysł. Ale ja bym buforował poszczególne ‘duże’ kontrolki - najlepiej okna. Poza tym gdyby jeszcze udało się wykryć, czy w danym zdarzeniu kontrolka faktycznie zmieniła swój wygląd, to rzeczywiście zysk na wydajności mógłby być spory. Być może do tego celu wystarczy sprawdzenie, czy zdarzenie w rodzaju Paint zostało obsłużone (ale to już zależy od szczegółów implementacji GUI).
Jeśli jednak chodzi o rysowanie, to zalecałbym wydzielenie do tego osobnego modułu - tak, aby kontrolki nie wydawał poleceń w stylu ‘narysuj prostokąt’, ale raczej ‘narysuj w(y)ciśnięty przycisk’, ‘narysuj obwódkę zaznacenia’, itd. Takie rozwiązanie zrobiłem u siebie, przejmując je w z Windows Forms, i sprawdza się całkiem nieźle. Dodatkowo tutaj mamy kolejne miejsce na optymalizacje, jako że ten obrazek przycisku również można cache’ować do tekstury.
grudzień 3, 2007 @ 12:31 pm
Też myślałem, żeby coś takiego sobie napisać. Ostatecznie zrezygnowałem, bo to jakby nie patrzeć tylko optymalizacja wydajności, a całkowicie zmienia koncepcję modułu GUI i jest bardzo trudna do napisania.
Aha, jak będziesz to miał to możesz łatwo zrobić wyginające się, gumowe okienka jak w XGL
grudzień 3, 2007 @ 1:46 pm
Fakt - przekonałem się, że nie jest to proste zadanie. Jak na razie chyba dam sobie z tym spokój. Może później coś z tym wytworzę. (prawdę mówiąc wątpię ^^)
grudzień 14, 2007 @ 8:03 pm
heh
ale mam gdzieś takie GUI napisałem z co prawda nudów ale działa świetnie, na zasadzie rysowania na OPENGL TEXTURE ale co do rysowania uzyłem tej samej techniki MS i borland czyli rysowanie komponentów w pamięci na obrazek
(coś jak canvas ) u mnie to sie nazywa Class’a TPen
Tekstura OPENGL = jeden widet bazowy czyli np OKIENKO jak w Windowsie, reszta jest przerysowywana zależnie od potrzeb. Biblioteki wymagane: libpng , zlib, opengl, freetype, libjpeg. jak chcesz dam screen i demko
wniosek program rysuje tylko 1 teksturę opengl
i podmienia na niej grafikę kiedy chcemy….
Pozdro Redzik (old sql developer)
grudzień 14, 2007 @ 8:17 pm
Redzik: thx, ale nie trzeba bo ja uzywam DirectX wiec nic by mi to nie pomoglo
grudzień 22, 2007 @ 4:58 pm
DX
tak po prawdzie to nie ma znaczenia czy uzywasz DX czy Gl czy tez libSDL, cały myk na tym polega, dam Ci screen’a : http://redzik.boo.pl/x/screen1a.png
a nie 100 elementów z których składa się gui jak widziałem w innych GUI, dodatkowo to jest zajebiście szybkie troszke ASM wsadziłem w kod
Jeśli nie klikam zednych elemętów na gui lub nie wymagają przerysowania to nie trace na to czasu i cennego procesora a co do karty graficznej jej zadaniem jest wyświetlenie jednej Textury
kontrolki które są juz napisane: Window, Listbox, Inputbox, TextArea (ni ma scroola V i H ), Label, Button, Slider, PageControl, CheckBox, ImageObiect, CpuMonitor… dalej mi sie nie chciało robić, na podstawie Genettychnych mozna tworzyć następne, stworzenie kontrolki/stylu to kwestia kilku minut …
Pozdro Redzik (old sql developer)
grudzień 22, 2007 @ 6:45 pm
Nie, no właśnie na tym cały mój pomysł polegał, żeby rysować GUI tylko wtedy kiedy coś się faktycznie zmieni.
Jedynym problemem jest konkretna implementacja więc kod z OpenGL niewiele by pomógł.
Zainteresowałeś mnie jednak tym: “na podstawie Genettychnych mozna tworzyć następne”.
Co miałeś na myśli? Chętnie bym ten kod obejrzał ^^
grudzień 22, 2007 @ 8:49 pm
Kodu związanego czysto OpenGL jest tyle:
//– kod ——–
int CTextureManager::BuildTex(int id, int gFilter, int inFilter,SDK_Surface * p )
{
if(id == (-1) ) id = GetNewTextureID (-1);
glBindTexture ( GL_TEXTURE_2D, id );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D ( GL_TEXTURE_2D, 0 ,
ale to nie ma związku z gui, co do genetycznych, chodzi o to ze podwędziłem sposób jaki zastosowali w delphi wszystkie komponenty posiadają cechy główne czyli: rysowanie , akcje klawiszowe, pozycje, aktywna kontrolka, martwa kontrolka… na podstwie tych cech mozna stworzyć uniwersalny obiekt kontrolki i metodami Virtual’nymi połączyć go z nowym komponentem… ogólnie chodzi o to ze mozna zrobić wszystkie kontrolki takie jakie ma winda (do piekła) czy Linux wszystko to kwestia fantazji
dodatkowo w np: TextArea mozna dodać nowe wewnętrzne kontrolki, czyli np: paski przewijania na podstawie kontrolek juz istniejących takich jak Slider (ale to by chyba było głupawym pomysłem)
gFilter ,
p->nPowWidth ,
p->nPowHeight,
0 ,
inFilter ,
GL_UNSIGNED_BYTE,
p->Data
);
return id;
}
//– kod ——–
Oczywiście funkcja przebudowania GL_TEXTURE tez jest przebudowywana tylko w razie potrzeby….
no i jeszcze wyświetlenie grafiki
mały załącznik do wypowiedzi :
Class’a główna Widget:
http://redzik.boo.pl/x/a1.txt
przykładowa kontrolka button: (kod całej kontrolki)
http://redzik.boo.pl/x/a2.txt
Wprawdzie zasada działania GUI i komponentów ( gadżetów ) to żadne odkrycie ale fajnie jest to samemu napisać. Jest jeszcze Główny “zbiornik” nazwałem go GUI_BASE, to tam przypisujemy przypisujemy wszystkie dane wejściowe on zarządza całym rysowaniem wszystkiego, rozdzielaniem Eventów (klawisze mysz) na poszczególne kontrolki i innymi takimi dziwactwami.
cały kod do napisania w naszej aplikacji to:
//— KOD —
GUI_Base * myGUI = new GUI_Base();
::..”,font);
SDK_Window * myWINDOW = new SDK_Window(0,0,450,580, false, true,”..:: łokienko
myWINDOW->setVisible(true);
SDK_PushButton * btn = new SDK_PushButton(300, 64,50,22,”text” ,font );
//btn->SetFunction( func_btn ); // Callback dla akcji
myWINDOW->addWidget( btn ); // dodajemy kontrolke do rodzica
myGUI ->WidgetsAddFirst( myWINDOW ); // dodajemy całe okienko do Głównego kontenera
// potem gdzieś w kodze (ale ne byle gdzie):
myGUI->Draw(); // rysowanie
myGUI->UpdateEvents(); // aktualizacja zdarzeń
//— KOD —
grudzień 22, 2007 @ 9:57 pm
“co do genetycznych, chodzi o to ze podwędziłem sposób jaki zastosowali w delphi”
zupełnie nie rozumiem co w tym sposobie “genetycznego” ?
ot zwykłe dziedziczenie i wykorzystanie polimorfizmu
grudzień 22, 2007 @ 10:30 pm
no nie do konca o to mi chodzi chodzi mi bardziej o to ee coś w stylu o przykład:
// ———————-
class myBUTTON : public SDK_PushButton
{
myBUTTON ()// konstruktor
{
SetMyDraw(true); // rysowanie w kontrolce standardowej jest ignorowane O TO CHODZI
};
// ———————-
Class myBUTTON jest nowa kontrolką na podstawie kontrolki GENETYCZNEJ (coś jak szablon, genetyczna czyli posiada cechy poprzednika ale nie wszystkie no i nowe oczywiście )… ni umiem tego inaczej wytłumaczyć
grudzień 23, 2007 @ 7:22 przed południem
Ale to się po chrześcijańsku nazywa właśnie dziedziczeniem, gdzie SDK_PushButton jest klasą bazową, a myBUTTON jest klasą pochodną.
Określenie którejś z klas jako genetycznej jest dość oryginalne choć w pewnym sensie nawet pasuje
grudzień 23, 2007 @ 10:11 przed południem
eee głównie chodzi mi o to :
//—–
SetMyDraw(true); // rysowanie w kontrolce standardowej jest ignorowane O TO CHODZI
//—–
nie o dziedziczenie (choć tam tez jest to jedna z podstaw działania) ale oki mniejsza…
grudzień 25, 2007 @ 8:35 pm
czyli nie rozumiem co w tym genetycznego ^^
ja jak chce zeby klasa pochodna rysowala po swojemu to po prostu nadpisuje metodę wirtualną render() i po sprawie