Warsztat.GD

Produkcja gier => Design => Wątek zaczęty przez: Adam B w Czerwiec 21, 2009, 15:37:44

Tytuł: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 15:37:44
Czytając forum postanowiłem napisać własne GUI, w celu napisania aplikacji okienkowej - zagadnienie dla mnie nowe bo nigdy w większym stopniu nie miałem do czynienia z okienkami od strony programowania.
Z założenie ma być to proste GUI:

 - okna
 - przyciski
 - rozwijane menu

Programując chce się wzorować na swingu znanego z javy.

Do projektu postanowiłem zaprzęgnąć OpenGL +glut. Zastanawiam się jednak czy jeżeli ma być to proste GUI i na pewno nie będzie w przyszłości służyć do robienia czegokolwiek w 3d nie prościej będzie skorzystać z allegro? Prosił bym ludzi którzy mieli z tym jakieś doświadczenie o opinie.

Pozdrawiam serdecznie.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Kos w Czerwiec 21, 2009, 15:58:50
Do projektu postanowiłem zaprzęgnąć OpenGL +glut.
A co takiego ma GLUT, co mogłoby być potrzebne w GUI? :)


Najsensowniej chyba będzie, jeśli zrobisz to GUI niezależne od wyświetlania, a osobno zrobisz moduł rysujący je na np. OpenGL. Jeśli któregoś dnia zapragniesz odpalić je pod allegro, to dorobisz drugi moduł wyświetlania i już. Rozważ taką opcję.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 16:15:35
Do projektu postanowiłem zaprzęgnąć OpenGL +glut.
A co takiego ma GLUT, co mogłoby być potrzebne w GUI? :)


Najsensowniej chyba będzie, jeśli zrobisz to GUI niezależne od wyświetlania, a osobno zrobisz moduł rysujący je na np. OpenGL. Jeśli któregoś dnia zapragniesz odpalić je pod allegro, to dorobisz drugi moduł wyświetlania i już. Rozważ taką opcję.

5 linii kodu i już jest okno po którym można malować w OpenGL - tylko tyle :)

Mi bardziej się właśnie rozchodzi w pytaniu o samą funkcję "show" albo "draw" i ogolnie czy są jakieś przeciwskazania napisania ich w allegro ?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: taki_tam w Czerwiec 21, 2009, 16:39:29
Cytuj
czy są jakieś przeciwskazania napisania ich w allegro ?

No ale przecież, Allegro to tylko render, który nie powinien mieć nic wspólnego z całym systemem GUI.
Innymi słowy, ja przeciwwskazań nie widzę.

Pozdro! ;)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: bs.mechanik w Czerwiec 21, 2009, 16:50:57
Ogolnie sprawa wyglada tak, ze oddzielasz renderowanie od systemu GUI. Renderowanie mozesz podlaczyc np. dziedziczac po interfejsach. Mozesz napisac potem kilka rendererow, zeby user mogl szybko podlaczyc GUI do swojego app.
Tyle.

:)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 21, 2009, 17:13:15
Nie rob tego co ci kolega Kos tutaj radzi. Tylko zmarnujesz czas.

Bedziesz musial cos tam obsluzyc to i przepiszesz.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Kos w Czerwiec 21, 2009, 17:35:49
Nie zgadzam się. Nawet, jeśli żadny inny system wyświetlania nie miałby powstać, to warto wg mnie sobie wyrabiać dobre nawyki i uczyć się oddzielać logikę od widoku. Poza tym kod będzie wtedy łatwiejszy do zarządzania i rozbudowy.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 17:47:45
Nie zgadzam się. Nawet, jeśli żadny inny system wyświetlania nie miałby powstać, to warto wg mnie sobie wyrabiać dobre nawyki i uczyć się oddzielać logikę od widoku. Poza tym kod będzie wtedy łatwiejszy do zarządzania i rozbudowy.

Też tak myślę.

bs.mechanik sugerujesz stworzenie kilkudziesięciu różnych klas do wyświetlania ? Bo chyba nie zrozumiałem Twojej idei
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 21, 2009, 17:50:07
Jezeli nie bedzie nigdy obslugi innego api graficznego to bedzie to tylko kolejna niepotrzebna warstwa abstrakcji.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: bs.mechanik w Czerwiec 21, 2009, 17:53:30
Sugeruję stworzenie interfejsu dzieki któremu będziesz mógł komunikować się z warstwą renderującą, a potem jego implementację, by bibliotekę można było szybko wprowadzić do własnego projektu (oddzielnie dla DX, ogl, DXm itp). Interfejs po to, by user mial jednak możliwośc dopisania własnego renderera. 
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 18:16:39
Sugeruję stworzenie interfejsu dzieki któremu będziesz mógł komunikować się z warstwą renderującą, a potem jego implementację, by bibliotekę można było szybko wprowadzić do własnego projektu (oddzielnie dla DX, ogl, DXm itp). Interfejs po to, by user mial jednak możliwośc dopisania własnego renderera. 

Ja mam to tak rozplanowane:

////////////////////////KLASA GUI
class gui_button{
  public: 
    gui_button(string lname, int lx, int ly, int lwidth, int lheight);
     
  public:
    string name;
    int x;
    int y;
    int width;
    int height;
};

//////////////////////////////KLASA RYSUJACA

class visual{
  public:
void button(gui_button * b){    
       rectfill(screen, b->x, b->y, b->width, b->height, makecol(128,30,30)); 
     }

//////////////////////////////W PROGRAMIE

visual rysuj;
...
rysuj.button(wsk);


o coś takiego chodzi?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: bs.mechanik w Czerwiec 21, 2009, 18:29:05
Masz interfejs, załóżmy IRenderer. Jak wiadomo, ma on same metody czysto wirtualne. Masz klasę odpowiedzialną za logikę gui - CGUI. Dodajesz do swojego GUI nowe przyciski (CButtons), ikonki (CIcon) itp (pGui->addObject(pButton)). Na końcu przekazujesz do klasy renderującej (wydziedziczonej po IRenderer) obiekt klasy CGUI, który zawiera wszystkie informacje o położeniu przycisków, ich stanie itp. Renderujesz  (pOpenGLGuiRenderer->render(pGui) lub pDXRenderer->render(pGui)).

Ja sobie wyobrażam to tak. Nie pisałem jeszcze wlasnego GUI, więc możliwe, że projekt jest zły :)

Wadą tego są wszędobylskie funkcje wirtualne i dziedziczenie, jednak na dobrą sprawę, nie jest to duży narzut.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: rm-f w Czerwiec 21, 2009, 19:25:57
KISS.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: yarpen w Czerwiec 21, 2009, 19:46:31
Zainteresuj sie konceptem Immediate Mode GUI. Nie cieszy sie moze zbyt wielka popularnoscia, bo ma za malo klas, dziedziczenia i f-kcji wirtualnych, za to swietnie sprawdza sie w praktyce (o ile nie piszesz Worda).
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 21, 2009, 20:01:13
Cytuj
Jezeli nie bedzie nigdy obslugi innego api graficznego to bedzie to tylko kolejna niepotrzebna warstwa abstrakcji.
Są przynajmniej dwa powody, by dodać tą warstwę:
1. Można w niej umieścić rzeczy specyficzne dla danego API (np. w przypadku OpenGL i DirectX zrobić batching prymitywów - bez wplanowanego batchingu nie ma co nawet zaczynać robić GUI).
2. GUI ma być pod OpenGL, więc warto zabezpieczyć się na przyszłość, jak już przyjdzie do przesiadki na Direct3D.

Cytuj
Zainteresuj sie konceptem Immediate Mode GUI. Nie cieszy sie moze zbyt wielka popularnoscia, bo ma za malo klas, dziedziczenia i f-kcji wirtualnych, za to swietnie sprawdza sie w praktyce (o ile nie piszesz Worda).
Brzmi jak podejście, do którego sam doszedłem pisząc swoje GUI - jeśli tak, to naprawdę gorąco polecam.
- Zalety: proste w obsłudze i mało kodu do napisania.
- Wady: mało kodu do napisania (ktoś może czuć się głupio pisząc wypasione GUI na trzech klasach bez żadnego dziedziczenia).

