GUI: Sposób na rysowanie

Podczas 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 ^^

Reklamy

13 myśli nt. „GUI: Sposób na rysowanie

  1. 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.

  2. 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 🙂

  3. 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ę ^^)

  4. 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)

  5. 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
    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 🙂 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 🙂

    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)

  6. 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ł ^^

  7. 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 ,
    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 🙂 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)

    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();
    SDK_Window * myWINDOW = new SDK_Window(0,0,450,580, false, true,”..:: łokienko 😀 ::..”,font);
    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 —

  8. „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

  9. 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ć

  10. 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 😉

  11. 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… 🙂

  12. 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 😛

Skomentuj

Wprowadź swoje dane lub kliknij jedną z tych ikon, aby się zalogować:

Logo WordPress.com

Komentujesz korzystając z konta WordPress.com. Wyloguj / Zmień )

Zdjęcie z Twittera

Komentujesz korzystając z konta Twitter. Wyloguj / Zmień )

Facebook photo

Komentujesz korzystając z konta Facebook. Wyloguj / Zmień )

Google+ photo

Komentujesz korzystając z konta Google+. Wyloguj / Zmień )

Connecting to %s