Autor Wątek: FUGE - GUI do twojej gry  (Przeczytany 20770 razy)

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Luty 20, 2009, 16:10:08
Mam jeszcze jedno pytanie: po co jest funkcja BeginScene w rendererze? Miałem tam kod ustawiający odpowiednie stany urządzenia (bufor-z, alpha, FVF, oświetlenie, przekształcenia). Początkowo GUI w ogóle się nie rysowało, dopiero po zamienieniu formatu wierzchołka z D3DFVF_XYZ na D3DFVF_XYZRHW ujrzałem coś na ekranie. Nie działał jednak alpha blending. Przed chwilą odkryłem, że jak przeniosę kod z BeginScene np. do DrawRectangle to wszystko jest tak jak być powinno. Okazało się, że BeginScene w ogóle nie jest wywoływana :)

Bo tę funkcję użytkownik powinien wołać sam - jeśli potrzebuje. Jeśli nie, to można jej w ogóle nie implementować (tj. zostawić pustą definicję). Stany urządzenia musisz ustawiać w funkcjach rysujących (DrawImage, DrawRectangle itd.). Nie wiem, czy to ma sens, ale kiepsko znam Direct3D i nie chciało mi się w to wgłębiać :P. We wbudowanym rendererze DirectX jest tam resetowanie urządzenia, czyszczenie ekranu, no i woła się BeginScene na urządzeniu.

Mi z kolei FUGE nie wywołuje DrawImage mojego renderera :(. Jak by coś to LoadImage mojej klasy bitmapy działa poprawnie i zwraca true.

Jesteś pewien, że DrawImage się nie woła? Rysowanie "fajki" na checkboxie wygląda na przykład tak:

Kod: (cpp) [Zaznacz]
if (m_Checked)
    {
        CSize bmp_size = m_BitmapSymbols->GetSize();
        CRect src_rect (CPoint (0, 0), bmp_size); 
        const int sz = 16; 
       
        if (bmp_size.width > 0 && bmp_size.height > 0)
        {
            src_rect.x = (4 % (bmp_size.width / sz)) * sz;
            src_rect.y = (4 / (bmp_size.width / sz)) * sz;
            src_rect.width = sz;
            src_rect.height = sz;
           
            GetRenderer()->DrawImage (m_BitmapSymbols, m_AbsRect.GetTopLeft(), &src_rect);           
        }       
    }

Tak więc jeśli checkbox jest zaznaczony, a bitmapa prawidłowa, to DrawImage musi się wywołać. No, chyba że GetRenderer zwraca jakieś głupoty, ale w takim wypadku raczej nic by ci się nie rysowało.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Angru

  • Użytkownik

# Luty 20, 2009, 16:47:22
@maVes:
Kod przygotowania i sprzątania po rysowaniu GUI proponuję umieścić gdzieś w swojej klasie (np. bazowej GUISystem dla FugeGUISystem), która będzie współpracować z twoim silnikiem dając interfejs beginDraw() i endDraw(). Wtedy GUISystem::drawGUI() byłaby wirtualna i definiowana ponownie w FugeGUISystem. W ten sposób struktura ci się nie posypie jak Złośliwiec nas oleje i przestanie wypuszczać fixy :P

@Złośliwiec:
Cytuj
CSize bmp_size = m_BitmapSymbols->GetSize();
Hmm, jeżeli m_BitmapSymbols jest klasą po IBitmap, to moja FugeBitmap : public IBitmap korzystająca wewnętrznie z mojej klasy bitmapy chyba po prostu nie wiej jak zrobić GetSize(). Ta metoda nie jest wirtualna i nie mogę tu nic zmajstrować.

Offline maVes

  • Użytkownik

# Luty 20, 2009, 17:19:46
Kod przygotowania i sprzątania po rysowaniu GUI proponuję umieścić gdzieś w swojej klasie (np. bazowej GUISystem dla FugeGUISystem), która będzie współpracować z twoim silnikiem dając interfejs beginDraw() i endDraw(). Wtedy GUISystem::drawGUI() byłaby wirtualna i definiowana ponownie w FugeGUISystem. W ten sposób struktura ci się nie posypie jak Złośliwiec nas oleje i przestanie wypuszczać fixy :P
Zrobiłem tak jak mówił Złośliwec - stany urządzenia ustawiam w BeginScene, a następnie ręcznie wywołuję tę funkcję przed rysowaniem GUI.

Cytuj
CSize bmp_size = m_BitmapSymbols->GetSize();
Hmm, jeżeli m_BitmapSymbols jest klasą po IBitmap, to moja FugeBitmap : public IBitmap korzystająca wewnętrznie z mojej klasy bitmapy chyba po prostu nie wiej jak zrobić GetSize(). Ta metoda nie jest wirtualna i nie mogę tu nic zmajstrować.
Też tak przez chwilę myślałem. Postawienie słówka virtual przy GetSize i nadpisanie funkcji by tu pomogło, ale znalazłem inne rozwiązanie. Wystarczy przy wczytywaniu obrazka odpowiednio ustawić pole m_Size dziedziczone po IBitmap :)