W mojej implementacji wadą była jeszcze konieczność odświeżania GUI co klatkę, ale przy GUI akcelerowanych sprzętowo nie jest to aż tak wielkim problemem. :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Kos w Czerwiec 21, 2009, 20:12:59
A tak z ciekawości, to jak się w praktyce rozwiązuje tworzenie bardziej złożonych layoutów przy takim paradygmacie?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 21:35:34
Nie czytałem jeszcze o: Immediate Mode GUI, ale moje GUI ma składać się z 3 klas głównych a właściwie z 2 klas bo jedna klasa to będzie abstrakcyjna tylko do dziedziczenia. Wszystko ma się opierać na klasie Window i Button.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 21, 2009, 22:11:47
Cytuj
Jezeli nie bedzie nigdy obslugi innego api graficznego to bedzie to tylko kolejna niepotrzebna warstwa abstrakcji.
Są przynajmniej dwa powody, by dodać tą warstwę:
1. Można w niej umieścić rzeczy specyficzne dla danego API (np. w przypadku OpenGL i DirectX zrobić batching prymitywów - bez wplanowanego batchingu nie ma co nawet zaczynać robić GUI).
2. GUI ma być pod OpenGL, więc warto zabezpieczyć się na przyszłość, jak już przyjdzie do przesiadki na Direct3D.
Ad. 1. Majac klase pt. Graphics ktora z zalozenia jest tylko  klasa utility ("uzytecznosc") ktora obudowuje odwolania do ogl-a juz samoistnie stworzylismy "interfejs" do API. Poniewaz miksowanie rendererow jeszcze nikomu na dobre nie wyszlo, obsluge innego API (niz te na ktorym zaczelismy ) mozemy zalatwic poprzez #define-y (w jednym z silnikow na forum, renderery ladnie byly schowane w .dll-ach). Probowalem rzeczonego podejscia IRenderer na sile... okazalo sie to tylko niepotrzebnie napisanym kodem(czyli smietnikiem) i z racji calej serii wyjatkow (ciezko uogolnic interfejs bez wielkich kompromisow) musialem go przepisywac, poprawiac kilkakrotnie. Nie ma po prostu co sie palic do tego... jezeli zrobic to dobrze to jest tam sporo nadprogramowej roboty (np. wypadaloby przetestowac wszystkie dostepne API w danej dziedzinie pod kompatybinosc z naszym interfejsem w calym zakresie).

Ad. 2. "Jak"? Chyba jezeli. I dlaczego przesiadki? Chyba rozbudowy silnika o obsluge d3d.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 21, 2009, 22:34:00
A tak z ciekawości, to jak się w praktyce rozwiązuje tworzenie bardziej złożonych layoutów przy takim paradygmacie?
Na ile "bardziej"? W moim wykonaniu cały obszar podzielony jest na okna (patrz: Blender), a każde okno ma jakąś funkcję rysującą. Do tego jest sporo funkcji pomocniczych rysujących i zajmujących się obsługą przycisków, editboxów, comboboxów, treeview i podobnych. Z layoutem nie ma problemu, bo najczęściej i tak wykorzystuję property gridy (po lewej tree view, po prawej kontrolki w układzie liniowym). Oczywiście property grid i jego drzewo nigdzie nie jest fizycznie przechowywane (jak to w immediate mode bywa), więc można tam wyświetlić co się żywnie podoba - kwestia napisania prostej funkcji printującej co trzeba. :)

Cytuj
lasa utility ("uzytecznosc")
Nie wiem skąd wytrzasnąłeś takie tłumaczenie słowa utility, ale w tym kontekście ono nijak nie pasuje. "utility" == "przydatne narzędzie/urządzenie"

Cytuj
obsluge innego API (niz te na ktorym zaczelismy ) mozemy zalatwic poprzez #define-y
Z uwagi na różnice między API, jest to taki sobie sposób.

Cytuj
(w jednym z silnikow na forum, renderery ladnie byly schowane w .dll-ach)
Przy okazji ładnie komplikowały prosty program. ;)

Cytuj
Probowalem rzeczonego podejscia IRenderer na sile... okazalo sie to tylko niepotrzebnie napisanym kodem(czyli smietnikiem) i z racji calej serii wyjatkow (ciezko uogolnic interfejs bez wielkich kompromisow) musialem go przepisywac, poprawiac kilkakrotnie.
Jakiego typu wyjątków? Do GUI wystarczy zestaw podstawowych operacji, a do tego nie potrzeba wielkiej filozofii. Przykładowo API do rysowania grafiki 2D w Allegro, GDI, .NET, czy Javie są na tyle podobne, że gdyby nie różnice wspieranych języków, nie było by większych problemów z ich uogólnieniem. W przypadku API akcelerowanych sprzętowo jest może delikatnie inna filozofia, ale nie jest to też większy problem - w moim przypadku po prostu dodałem wymaganie, że cała grafika i fonty są zawczasu spakowane w jeden atlas tekstur i tyle wystarczyło, żeby całkowicie odciąć się od API pod spodem. :)

Cytuj
(np. wypadaloby przetestowac wszystkie dostepne API w danej dziedzinie pod kompatybinosc z naszym interfejsem w calym zakresie)
Jak wyżej. Piszesz własne API, więc robisz takie funkcje, jakie są Ci potrzebne - narysuj linię w danym kolorze, obrazek i tym podobne. Wrapper pod spodem już dba o szczegóły, jak to najlepiej połączyć z danym API. Przykładowo w przypadku mojego 2D wrappera na D3D wrapper sam już pakuje wszystko w jedną indeksowaną tablicę wierzchołków, zmienia linie na quady oteksturowane jednym pikselem (żeby można było dokładnie wszystko wrzucić do jednej listy) i rysuje dopiero wtedy, gdy trzeba, albo nazbiera mu się wystarczająco geometrii (np. 1000 quadów). Sama aplikacja nie ma żadnej świadomości, że tam dzieje się coś takiego. :)

Cytuj
Ad. 2. "Jak"? Chyba jezeli. I dlaczego przesiadki? Chyba rozbudowy silnika o obsluge d3d.
OpenGL i D3D są na tyle podobne, że bez większych problemów można napisać wspólny interface 2D - jedyną różnica jest to, że w przypadku D3D trzeba przesunąć całą grafikę o 0.5 piksela.

Co do przesiadki, wiem jak to jest, bo sam zaczynałem od OpenGL i dość długo w nim siedziałem. Stadia są następujące:
- Zagorzały zwolennik OpenGL.
- "A dlaczego by nie zajrzeć w końcu co tak naprawdę jest w tym drugim API?"
- Nauka drugiego API (bo zawsze lepiej umieć dwa niż jedno).
- Pisanie w D3D dla zabawy.
- Chęć napisania przenośnego silnika (OpenGL/Direct3D).
- Chęć napisania przenośnego silnika (Direct3D/OpenGL).
- Rodzące się pytanie, po co zajmować się OpenGL.
- Pisanie wyłącznie w Direct3D.

Osobiście myślę, że czeka to każdego (nie dotyczy użytkowników Linuksa), chyba że ktoś jest ignorantem i woli OpenGL od Direct3D (pomimo że nie ma pojęcia jak się w Direct3D pisze), albo z jakiegoś powodu przy OpenGL zwyczajnie się upiera. :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Dab w Czerwiec 21, 2009, 22:58:20
Proponuję przerzucić się z tym mimo wszystko do wątku "OpenGL vs DirectX". :)
Ja nie czuje się ignorantem (przynajmniej jeżeli chodzi o OGL), a GL 3.1 robi duży krok naprzód (poza tym że nie jest jeszcze w praktyce nigdzie zaimplementowane i prawdopodobnie cała reszta świata poza NVidią będzie miała problemy z kompatybilnością). Anyway, czuje się szczęśliwy, ponieważ mam dostęp chociażby do GS nie wymagając wciąż niezbyt popularnej Visty.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 21, 2009, 22:59:01
Cytuj
Ad. 2. "Jak"? Chyba jezeli. I dlaczego przesiadki? Chyba rozbudowy silnika o obsluge d3d.
OpenGL i D3D są na tyle podobne, że bez większych problemów można napisać wspólny interface 2D - jedyną różnica jest to, że w przypadku D3D trzeba przesunąć całą grafikę o 0.5 piksela.

Co do przesiadki, wiem jak to jest, bo sam zaczynałem od OpenGL i dość długo w nim siedziałem. Stadia są następujące:
- Zagorzały zwolennik OpenGL.
- "A dlaczego by nie zajrzeć w końcu co tak naprawdę jest w tym drugim API?"
- Nauka drugiego API (bo zawsze lepiej umieć dwa niż jedno).
- Pisanie w D3D dla zabawy.
- Chęć napisania przenośnego silnika (OpenGL/Direct3D).
- Chęć napisania przenośnego silnika (Direct3D/OpenGL).
- Rodzące się pytanie, po co zajmować się OpenGL.
- Pisanie wyłącznie w Direct3D.

