wtorek, 10 lipca 2007

AGE Accelerated

Po pierwsze - rozważania z poprzedniego posta zakończyłem. Zdecydowałem się narazie na używanie ID3DXSprite i zupełne olanie rysowania prostokątów :)

Teraz do rzeczy. Ostatnio zauważyłem, że wydajność mojego silniczka straszliwie spadła - podczas rysowania 1000 spritów wcześniej miałem 350 FPS, a teraz 120 FPS....

Winowajcą okazało się pewne ustawienie D3DPRESENT_PARAMETERS. Otóż problematyczne okazały się pola: EnableAutoDepthStencil wraz z AutoDepthStencilFormat tej struktury. Po ustawieniu EnableAutoDepthStencil na false okazało się że FPS zwiększyło się ze 3 razy :)

Pomijam już fakt, że kiedy włączę pełny ekran to FPS zwiększa się jeszcze bardziej. Taka wydajność na razie wystarczy żeby kodzić niewielkie gierki, ale co jeśli zechce zaimplementować particle engine? Cóż. o tym pomyśli się później :)

Bitwy wydajnościowe

Dzisiaj zdążyłem przetestować już kilka sposobów renderowania w celu sprawdzenia który byłby najlepszy [czyt: najszybszy]. Mam 3 kandydatów:

  • Można użyć D3DXSprite do rysowania co jest bardzo wygodne, ale problem pojawia się z wywołaniami Begin() i End(). Wywoływanie ich przy rysowaniu każdego pojedynczego sprita jest BARDZO niewydajne :) Koncept więc jest taki, żeby wywoływać je na początku i na końcu sceny. Ok. Tak może być. Oczywiście przed narysowaniem tekstu lub linii trzebaby wywołać metodę Flush() bo inaczej znajdą się one za wszystkimi spritami, a nie tam gdzie powinny. Ale co jeśli będę chciał narysować wypełniony kolorem prostokąt? Można użyć metody ColorFill() z IDirect3DDevice9, ale to jest równie wydajne co kupowanie jabłek po jednym i przynoszenie każdego do domu. Z kolei jeśli użyję DrawPrimitiveUP() to jeśli nie wywołam Flush() to oczywiście prostokąt rysowany jest za spritami, a jeżeli ją wywołam to prostokąt w ogóle nie jest rysowany!
  • Drugi sposób na rysowanie to użycie vertex bufferów. Niby dobry sposób, ale jak będę chciał zmienić którykolwiek z wierzchołków to trzeba użyć dość wolnego Lock()'a...
  • Trzeci sposób to rysowanie wszystkiego za pomocą DrawPrimitiveUP() problem w tym, ze wszystkie transformacje wierzchołków musiałbym robić na własną rękę co też mogłoby być średnio wydajne ;)
Podsumowując - nie ma złotego środka. No chyba że wymyślę jeszcze jakiś inny sposób albo dowiem się dlaczego DrawPrimitiveUP() nie działa po wywołaniu Flush()'a...

poniedziałek, 9 lipca 2007

AGE: po[d]stępy

Uff dzisiaj cały dzień się trudziłem z przywracaniem urządzenia D3DDevice w celu umożliwienia zmiany trybu graficznego i przełączania pomiędzy pełnym ekranem a oknem. Później stwierdziłem, że jak już pełny ekran to trzeba się też uporać z przestraszliwym ALT-TABem ;) Początkowo miałem pewne problemy, ale poczytałem trochę i zniknęły :)

Dodatkowo poprawiłem też funkcje wejścia klawiatury i myszki. Po drodze zakodziłem je jeszcze w Direct Input, ponieważ miałem pewne problemy z pozycją kursora na pełnym ekranie, ale wystarczyło tylko zmienić styl okna na WS_POPUP i już wszystko jest wporządku :) Dlatego też DInput poszedł się... w odstawkę. Powróciło stare dobre WinAPI ;)

Wnioski są 2:
- rozwiązanie jednego problemu od razu wpędza nas w drugi więc, jeśli założymy że zrobimy coś żeby mieć "z głowy" to może to być największy błąd naszego życia :)
- nie wszystko złoto co M$'a :P

niedziela, 8 lipca 2007

AGE-0.1: Final Countdown

Brzmi pięknie. Zupełnie jakbym już kończył :)

W pewnym sensie tak jest, ponieważ zaimplementowałem co chciałem i nawet da się na tym napisać grę. Rzecz w tym, że zanim wypuszczę wersję 0.1 czeka mnie jeszcze troche poprawiania niektórych rzeczy i małego przeorganizowania kodu. Jeżeli podczas najbliższego tygodnia mi się to nie znudzi to myślę, że AGE-0.1 będzie gotowe do tego czasu :)

sobota, 7 lipca 2007

Programowanie Toolsów ^^

Jako że kolizje są już skończone właśnie pomyślałem o tym, żeby stworzyć sobie własny format pliku z zapisanymi gotowymi punktami dla klasy ageBody reprezentującej obiekt kolizyjny. A jak własny format pliku to i własne narzędzie do tworzenia takich plików :)

Wychodząc z założenia że prostota przede wszystkim doszedłem do wniosku, że najlepiej będzie jeśli plik będzie się składał z 2 części:

  1. informacyjnej
  2. danych
W części informacyjnej wcisnę oczywiście nie mniej nie więcej tylko ilość punktów do wczytania, a w części danych - punkty :) Przypuszczam, że ten - jakże złożony - format pliku sprawdzi się najlepiej. Zresztą... co innego mógłbym w nim jeszcze zapisać? :P Jeśli kiedyś będzie mi się chciało pobawić w rozbudowaną fizykę, wtedy będzie trzeba dodać masę i inne śmieszne rzeczy, ale póki co - keep it simple :)

Collision Detection Finished

Wreszcie skończyłem prace nad detekcją kolizji pomiędzy obiektami. Myślałem, że to się nie zdarzy...

Tak czy inaczej AGE zostało wyposażone w prosty, szybki i skuteczny sposób na wykrywanie kolizjii metodą SAT. W tej chwili możliwe jest wykrywanie kolizji pomiędzy wszystkimi obiektami na scenie [ które wcześniej zostaną zarejestrowane w detektorze kolizji ] oraz prosty system umozliwiajacy definiowanie zachowania obu obiektow po zderzeniu.

piątek, 6 lipca 2007

Obija się!

Bazując na poście spidera, o którym pisałem poprzednio udało mi się napisać działającą funkcje rozpoznającą kolizje i wyznaczającą głębokość penetracji. Teraz dla podstawowego sprawdzania kolizji wystarczy napisać prostego managera kolizji i voilla!

Nie wierzyłem, że w ogóle mi się uda napisać te kolizje, ale wreszcie udało mi się to zrobić, a co najważniejsze - zrozumieć!