Offline Angru

  • Użytkownik

# Luty 20, 2009, 17:32:01
Cytuj
CSize bmp_size = m_BitmapSymbols->GetSize();
Hmm, jeżeli m_BitmapSymbols jest klasą po IBitmap, to moja FugeBitmap : public IBitmap korzystająca wewnętrznie z mojej klasy bitmapy chyba po prostu nie wiej jak zrobić GetSize(). Ta metoda nie jest wirtualna i nie mogę tu nic zmajstrować.
Też tak przez chwilę myślałem. Postawienie słówka virtual przy GetSize i nadpisanie funkcji by tu pomogło, ale znalazłem inne rozwiązanie. Wystarczy przy wczytywaniu obrazka odpowiednio ustawić pole m_Size dziedziczone po IBitmap :)

[/quote]

Dobry pomysł, tak też zrobię. Jak dotyram do 25-tego posta to dam ci punkt karmy :) Złośliwiec też dostanie za Fuge i kolejne wersje. I za słowko virtual jeżeli wstawi (będzie bardziej elegancko).

@Złośliwiec
A tak przy okazji, jak już FUGE wgramolił się w mój kod fajnie byłoby wiedzieć od czego to akronim (jeżeli w ogóle, może być imię psa, albo tak ci się wklepało)

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Luty 20, 2009, 18:52:54
Hmm, jeżeli m_BitmapSymbols jest klasą po IBitmap, to moja FugeBitmap : public IBitmap korzystająca wewnętrznie z mojej klasy bitmapy chyba po prostu nie wiej jak zrobić GetSize(). Ta metoda nie jest wirtualna i nie mogę tu nic zmajstrować.

Zauważ, że ta metoda to trywialny akcesor. Nie ma sensu czynić jej wirtualną. Jedynym poprawnym sposobem zakomunikowania "otoczeniu" klasy rozmiaru bitmapy jest ustawienie pola m_Size na odpowiednią wartość. Najwidoczniej tego nie robisz podczas wczytywania bitmapy.

A tak przy okazji, jak już FUGE wgramolił się w mój kod fajnie byłoby wiedzieć od czego to akronim (jeżeli w ogóle, może być imię psa, albo tak ci się wklepało)

Tego nawet najstarsi górale nie pamiętają ;). Dwie ostatnie litery na pewno od GUI Environment, a reszta?... Zaraza wie. Jak chcesz, to możesz coś wymyślić. Najlepiej żeby wyszedł akronim rekurencyjny ;).

//EDIT:
Cytuj
Też tak przez chwilę myślałem. Postawienie słówka virtual przy GetSize i nadpisanie funkcji by tu pomogło, ale znalazłem inne rozwiązanie. Wystarczy przy wczytywaniu obrazka odpowiednio ustawić pole m_Size dziedziczone po IBitmap

O, właśnie o tym mówiłem :).
« Ostatnia zmiana: Luty 20, 2009, 18:55:08 wysłana przez Złośliwiec »

Offline Angru

  • Użytkownik

# Luty 20, 2009, 21:34:55
Cytuj
Zauważ, że ta metoda to trywialny akcesor.
Słusznie, zasugerowałem się chyba myśląc, że IBitmap to czysty interfejs. Słabo się temu przyjrzałem, a m_Size jest udokumentowane jako protected. Cofam zatem to, że będzie bardziej elegancko z virtualnym getterem.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Luty 20, 2009, 22:23:07
Słusznie, zasugerowałem się chyba myśląc, że IBitmap to czysty interfejs.

W moich "dziełach" abstrakcyjne interfejsy nie istnieją :P. Uważam je bowiem za ślepy idealizm - więcej klas, więcej pisania, brak pożytku. Nie mnożyć bytów ponad potrzebę ;).

Offline PoD

  • Użytkownik

# Marzec 06, 2009, 00:08:47
Poddaję się, nie mam bladego pojęcia jak naprawić błąd linkera. Wygląda jakby w statycznej bibliotece nie były zdeklarowane niektóre funkcje, jak np. CUIManager::AddWindow. Możliwe, że to wina starej wersji Visuala z 2003 roku?

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Marzec 06, 2009, 10:22:48
Nie wiem, a pokażesz jakiś kawałek kodu i te błędy?

Offline PoD

  • Użytkownik