Osobiście myślę, że czeka to każdego (nie dotyczy użytkowników Linuksa), chyba że ktoś jest ignorantem i woli OpenGL od Direct3D (pomimo że nie ma pojęcia jak się w Direct3D pisze), albo z jakiegoś powodu przy OpenGL zwyczajnie się upiera. :)
Kto zasiewa burzę ten zbiera wiatr. U mnie te stadia wyglądają zupeeełnie inaczej :P

Ja z moim GUI nie kombinują tak jak wszyscy tutaj. U mnie GUI jest oddzielone od renderingu, ale rendering jest ustawiony na sztywno na OpenGL. Każdy element interfejsu (przycisk itp.) ma kilka funkcji takich jak onDrag, onClick. W przypadku np. przycisku, onClick jest callbackiem, zaś w przypadku np. scrollbara onClick jest funkcją która obsługuje tylko ten scrollbar i nie jest to wtedy callback. Jak na razie działa dobrze, bez przekombinowania :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 21, 2009, 23:01:02
Z tym OpenGL i Direc3D to masz racje - sam już od dłuższego czasu myślę o Direct3D poważnie - zacząłem od OpenGL bo każdy z osobna i wszyscy na raz mówili ZACZNIJ OD OPEN GL no więc zacząłem. Z braku czasu nie mogę się uczyć Direct3d.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 21, 2009, 23:02:34
Cytuj
w przypadku np. scrollbara onClick jest funkcją która obsługuje tylko ten scrollbar i nie jest to wtedy callback.
Tzn. jak działa i kiedy/przez kogo jest wywoływana ta funkcja?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 21, 2009, 23:26:43
Cytuj
w przypadku np. scrollbara onClick jest funkcją która obsługuje tylko ten scrollbar i nie jest to wtedy callback.
Tzn. jak działa i kiedy/przez kogo jest wywoływana ta funkcja?
U mnie robi to klasa o oryginalnej nazwie GUIManager  :P scrollbar ma bounding rectangle, GUIManager sprawdza czy kliknięcie było w tymże prostokącie, jeśli tak, to daje scrollbar->onClick(clickX, clickY) i niech się scrollbar męczy czy kliknięto w strzałkę scrollbara, czy w pasek czy w co.

Pewnie są na to jakieś super mądre metody z przekazywaniem odpowiedzialności i podziałem na różne struktury, ale tym później się będę martwił, a wolę mieć coś co działa niż piękny projekt na papierze :]
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 22, 2009, 00:02:29
Dzisiaj dużo zrobiłem bo wybrałem Allegro jako interface graficzny oraz przemyślałem dokładniej to co chce napisać i jak to ma wyglądać!

W załączniku screen - jeszcze nic nie jest funkcjonalne no ale już da się dodawać elementy i je rysować.

od strony kodu wygląda to mniej więcej tak:
AllegroInterface Interface; // Nasz allegrowy interfejs graficzny
...
gui_button * b1 = new gui_button("b1", 10, 10, 100, 50); //stworzenie przycisku
gui_button * b2 = new gui_button("b2", 210, 10, 100, 50);
gui_button * b3 = new gui_button("b3", 410, 10, 100, 50);
gui_window * w1 = new gui_window("OKIENKO PIERWSZE yyy", 100, 100, 300, 300, true); //stworzenie okna
...
Interface.draw(bufor, b1); // rysowanie przycisku
Interface.draw(bufor, b2);
Interface.draw(bufor, b3);
Interface.draw(bufor, w1); // rysowanie okna


Kod był troszkę na szybko pisany w założeniu chce aby każdy przycisk był powiązany z jakimś oknem, a rysowanie odbywało się przy pomocy jednej funkcji dla maksymalnego uprostrzenia (system podkreśla mi to słowo:P).

Ma to wyglądać mniej więcej tak:

AllegroInterface Interface;
...
gui_button * b1 = new gui_button("b1", 10, 10, 100, 50);
gui_button * b2 = new gui_button("b2", 210, 10, 100, 50);
gui_button * b3 = new gui_button("b3", 410, 10, 100, 50);
gui_window * w1 = new gui_window("OKIENKO", 410, 10, 100, 50, 1);

gui_window panel = new gui_window("panel", 0, 0, WIDTH, HEIGHT, 0);
panel->addItem(b1);
panel->addItem(b2);
panel->addItem(b3);
panel->addItem(w1);
w1->addItem(inny_przycisk); //xDDD
....
Interface.draw(bufor); // rysuje wszystko co zapiera się w panelu

Więc okno będzie to podstawa - każde okno będzie zawierało listę elementów jaki się a nim znajdują.
Jeżeli kursor myszki będzie na oknie to będą sprawdzane wszystkie elementy tego okna (nie wiem w ogole czy jest sens wprowadzać tu taką lub bardziej zaawansowaną optymalizację skoro w oknie może znajdować się z 200-300 Itemów maksymalnie... jakaś 1 milisekunda dla procesora).
Rozwijane Menu itp planuję zorganizować jako okno z butonami.

Więc to tyle teraz idę oglądnąć kilka odcinków DragonBalla xD :)
Pozdrawiam
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 22, 2009, 00:37:21
Co do przesiadki, wiem jak to jest, bo sam zaczynałem od OpenGL i dość długo w nim siedziałem. Stadia są następujące:
- Zagorzały zwolennik OpenGL.
- "A dlaczego by nie zajrzeć w końcu co tak naprawdę jest w tym drugim API?"
- Nauka drugiego API (bo zawsze lepiej umieć dwa niż jedno).
- Pisanie w D3D dla zabawy.
- Chęć napisania przenośnego silnika (OpenGL/Direct3D).
- Chęć napisania przenośnego silnika (Direct3D/OpenGL).
- Rodzące się pytanie, po co zajmować się OpenGL.
- Pisanie wyłącznie w Direct3D.

Osobiście myślę, że czeka to każdego (nie dotyczy użytkowników Linuksa), chyba że ktoś jest ignorantem i woli OpenGL od Direct3D (pomimo że nie ma pojęcia jak się w Direct3D pisze), albo z jakiegoś powodu przy OpenGL zwyczajnie się upiera. :)
Ha... masz mnie za ignoranta.  ;)

U mnie bylo dokladnie na odwrot... podmien D3D na OGL i na odwrot OGL na D3D.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 22, 2009, 01:10:50
Faktem jest że trzeba/dobrze jest znać i jedno i drugie!
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 22, 2009, 10:47:04
Faktem jest że trzeba/dobrze jest znać i jedno i drugie!
Jak się zna jedno to zna się i drugie. Przecież to to samo tylko nazwy zmienione :P
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 22, 2009, 11:30:48
Jak się zna jedno to zna się i drugie. Przecież to to samo tylko nazwy zmienione :P
Właśnie udowodniłeś, że któregoś nie znasz. ;) Różnice miejscami są dość znaczne, pomijając fakt, że porównanie DX10 i OpenGL (w dowolnej wersji) zupełnie mija już się z celem, bo DX10 ma całkowicie inną filozofię (obiekty stanów, model zasób-widok i tym podobne). :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 22, 2009, 12:15:17
Jak się zna jedno to zna się i drugie. Przecież to to samo tylko nazwy zmienione :P
Właśnie udowodniłeś, że któregoś nie znasz. ;) Różnice miejscami są dość znaczne, pomijając fakt, że porównanie DX10 i OpenGL (w dowolnej wersji) zupełnie mija już się z celem, bo DX10 ma całkowicie inną filozofię (obiekty stanów, model zasób-widok i tym podobne). :)
A kto mówił o DX10 =)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 22, 2009, 12:30:55
Cytuj
A kto mówił o DX10 =)
Chodziło mi o to, że różnice między DX9, a OpenGL są znaczne, a między DX10, a OpenGL ogromne. Skoro twierdzisz, że OpenGL i Direct3D 9 to tylko pozmieniane nazwy, to powiedz jak w OpenGL jednocześnie podpiąć ten sam rendertarget do dwóch samplerów (np. jeden sampluje z filtrowaniem typu POINT, a drugi typu LINEAR). ;)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 22, 2009, 13:57:37
Cytuj
A kto mówił o DX10 =)
Chodziło mi o to, że różnice między DX9, a OpenGL są znaczne, a między DX10, a OpenGL ogromne. Skoro twierdzisz, że OpenGL i Direct3D 9 to tylko pozmieniane nazwy, to powiedz jak w OpenGL jednocześnie podpiąć ten sam rendertarget do dwóch samplerów (np. jeden sampluje z filtrowaniem typu POINT, a drugi typu LINEAR). ;)
zawsze można zrobić FBO blita i wtedy sobie czytać. Można też filtrowanie w shaderze zrobić.

to ty mi powiedz jaki jest odpowiednik PBO w DirectX 9, bo się nie doszukałem!

Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 22, 2009, 14:14:53
Cytuj
zawsze można zrobić FBO blita i wtedy sobie czytać.
I przy okazji zużyć pełny ekran fillrate'u i pamięci na pełen ekran tylko po to, żeby obejść ograniczenie API? Dziękuję, postoję. ;)

Cytuj
Można też filtrowanie w shaderze zrobić.
Nieco lepiej, ale wtedy 4x bardziej obciążasz samplery (znowu tylko i wyłacznie z uwagi na niedomagania API OpenGL), co im się samplerom raczej nie spodoba.

Cytuj
to ty mi powiedz jaki jest odpowiednik PBO w DirectX 9, bo się nie doszukałem!
Nie ma jako takiego odpowiednika, bo taki feature był tam "od zawsze". Tekstury/powierzchnie można tworzyć i lockować z odpowiednimi flagami (np. dynamic/discard), a do szybkiego kopiowania między powierzchniami jest StretchRect. :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Avaj w Czerwiec 22, 2009, 14:19:29
A wracając do GUI...  8)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 00:52:05
A no wracając do gui mam pewien problem ;)

Postanowiłem że wszystko co będzie w oknie będzie umieszczane w vector <obj *> content  (obj to klasa po której inne klasy dziedziczą). Mam funkcję addItem(obj *), za pomocą której wiążę obiekt z oknem. Funkcja addItem dodaje do vectora wskaźnik. Teraz za pomocą funkcji (Interfejsu) draw chcę narysować zawartość okna.

Oto kod:


////////GUI
class gui_window : public obj
{
public: // klasa częściowa i uprostrzona dla czytelności
    vector <obj *> content;

    void addItem(obj * o){
      content.push_back(o);
    }
};

//////INTERFEJS ALLEGROWY

class AllegroInterface{
  public:
    void draw(BITMAP * layer, gui_button * g);   
    void draw(BITMAP * layer, gui_window * g);   
};

//////KOD PROGRAMU
//TUTAJ MAM PROBLEM Z UGRYZIENIEM TEGO :/

for (int i =0; i<w1->content.size(); i++){  // w1 to okno, a content to właśnie vector jego zawartości
          Interface.draw(bufor, w1->content[i]); // 1*
        }

1* - content zawiera obj* więc nie zadziała, jak tutaj sensownie wywołać odpowiednią funkcję rysującą (z AllegroInterface)? Potrzebna mi dodatkowa wiedza o typie...

Jakoś nic sensownego nie przychodzi mi do głowy :/
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: wine w Czerwiec 23, 2009, 00:55:14
zastosować delegat czyli wskaźnik do metody (http://www.warsztat.gd/articles.php?x=view&id=268). Chyba o to ci chodzi?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 23, 2009, 00:56:37
Od tego właśnie są w tym przypadku metody wirtualne.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 01:22:45
Od tego właśnie są w tym przypadku metody wirtualne.

Z mojej wiedzy wynika, że zastosowanie metody wirtualnej by mi pomogło jak by metoda rysująca była wpisana w klasę window jak i w klasę button.

coś w stylu:
#include <cstdlib>
#include <iostream>
#include <string.h>

using namespace std;

class k1{
public:
  virtual void f1(){cout<<"k1 f1:"<<endl;}
          void f2(){cout<<"k1 f2:"<<endl;}
};

class k2: public k1{
public:
  void f1(){cout<<"k2 f1:"<<endl;}
  void f2(){cout<<"k2 f2:"<<endl;}
};

int main(int argc, char *argv[])
{
    k1 *wsk1;
    wsk1 = new k2();
   
    wsk1->f1(); //KLASA DRUGA WUNKCJA PIERWSZA
    wsk1->f2(); //KLASA PIERWSZ FUNKCJA DRUGA
   
    system("PAUSE");
    return EXIT_SUCCESS;
}

Jednak tutaj nie wiem za bardzo jak to podpiąć może to wina już nie najwcześniejszej pory ;)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 23, 2009, 01:45:13
KK: Mówienie o całkowicie innej filozofii przy okazji DX10 jest grubo na wyrost.

 A teraz spójrz jak się napociłeś udowadniając wyższość D3D (na dziś) ponad OGL. Stwierdzileś też po drodze, że sam sie zdecydowaleś na całkowite pominięcie, odżegnanie od OGL w przypadku windy. A teraz powiedz, jak to się ma do tych interfejsów na API które warto tworzyć, do Agile Development które od zawsze chwalisz.
 ;)

Ja tu dostrzegam szereg kontrastów.

Co do Utility... wziąlem je w cudzysłów, a także nawias (chyba?). Znam słowo, jego znaczenie i używałem... nigdy nie musiałem tłumaczyć na polski. Z racji braku pewności jak powinno być, napisałem to tak jak napisałem... co by żadnego malkontenta nie urazić. No i proszę - mimo to - znalazł się taki. :)


Co do problemu interfejsu... zamiast metod wirtualnych możesz wykorzystać template-y (co polecam):
Kod: (cpp) [Zaznacz]
struct IDrawable
{
  void IDrawable_Draw();
};
struct DrawableObject : IDrawable
{
  void IDrawable_Draw()
  {
  }
};
struct Panel
{
  template<typename DrawableT>
  void Draw(DrawableT& drawable)
  {
    drawable.IDrawable_Draw();
  }
};

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
  Panel panel;  
  DrawableObject drawableObject;
  panel.Draw<DrawableObject>(drawableObject);
  return 0;
}
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 23, 2009, 04:23:52
Co do problemu interfejsu... zamiast metod wirtualnych możesz wykorzystać template-y (co polecam):
Kod: (cpp) [Zaznacz]
 panel.Draw<DrawableObject>(drawableObject);
Template to słaby zamiennik metod wirtualnych. Co jeśli nie znasz typu DrawableObject i masz listę obiektów IDrawable ?

A teraz powiedz, jak to się ma do tych interfejsów na API które warto tworzyć, do Agile Development które od zawsze chwalisz.  ;)
Wystarczy mieć renderer z kilkoma metodami :
* Start2DMode()
* DrawImage( x, y, image )
* DrawLine( x, y, x, y )
* DrawRectangle( x, y, w, h )
* DrawString( text )
* LoadTexture( name )
I to wystarczy. Żadna filozofia. Nie ma najmniejszego znaczenia czy to będzie pod D3D czy OGL bo przerobienie tego to jest 1 godzina, a taki interface jak powyższy "wychodzi" sam z siebie. Przecież głupotą byłoby pisać np. w metodzie GUI_Button::Draw wywołanie bezpośrednio do DrawPrimitive i jakieś bawienie się w ustawianie macierzy, shader'ów, vertex declaration itd. To jest robione po stronie renderera i wybór D3D czy OGL nie wpływa na interface renderera 2D.


Z mojej wiedzy wynika, że zastosowanie metody wirtualnej by mi pomogło jak by metoda rysująca była wpisana w klasę window jak i w klasę button.
Bo tak powinno być. Umieszczanie w "rendererze" różnych metod typu "void draw(BITMAP * layer, wstaw_tutaj_nazwe_klasy_gui * g);" mija się z celem. Powinieneś zrobić metodę draw w obiekcie typu gui_element.

Poza tym nie widzę za bardzo czym się różni gui_button od gui_window.