# Marzec 06, 2009, 22:13:58
Myślałem, że to własnie przez mój "zły" kod, ale jednak nie, gdyż po nieudanej próbie użycia FUGE w projekcie, spróbowałem z pierwszym przykładowym kodem z dokumentacji. Efekt ten sam, czyli błędy linkowania.

Linking...
test.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class fuge::CWindow * __thiscall fuge::CUIManager::AddWindow(class fuge::CRect const &,class fuge::CElement *,unsigned short const *,int,int)" (__imp_?AddWindow@CUIManager@fuge@@QAEPAVCWindow@2@ABVCRect@2@PAVCElement@2@PBGHH@Z) referenced in function _WinMain@16
Debug/fuge_test.exe : fatal error LNK1120: 1 unresolved externals

Odwołuje się oczywiście do linii:
// Create a small window
       CWindow* wnd = ui->AddWindow (CRect (5, 5, 300, 200), null, L"Fuge Example");
Po jej wykomentowaniu jest ok, ale oczywiście nic mi po pustym okienku.

Zaobserwowałem podobne zjawisko dla wszystkich funkcji z serii "Dodaj element" i to chyba najbardziej boli, bo uniemożliwia korzystanie z biblioteki. Funkcje takie jak ToMultiByte można sobie samemu napisać.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Marzec 06, 2009, 22:18:58
Czyżbyś nie miał włączonego typu wchar_t?

Offline PoD

  • Użytkownik

# Marzec 07, 2009, 00:52:42
Zwracam honor, mój błąd. Wydawało mi się, że mam włączony, ale w praktyce przestawiłem Character Set na Unicode, ale zapomniałem o traktowaniu wchar_t jako domyślny typ znaku dla stringów.

Pierwsze wrażenia: biblioteka wydaję się fajna, mała i spójna. Zobaczymy jak się będzie edytory z tym pisało.

Dzięki, pzdr.

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Maj 04, 2010, 22:27:19
Ukończyłem wreszcie wersję 1.0 biblioteki. Tym razem jest dostępna jako open-source na licencji LGPL. Całkowicie nowej funkcjonalności nie ma dużo: pojawiły się okna modalne i z większych zmian to właściwie wszystko. Natomiast poprawionych zostało mnóstwo różnych drobiazgów, które utrudniały wykorzystanie biblioteki w praktyce, na przykład przełączanie Unicode/ANSI, obsługa błędów ładowania plików, automatyczne centrowanie message box-ów (i przycisków na nich) i dopasowywanie tekstu, możliwość ustawienia ikonki czy stylu obramowania okna tworzonego przez Fuge. Dodałem trochę rzeczy przydatnych dla osób, które chciałyby wykorzystać Fuge jako swój podstawowy framework do stworzenia gry 2D, w tym wirtualne timery i klasę CImageList. Do tego oczywiście dużo poprawionych błędów mniejszych i większych oraz uzupełniona dokumentacja.

Mam nadzieję, że biblioteka przyda się paru osobom do stworzenia czegoś fajnego oraz że pojawią się jakieś sugestie - co jeszcze można by ulepszyć albo dopisać nowego.

http://darkcult.nazwa.pl/download/fuge-1.0.rar
« Ostatnia zmiana: Sierpień 20, 2010, 03:39:38 wysłana przez Złośliwiec »

Offline Złośliwiec

  • Użytkownik
    • Dark Cult

# Marzec 20, 2011, 00:22:36
Wersja 1.17 jest już dostępna:

http://darkcult.nazwa.pl/download/fuge-1.17.rar

Najważniejszą nowością jest tryb edycji, pozwalający na wstawianie nowych kontrolek w czasie wykonania, zmianę ich pozycji, rozmiaru i podstawowych atrybutów. Stan GUI może być zapisany do pliku XML i później wczytany. Tryb edycji można włączać i wyłączać w dowolnym momencie, więc można z niego skorzystać na różne sposoby. Można napisać sobie edytor GUI (całe 16 linii kodu razem z klamrami i dyrektywami preprocesora :-)) jako osobny plik EXE albo dodać możliwość edycji bezpośrednio w grze, włączaną np. skrótem klawiszowym.

Oprócz tego oczywiście mnóstwo poprawek i ulepszeń, m.in. naprawiony jest słynny już błąd kompilacji na Viście i Seven (niezadeklarowane 'CLEARTYPE_QUALITY'), obsługiwany jest Alt+Tab w trybie pełnoekranowym, uproszczone tworzenie schematów kolorów, zoptymalizowany wbudowany renderer DirectX. Uaktualniłem też dokumentację, tutoriale i FAQ.

Offline Frondeus

  • Użytkownik

# Marzec 20, 2011, 17:57:30
fatal error C1083: Cannot open include file: '../Untitled/PBLib/PBLib.h': No such file or directory