Immediate Mode GUI jest bardzo wygodne nie tylko ze względu na prostotę ale też dlatego że rozwiązuje powyższe problemy automatycznie. Ostatnio jak piszę edytory w C# to olewam cały ten Framework .NET i wbudowane kontrolki. Mam tylko swoją klasę którą wykorzystuję do wszystkiego (listy, buttony, widoki jakichś rzeczy itd).
Do tego warto mieć odizolowane rysowanie kontrolek od kodu. Zamiast metody "draw" którą trzeba przeciążyć żeby narysować Button, to do kontrolki podaję coś w rodzaju dynamicznego XAML. Wszystko jest rysowane z danych a nie kodem. Np. narysowanie jakiegoś obrazka z czarną obwódką:
// pseudocod
draw_image( {image_name}, {x} + 1, {y} + 1 )
draw_frame( {x}, {y}, {x}+{w}, {y}+{h}, black )
w klamerkach {} są zmienne odczytywane z różnych miejsc: zmienne z globalnej tablicy lub zmienne lokalne w kontrolce.
Dzięki temu mam tylko jedną klasę "UIElement" która służy do wszystkiego; Button, List, TreeView, itd. Gdy potrzebuję wiedzieć kiedy dany przycisk będzie wciśnięty to ustawiam mu nazwę event'a który ma mi przysłać w momencie kliknięcia.


Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 10:46:21
Esidar mówisz o umieszczeniu funkcji rysującej w gui_button i gui_window. Tylko, że gui ma być zbudowane na zasadzaie: GUI osobno i WIZUALIZACJA GUI tez osobno.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: master18 w Czerwiec 23, 2009, 11:37:19
Ja już kilka projektów mam za sobą. Na początku było fajnie bo GUI zawierały około 300, ale po ostatnim gdzie tych kontrolek wyszło ponad 2500 to postanowiłem zrobić GUI ładowane z pliku, tym bardziej że program jest wielojęzyczny polski, angielski, ruski itd.
Nie wiem jak to się ma do wydajności jeśli chodzi o metody opisywane przez was, ale ja postanowiłem zrobić coś podobnego do metody działania kontrolek WinApi. Każdy rodzaj kontrolki przechowuje swoje pozycje i skalę o wartościach od 0.0f do 1.0f razy rozdzielczość ekranu/okna. Potem mam klasę meneger_GUI i ona zarządza przepływem komunikatów (mysz i klawiatura). Rekurencyjnie rozsyłam sobie te komunikaty po kontrolkach i każda kontrolka sama sobie robi z tym co chce np. mouse over, mouseLB down. Potem ta kontrolka wystawia stosowny komunikat do kolejki komunikatów ze swoim nr ID. Do tego jeszcze każda kontrolka ma wskaźnik na swojego rodzica, np okno i wtedy sama pobiera sobie z niego takie parametry jak widzialność, pozycja itp.
GUI działa na DX i muszę przyznać, że wydajność tej metody są zadowalające. Bufor wierzchołków i indeksów blokuję tylko w razie konkretnego zdarzenia.
No ale jeszcze nie zaprojektowałem wszystkich kontrolek, żeby wiedzieć na dokładnie jak to się sprawdzi.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 23, 2009, 11:44:40
Esidar mówisz o umieszczeniu funkcji rysującej w gui_button i gui_window. Tylko, że gui ma być zbudowane na zasadzaie: GUI osobno i WIZUALIZACJA GUI tez osobno.

Zamiast metody "draw" którą trzeba przeciążyć żeby narysować Button, to do kontrolki podaję coś w rodzaju dynamicznego XAML.

Ja nie mam metody draw w kontrolkach. Mam w rendererze "void draw( xaml_data* data);" z danymi pobranymi z kontrolki. To że tobie poradziłem użycie draw w kontrolce to dlatego że z jakiegoś powodu uparłeś się mieć 2 różne klasy gui_button i gui_window i powtórzę, nadal nie widzę między nimi różnicy :)

Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: mdn w Czerwiec 23, 2009, 12:41:02
Moim gui, które powoli wychodzi ze stanu projektu, oparte jest na sprite'ach (kontrolka sama pobiera z pliku tekstury odpowiednie fragmenty, które składają sie na jej wygląd, i 'skleja się' do kupy) i sama się wyświetla (wirtualna metoda Draw(); ).
W ten sposób moje gui uzależnione jest od dx9, z drugiej strony wystarczy podmienić jeden plik z teksturą, by uzyskać całkiem inne gui ;)
I szczerze powiedziawszy, trudno jest mi sobie wyobrazić oddzielenie modułu wyświetlania i gui, niestety.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 12:59:12
Esidar mówisz o umieszczeniu funkcji rysującej w gui_button i gui_window. Tylko, że gui ma być zbudowane na zasadzaie: GUI osobno i WIZUALIZACJA GUI tez osobno.

Zamiast metody "draw" którą trzeba przeciążyć żeby narysować Button, to do kontrolki podaję coś w rodzaju dynamicznego XAML.

Ja nie mam metody draw w kontrolkach. Mam w rendererze "void draw( xaml_data* data);" z danymi pobranymi z kontrolki. To że tobie poradziłem użycie draw w kontrolce to dlatego że z jakiegoś powodu uparłeś się mieć 2 różne klasy gui_button i gui_window i powtórzę, nadal nie widzę między nimi różnicy :)


Do klasy windows można przypisywać/dodawać przyciski (buttony) oraz inne okna.
Do klasy button można przypisywać różne akcje, które uruchamiają się po kliknięciu w przycisk.
Tak to rozplanowałem jeżeli ma to jakąś wadę proszę o jej podanie bo na kartce wyglądało to dość dobrze ;)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 23, 2009, 13:07:01
Cytuj
Do klasy windows można przypisywać/dodawać przyciski (buttony) oraz inne okna.
Do klasy button można przypisywać różne akcje, które uruchamiają się po kliknięciu w przycisk.
Tak to rozplanowałem jeżeli ma to jakąś wadę proszę o jej podanie bo na kartce wyglądało to dość dobrze ;)
Wada: za dużo tego przypisywania, ale to pewnie przez moje zboczenie na punkcie immediate mode GUI (gdzie przyciski się robi jedną linijką - bez żadnych new/delete, callbacków, przypisywania itp). :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: master18 w Czerwiec 23, 2009, 13:21:23
Osobiście też mam atlas GUI, to bardzo ułatwia sprawę. A co do reakcji na button np. to może lepiej jak by ona wysyłała komunikat do aplikacji o tym fakcie ze swoim ID. Planuję w przyszłości zrobić sobie edytor GUI, a aplikacja ładowała by sobie kontrolki z pliku. Do tego podejścia skłoniło mnie długie czasy kompilacji dużego projektu tylko po to by przesunąć kontrolkę w lewo lub w prawo. No chyba, że ktoś ma to GUI w DLL.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 23, 2009, 13:42:15
Cytuj
Do tego podejścia skłoniło mnie długie czasy kompilacji dużego projektu tylko po to by przesunąć kontrolkę w lewo lub w prawo.
Rozwiązanie: automatyczne układanie kontrolek. :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: wine w Czerwiec 23, 2009, 15:36:17
No chyba, że ktoś ma to GUI w DLL.
albo w jakimś zewnętrznym pliku...
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 15:53:47
A ja dalej nie wiem na jakiej zasadzie mogę odebrać poprawnie typy w funkcji rysującej. Jak rozpoznać czy addItem było wywołana dla gui_button czy gui_window ? Może jakiś mądrzejszy kolega mnie oświeci ??
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Paweł w Czerwiec 23, 2009, 15:58:56
zapewne przeszukałes forum?
http://forum.warsztat.gd/index.php/topic,11047.0.html (http://forum.warsztat.gd/index.php/topic,11047.0.html)

EDIT:
IMGUI wyglada conajmniej interesujaco :P googlowalem troche na ten temat, zastanawiam sie jednak czy uzywajac tego typu rozwiazania nie traci sie tej warstwy abstrakcji GUI -> render?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: yarpen w Czerwiec 23, 2009, 16:05:37
Osobiście też mam atlas GUI, to bardzo ułatwia sprawę. A co do reakcji na button np. to może lepiej jak by ona wysyłała komunikat do aplikacji o tym fakcie ze swoim ID. Planuję w przyszłości zrobić sobie edytor GUI, a aplikacja ładowała by sobie kontrolki z pliku. Do tego podejścia skłoniło mnie długie czasy kompilacji dużego projektu tylko po to by przesunąć kontrolkę w lewo lub w prawo. No chyba, że ktoś ma to GUI w DLL.
W duzych projektach uzywa sie po prostu Scaleforma albo podobnej biblioteki i robi GUI we Flashu. Ale do wiekszosci projektow domowych to jednak mocny overkill.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 23, 2009, 16:45:16
Nie wspominając że Adobe Flash CS4 to jakieś 4tyś zł :)

Scaleform używa rozwiązań z IMGUI czyli eventy, wspólna baza parametrów itd. Z drugiej strony Scaleform jest oparty o Flasha który nie jest IMGUI i ma często przemieszanie kodu z grafiką (nawet do takich pierdół jak zapętlanie animacji) i który jako program do animacji grafiki wektorowej jest ok, ale do robienia w nim UI super nie jest :) np. nie fajne połączenie kodu z grafiką, brak wsparcia dla 3D i shader'ów itp

Kiedyś był Anark Gameface który miał własne rozwiązania, własny edytor (i był ogólnie słaby pod względem możliwości), ale już przestał istnieć (przejęła go NVidia i słuch o nim zaginął :) ).

Ja tu widzę niszę OpenSource lub Indie dla kompleksowego rozwiązania GUI :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 23, 2009, 17:02:13
zapewne przeszukałes forum?
http://forum.warsztat.gd/index.php/topic,11047.0.html (http://forum.warsztat.gd/index.php/topic,11047.0.html)

EDIT:
IMGUI wyglada conajmniej interesujaco :P googlowalem troche na ten temat, zastanawiam sie jednak czy uzywajac tego typu rozwiazania nie traci sie tej warstwy abstrakcji GUI -> render?

Tutaj funkcja draw jest wpisana do CElemnet i jest virtualna - wiem jak coś takiego zastosować. U mnie z założenia - co doradzili mi warsztatowicze (przynajmniej tak to zrozumiałem) w CElement i w innych po nim dziedziczących klasach nie ma być draw, ponieważ draw ma być niezależne od logiki GUI.

Nic nie umiem wymyślić jedyne co mi pozostało to statyczny wskaźnik na funkcję rysującą.
Pseudokod pokazuje to tak:
// funkcja, którą będziemy wywoływać
void AllegroInterface.DrawButton(){ // FUNKCJA Z INTERFEJSU ALLEGRO DO RYSOWANIA PRZYCIKSÓW
  std::cout << "Rysowanie" ; // RYSUJE :)
}
...
class Button{ // KLASA PRZYCISKU
  void (*Draw)();
};
...
Button.Draw = &AllegroInterface.DrawButton(); // Teraz wskaznik z klasy button wskazuje na funkcje z Interfejsu
...
vector <obj *> content; // Wektor z wskaznikami na wszytkie elementy gui

content[x]->(*Draw)(); // Wywołanie draw dla Buttona


Jednak rozwiązanie ma minus bo funkcję rysującą trzeba przypisywać do każdej z klas dla której może wystąpić rysowanie :/

No ale skoro nie ma lepsze metody - łatwiejszej w używaniu to nic będę musiał opierać się na tym.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: poopa w Czerwiec 23, 2009, 22:08:42
Ja mam i w takich sytuacjach uzywam zdarzen...

Events jest klasa bazowa... ma jeden skladnik, jest to wskaznik na eventHandler.

Kazda klasa dziedziczaca z Events przypisuje wlasna funkcje do obslugi zdarzen...

W ten sposob wywolanie rysowania na dowolnym obiekcie (dziedziczacego z Events) sprowadza sie do wywolania Events::OnDraw na eventHandler-ze z pod wskazanego adresu, zapodając sam adres jako jeden z parametrow.

To tylko kolejna z możliwości - oczywiście.


Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: djsmtih w Czerwiec 23, 2009, 22:26:45
U mnie wygląda to tak:
CElement{
CElement *Parrent;
vector<CElement*> Child;
int action,value;

virtual void GenerateEvent(CElement* Message)
{
       Parrent->GenerateEvent(Message);
}

};
I na przykład jeśli naciśnięty zostaje przycisk wywołuje on:
GenerateEvent(this);
Przycisk->Pole->Okienko->GuiMenager->CallbackFunc()

Ponieważ funkcja jest wirtualna to np. w obiektach typu CListBox dla niektórych akcji przesyłanie może być
przerywane bo przycisk odpowiada za dodanie elementu do list boxa.

I jeszcze jedna fajna sprawa :) Przycisk ma odpowiadać za dodanie jakiejś tekstury.
TextBox do którego wpisywany jest plik tekstury staje się dzieckiem tego przycisku dzięki czemu
w funkcji odbierającej komunikaty można zrobić tak:

Tex.Load(Message->Child[0]->ReturnCharValue());

Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Dab w Czerwiec 24, 2009, 15:36:46
Mam pytanie do miłośników IMGUI. Jakie w zasadzie korzyści mamy z czegoś takiego w projekcie większym niż 500 linii kodu? (poza tym, że jest cool & trendy) Miałem nieprzyjemność dłubać przy jednej grze która korzystała z czegoś takiego (aczkolwiek nie wiedziałem, że ma to taką nazwę) -- Battle for Wesnoth i niestety był to istny koszmar. Podstawowym wzorcem projektowym jest tam magic button, GUI generalnie przechowuje połowę danych i zarządza 90% gry. Dopisanie czegokolwiek (albo nawet wyciągnięcie jakiś danych) do tego kodu to była masakra.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 24, 2009, 16:14:20
Mam pytanie do miłośników IMGUI. Jakie w zasadzie korzyści mamy z czegoś takiego w projekcie większym niż 500 linii kodu? (poza tym, że jest cool & trendy) Miałem nieprzyjemność dłubać przy jednej grze która korzystała z czegoś takiego (aczkolwiek nie wiedziałem, że ma to taką nazwę) -- Battle for Wesnoth i niestety był to istny koszmar. Podstawowym wzorcem projektowym jest tam magic button, GUI generalnie przechowuje połowę danych i zarządza 90% gry. Dopisanie czegokolwiek (albo nawet wyciągnięcie jakiś danych) do tego kodu to była masakra.
Jak zwykle, kwestia realizacji :) W teorii IMGUI lepiej zarządza danymi bo są tylko w 1 miejscu. Nie ma kopii w 20 miejscach i nie musisz tego ręcznie update'ować. Jeżeli masz np. wyświetlić nazwę gracza to umieszczasz na ekranie dowolną ilość TextBox'ów które wyświetlają np. "=Player.Name" co oznacza wyświetlenie zawartości zmiennej Name w obiekcie Player. Każdy TextBox potrafi zmienić nazwę gracza i automatycznie o tym powiadomić wszystkich zainteresowanych.

Jeżeli każdy TextBox robi swoją kopię tego tekstu (np. tak jak to robi WinAPI, wxWidgets, WindowsForms itp itd) to masz parę godzin pracy na oprogramowanie kopiowania i modyfikacji każdej kopii tej jednej zmiennej.

Nie wiem w jaki sposób to było zrealizowane w BfW skoro to było takie upierdliwe :)

W teorii dorobienie kolejnej zmiennej + kontrolka to powinno wystarczyć coś w stylu:
GUI::AddVariable<float>( "Player.Race" );
AddControl( "TextBox", 10, 15, 100, 20, "=Player.Race" );
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 24, 2009, 16:26:50
Cytuj
W teorii dorobienie kolejnej zmiennej + kontrolka to powinno wystarczyć coś w stylu:

Kod:
GUI::AddVariable<float>( "Player.Race" );
AddControl( "TextBox", 10, 15, 100, 20, "=Player.Race" );
To chyba nie jest do końca Immediate Mode GUI, z tego, co wyczytałem. ;)


Przy podejściu IMGUI, żeby zrobić przycisk wystarczy jedna linijka:
if( Button("Kliknij mnie!") ) rob_cos();

Ciekawy tutorial na temat IMGUI można znaleźć tutaj: http://sol.gfxile.net/imgui/
(chociaż osobiście wolę stosować automatyczny layouter, który sam wyznacza gdzie ma rysować przyciski)


EDIT:
A jeżeli chodzi o editboxy, to też można to załatwić jedna linijką:
if( EditBox( &moje_dane, UICośtamConverter() ) ) data_changed();
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: DamorK w Czerwiec 24, 2009, 18:34:14
A jeżeli chodzi o editboxy, to też można to załatwić jedna linijką:
if( EditBox( &moje_dane, UICośtamConverter() ) ) data_changed();

A moje_dane to strukturka zawierająca wszystkie dane które normalnie znalazłyby się w obiekcie, czyli aktualny tekst, pozycja kursora, czy editbox jest aktywny etc.? A jak nie to gdzie to trzymamy?
I jeszcze jedno. Nie wiem czy dobrze rozumiem ale czy poszczególne kontrolki nic o sobie nie wiedzą? Wobec tego co w przypadku kiedy dwie kontrolki zasłaniają się, skąd wiemy która jest nad która, tj. która ma przechwycić kliknięcie?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 24, 2009, 18:42:13
Ciekawy tutorial na temat IMGUI można znaleźć tutaj: http://sol.gfxile.net/imgui/
W tym tutorialu jest "nadinterpretacja" IMGUI :) Ja wolę ten tutorial http://mollyrocket.com/861 (http://mollyrocket.com/861) w którym wszystko lepiej wyjaśnione.

Główna idea IMGUI to przechowywanie danych/stanów po stronie hosta/użytkownika. Wygląd wszystkich kontrolek może być spokojnie wczytany z pliku i wszystkie animacje, blendingi itp mogą być ustawiane poza kodem. Jeżeli po wciśnięciu "NewGame" plansza ma wyjechać w lewo to mnie to nie interesuje. To jest automatycznie uruchomiona animacja z poziomu GUI.



Gdybym przeczytał tutorial http://sol.gfxile.net/imgui/ to też bym miał wrażenie że w IMGUI chodzi głównie o rysowanie przycisku w moim kodzie (użytkownika) :) Ale to byłaby przecież masakra :) Trzeba by mieć w grze hektolitry kodu w stylu:
if( Button( "KliknijMnie" ) )
{
   NicNieRob_AleNarysujRysunek("Tlo1_lewyrog",10,11);
   NicNieRob_AleNarysujRysunek("Tlo1_prawyrog",50,88);
   NicNieRob_AleNarysujRysunek("Tlo1_dolnypasek",30,11);
   NicNieRob_AleNarysujRysunek("Tlo2",150,121);
   NicNieRob_AleNarysujRysunek("Tlo3",550,388);
   NicNieRob_AleNarysujRysunek("Tlo4",350,111);
}
i za każdym razem musiałbym podawać całą definicję przycisku wklepywaną z palca w Visualu:
if( Button( "KliknijMnie", Position(10,10), Size(100, 30), Image( "LeftCorner", Offset(1,1) ), Image( "RightCorner", Offset(40,3) ) )
Byłoby to "way beyond usability" :) Zamiast tego wizualizację można zdefiniować w pliku (np. XAML). W kodzie korzystasz tylko z ID przycisku:
if( Button( "KliknijMnie" ) )
A wygląd jest zdefiniowany wcześniej i gdziekolwiek.

Ważne też żeby posługiwać się ID a nie tekstem z przycisku. W niektórych przykładach można zobaczyć:
DoTextBox( "To jest przycisk do uruchomienia gry" );
A teraz chcesz zrobić wersję na 16 języków... no i masz "z lekka" problem :) Dlatego wizualizacja jest zupełnie gdzieś indziej i jest nie zależna od kodu.

Główna idea IMGUI to przechowywanie danych/stanów po stronie hosta/użytkownika.

Jedyne czym użytkownik ma się zajmować to odczyt wyniku GUI oraz kontrolowaniem co kiedy ma się pokazać.

Cytuj
(chociaż osobiście wolę stosować automatyczny layouter, który sam wyznacza gdzie ma rysować przyciski)
Grafik "Te 5 przycisków z umiejętnościami postaci ma się ułożyć w pół okrąg, a ta lista to jest ułożona w gwiazdkę. I co ? Pykasz auto-layoutery do każdego przypadku ? :)


Jest jedna też inna rzecz powtarzana w kółko w wielu tutorialach "że zmienne podaje się podczas rysowania". Np.
DoValueEdit( &Player.Position.x );
Jest to kolejna nadinterpretacja IMGUI lub pewne niedomówienie. Równie dobrze może być tak:
DoValueEdit( LuaGlobals["Player.Position.x"] );
Nie jest istotne w jaki sposób przekażemy zmienną do systemu GUI. Czy zrobimy to za pomocą wskaźnika do "float", czy za pomocą nazwy zmiennej w LUA czy cokolwiek innego.

Ja preferuję drugą wersję bo dzięki temu nie określam typu zmiennej. W ten sposób wizualizacja decyduje jaki typ danych obsługuje i w jaki sposób je będzie reprezentować.
DoValueEdit może być TextBoxem z liczbą, może być suwakiem, ComboBox'em, planszą 2D z wyborem itd.

Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 24, 2009, 19:18:54
A moje_dane to strukturka zawierająca wszystkie dane które normalnie znalazłyby się w obiekcie, czyli aktualny tekst, pozycja kursora, czy editbox jest aktywny etc.? A jak nie to gdzie to trzymamy?
Trzyma to jedna z klas GUI. Warto zauważć, że w danym momencie tylko jeden EditBox jest aktywny, więc nie potrzeba trzymać takich informacji per-edit box.

Cytuj
I jeszcze jedno. Nie wiem czy dobrze rozumiem ale czy poszczególne kontrolki nic o sobie nie wiedzą? Wobec tego co w przypadku kiedy dwie kontrolki zasłaniają się, skąd wiemy która jest nad która, tj. która ma przechwycić kliknięcie?
Dwie kontrolki nie powinny się zasłaniać (jak dwa przyciski zachodzą na siebie, to coś z tym GUI jest nie teges). W moim gui o to akurat dba layouter (jak można zauważyć, nigdzie nie przekazuję informacji, jak i gdzie ten przycisk/edit narysować). :)

Cytuj
Ja wolę ten tutorial http://mollyrocket.com/861 w którym wszystko lepiej wyjaśnione.
Ja nie wolę, o mi się to video nie otwiera (swoją drogą, kto słyszał żeby robić tutoriale o kodowaniu w formie video). :)

Cytuj
Gdybym przeczytał tutorial http://sol.gfxile.net/imgui/ to też bym miał wrażenie że w IMGUI chodzi głównie o rysowanie przycisku w moim kodzie (użytkownika) :) Ale to byłaby przecież masakra :) Trzeba by mieć w grze hektolitry kodu
Jeżeli dobrze pamiętam, w tamtym tutorialu wystarczyło wywołać jedną funkcję, a nie samemu rysować przycisk. Co do sposobu wizualizacji - wiadomo, że powinno to być gdzieś indziej, najlepiej z opcją podmiany. :)

Cytuj
A teraz chcesz zrobić wersję na 16 języków... no i masz "z lekka" problem :) Dlatego wizualizacja jest zupełnie gdzieś indziej i jest nie zależna od kodu.
W moim podejściu tekst akurat jest jedyną rzeczą, której nie traktuję jako wizualizacji i jest podawany przez aplikację. Póki co przeróbka "na 16 języków" jest na tyle daleka od rzeczywistych potencjalnych wymagań, że nie zawracam sobie tym głowy. :)

Cytuj
Grafik "Te 5 przycisków z umiejętnościami postaci ma się ułożyć w pół okrąg, a ta lista to jest ułożona w gwiazdkę. I co ? Pykasz auto-layoutery do każdego przypadku ?
Zadaniem mojego GUI jest wspomaganie tworzenia edytorów, a nie menu w grach, więc równie dobrze można próbować układać buttony WinAPI w gwiazdkę z podobnym skutkiem. Mimo wszystko, powyższe da się też załatwić auto-layouterem, któremu podajesz po prostu definicję, gdzie mają leżeć kolejne przyciski. :)

Cytuj
Ja preferuję drugą wersję bo dzięki temu nie określam typu zmiennej. W ten sposób wizualizacja decyduje jaki typ danych obsługuje i w jaki sposób je będzie reprezentować.
DoValueEdit może być TextBoxem z liczbą, może być suwakiem, ComboBox'em, planszą 2D z wyborem itd.
A skąd wizualizacja ma wiedzieć, czym ten DoValueEdit ma być? ;)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: yarpen w Czerwiec 24, 2009, 19:46:05
Cytuj
Ja wolę ten tutorial http://mollyrocket.com/861 w którym wszystko lepiej wyjaśnione.
Ja nie wolę, o mi się to video nie otwiera (swoją drogą, kto słyszał żeby robić tutoriale o kodowaniu w formie video). :)
Akurat wszystkie video Caseya warto obejrzec. To czlowiek, ktory wlasciwie w pojedynke napisal Granny.
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 24, 2009, 21:37:59
Cytuj
Ja wolę ten tutorial http://mollyrocket.com/861 w którym wszystko lepiej wyjaśnione.
Ja nie wolę, o mi się to video nie otwiera (swoją drogą, kto słyszał żeby robić tutoriale o kodowaniu w formie video). :)
"U mnie działa" ;p filmik jest we flashu (ja mam Flash Player 10).

Jeżeli dobrze pamiętam, w tamtym tutorialu wystarczyło wywołać jedną funkcję, a nie samemu rysować przycisk. Co do sposobu wizualizacji - wiadomo, że powinno to być gdzieś indziej, najlepiej z opcją podmiany. :)
W tym tutorialu wywołuje się "button" ze współrzędnymi. Ktoś mało roztropny pewnie zaraz by dodał parametr z nazwą wyglądu a to już się prosi o problemy :) Sprawdzając stan przycisku nie powinno się podawać nic poza identyfikatorem. Wizualizacja powinna definiować położenie przycisku względem ekranu bądź względem okna, jego wygląd podczas stanu Normal, Hot i Active, animacje w stylu bujanie się na boki lub skalowanie itd.

Cytuj
A teraz chcesz zrobić wersję na 16 języków... no i masz "z lekka" problem :) Dlatego wizualizacja jest zupełnie gdzieś indziej i jest nie zależna od kodu.
W moim podejściu tekst akurat jest jedyną rzeczą, której nie traktuję jako wizualizacji i jest podawany przez aplikację. Póki co przeróbka "na 16 języków" jest na tyle daleka od rzeczywistych potencjalnych wymagań, że nie zawracam sobie tym głowy. :)
Dobrze jest jeśli wizualizacja ma wbudowaną obsługę języków. Wtedy ktoś kto rysuje/ustawia przyciski wie czy w tym miejscu zmieści się "flugenfachenundermachen".

A skąd wizualizacja ma wiedzieć, czym ten DoValueEdit ma być? ;)
Przykładowo tak może wyglądać wizualizacja EditBoxa
<Panel id="PodajNazweGracza">
   <Rectangle color="black" x=0 y=0 w=100 h=20 />
   <FillRectangle color="white" x=1 y=1 w=98 h=18 />
   <Text editable="true" x=2 y=2 font="Arial" text_color="black" />
</Panel>
A tak suwaka:
<Panel id="PodajNazweGracza">
   <Rectangle color="black" x=0 y=0 w=100 h=20 />
   <FillRectangle color="white" x=1 y=1 w=98 h=18 />
   <Slider x=2 y=2 color="blue" />
</Panel>
Podczas rysowania, każdy element (rect, fillrect, text, slider) ma dostęp do zmiennej podanej przez użytkownika i może go sobie odpowiednio zintepretować.

DoValueEdit( "PodajNazweGracza", &Player.Name );

U mnie zmienną podaną przez użytkownika może być nie tylko float, string czy bool. Może to być również tablica. Z takiej tablicy, wizualizacja może pobrać więcej rzeczy a nie tylko 1 parametr. W ten sposób można tworzyć np. tootlip albo ikonkę narzędzia. Tooltip to nie tylko prosty rectangle i tekst ale również może być tekst z ikonką (różną w zależności od tekstu), jak również ikonka, tekst i obiekt 3D. Wszystkie dane potrzebne do wizualizacji są wtedy pobierane z parametru będącego tablicą z kolejnymi danymi.

Co do jednej rzeczy... tutaj nie ma cudów, trochę kodu w bibliotece GUI trzeba i tak napisać. To nie jest tak, że jedna klasa wszystko działa :) Trzeba mieć prymitywy które będą coś rysować (line, rect, fill), trzeba mieć proste elementy edycyjne jak np. TextBox który potrafi pobierać Input z klawiatury, rysować kursor, wpisywać znaki... również slidery które pozwalają na przesuwanie jakimś suwakiem, albo wyświetlają stan wartości za pomocą paska itd.
Wizualizacja musi mieć również hierarchię aby przycisk się przesuwał po ekranie razem z oknem.

IMGUI definiuje nie wizualizację ale sposób interakcji z wizualizacją. Nie ma tutaj klasy "gui_button" którą się przeciąża aby mieć swój przycisk. Nie ma też "gui_textbox", ale w samej wizualizacji jest "DrawText" i/lub "DrawEditableText".
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Krzysiek K. w Czerwiec 24, 2009, 21:44:59
Cytuj
Dobrze jest jeśli wizualizacja ma wbudowaną obsługę języków. Wtedy ktoś kto rysuje/ustawia przyciski wie czy w tym miejscu zmieści się "flugenfachenundermachen".
OK, tylko pytanie, w czym ten ktoś będzie rysował/ustawiał te przyciski. Zapewne w jakims edytorze, więc najpierw trzeba zrobić ten edytor, a do edytora potrzebne jest GUI. ;) To, o czym piszesz będzie nadawało się jako GUI na potrzeby silnika gry (włącznie z edytorami i obsługą wielu języków), ale na potrzeby domowej produkcji to znaczny overkill. Mi chodzi o koncepcje pisania GUI do edytorów (gdzie tego GUI jest relatywnie najwięcej), a tam już artyści nie będą układać i animować przycisków - edytor ma po prostu być funkcjonalny i działać. :)
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Adam B w Czerwiec 24, 2009, 23:02:35
A ja rozwiązałem mój problem wywoływania funkcji w następujący sposób:

 - do gui_obj (najbardziej podstawowa klasa po której wszystko dziedziczy) dodałem int type; (potem może na enum zmienie zobacze)
 - type dla okna ma wartość 1, dla przycisku wartość 2 itp :)
 - wyświetlanie jest niezależne od GUI i wygląda tak:

void AllegroInterface::drawElement(BITMAP * layer, gui_obj * g){
     if (g->type==1) drawWindow(layer, (gui_window*) g);
     if (g->type==2) drawButton(layer, (gui_button*) g);
     }

 - wywołanie zaś ogólnej funkcja rysującej będzie miało postać:
for (int i=0; i<w1->content.size(); i++){// Rysuje wszystko to co zawiera się w oknie.
    Interface.drawElement(bufor, w1->content[i]);       
}

Myślę że najprostsze rozwiązanie ale mnie satysfakcjonuje.
Do klasy "gui_obj" dołączę funkcję typu getX, getY, getWidth itp. żeby wszystko zapakować ;)
Programując inną wizualizację trzeba będzie tylko wiedzieć co ma jaki: "type". No i oczywiście znać funkcje typu getCOŚ ale są IMHO bardzo intuicyjne + wywoływać funkcję Pressed, Released itp.
Wydaje mi się, że jest to proste rozwiązanie i łatwe do zrozumienia. Co wy na to ?
Pozdrawiam 
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Esidar w Czerwiec 25, 2009, 15:02:44
To, o czym piszesz będzie nadawało się jako GUI na potrzeby silnika gry (włącznie z edytorami i obsługą wielu języków), ale na potrzeby domowej produkcji to znaczny overkill.
Dlatego wcześniej wspomniałem że przydałoby się porządne GUI Open Source z porządnym edytorem :) Jeśli kogoś nie bawi robienie własnego GUI to będzie w sam raz :)


A co do samej koncepcji IMGUI to jest szalenie wygodna i nie tylko w grach. Do napisania biblioteki nie potrzeba nakładu pracy większego niż "zwykłe" GUI oparte o klasy i message, natomiast w samym użyciu jest rewelacyjne. Zwłaszcza trzymanie wszystkich stanów/danych po stronie klienta. Edytory pisze się w tym znakomicie a co najważniejsze dużo szybciej :)
Oczywiście nie mówię tutaj o toolach z jedną listą i jednym butonem, bo to można zrobić jakkolwiek. Ale jeśli masz edytor np. do układania elementów na ekranie to fakt że kontrolki GUI korzystają bezpośrednio z danych programu, jest bardzo wygodne.
Najprostszy przykład: jeżeli masz listę elementów na ekranie (1 kontrolka) oraz wyświetlasz te elementy w widoku (2 kontrolka) to pewnie chcesz aby zaznaczenie elementu było widoczne i tu i tu. Normalnie to trzeba synchronizować takie zmiany między kontrolkami, a tak to kontrolki same się o tym dowiadują/same się o to pytają. Przy okazji trzecia kontrolka wyświetlająca właściwości obiektów (Properties) sama zauważy zmianę zaznaczenia i sama odświeży parametry które pokazuje.

Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Zombiak w Lipiec 03, 2009, 15:39:01
Odswieżę trochę topic. Nasuwa mi się pewna wątpliwość co do użyteczności IMGUI. Idea jest fajna tylko jakoś nie wyobrażam sobie rysowania w tym okien. Owszem jeden dialog to nie problem (chociaż byłoby to dziwne troszczyć się o relatywną pozycję kontrolek i samej ramki w kodzie gry) no to wiele takich okien kompletnie odpada. Zakładając, że piszemy te DoButton, rysowanie kontrolki odbywa się tam gdzie jej obsługa. To znaczy, że pewne elementy kontrolki zawsze będą nad innymi. Pomijając nawet okienka to zwykły combobox po rozwinięciu zostanie zasłonięty przez drugi znajdujący się niżej. Czy to ja nie łapię idei czy to faktycznie jest ograniczenie tej techniki?
Tytuł: Odp: My own GUI ;P
Wiadomość wysłana przez: Dab w Lipiec 03, 2009, 15:41:15
Nie. Renderowanie nie odbywa się w DoButton, tylko w momencie EndGUI. Od momentu BeginGUI aż do EndGUI wszystko jest buforowane.