Sample

Przykłady dotyczące rozszerzenia Android Game Development Extension pokazują, jak korzystać z kluczowych funkcji rozszerzenia. W tym temacie opisano przykłady i ustawienia potrzebne do ich uruchomienia.

Na stronie z plikami do pobrania dostępne są te przykłady:

  • HelloJNI: projekt wprowadzający.
  • Endless-Tunnel: projekt tylko na Androida.
  • Teapot: projekt wieloplatformowy na systemy Windows i Android.
  • AssemblyCode-Link-Objects: projekt szablonu z kodem źródłowym zestawu.

Zanim rozpoczniesz

  • Zainstaluj rozszerzenie Android Game Development Extension i próbki. Szczegółowe informacje znajdziesz w krótkim wprowadzeniu. Z tego tematu dowiesz się też, jak skompilować i uruchomić próbkę. Jako przykład posłuży nam wersja Teapot na Androida.

  • W przewodniku Konfiguracja projektu opisano, jak skonfigurować ustawienia projektu, który korzysta z rozszerzenia, np. dodać platformę Android i plik APK.

HelloJNI

Przykład HelloJNI to prosty projekt, który wyświetla komunikat „Hello From JNI” w oknie aplikacji. Projekt używa różnych zestawów kodu źródłowego na potrzeby systemu Windows i Androida.

  • Katalog kodu źródłowego Androida i skryptów kompilacji Gradle: HelloJNI\AndroidPackaging
  • Kod źródłowy systemu Windows i katalog projektu Visual Studio: HelloJNI

Podczas kompilowania projektu Visual Studio przekazuje do pliku build.gradle na poziomie aplikacji te ustawienia: Możesz zmienić te ustawienia, modyfikując skrypty kompilacji Gradle.

  • MSBUILD_NDK_VERSION
  • MSBUILD_MIN_SDK_VERSION
  • MSBUILD_JNI_LIBS_SRC_DIR
  • MSBUILD_ANDROID_OUTPUT_APK_NAME
  • MSBUILD_ANDROID_GRADLE_BUILD_OUTPUT_DIR

Aby skonfigurować i uruchomić przykład:

  1. W Visual Studio otwórz i skompiluj przykład HelloJNI.
  2. Dodaj platformę Android arm64-v8a. Więcej informacji znajdziesz w artykule Dodawanie platformy Android.
  3. Dodaj element pakietu APK na Androida do nowej platformy.
  4. Kompiluj projekt.
  5. Dodaj te platformy Androida, a potem do każdej z nich dodaj element APK Androida: Android-armeabi-v7a, Android-x86Android-x86_64.
  6. Zbuduj i uruchom przykład.

Endless-Tunnel

Plik Endless-Tunnel to gra na Androida, w której gracz zbiera białe sześciany, próbując dotrzeć do końca tunelu. Został on przeniesiony z przykładowego kodu OpenGL w repozytorium Android NDK na GitHubie. Plik próbny nie zawiera wersji gry na system Windows.

W pliku z próbką są już skonfigurowane ustawienia i platformy Android, więc możesz skompilować i uruchomić projekt w Visual Studio bez wprowadzania żadnych modyfikacji. Gdy otworzysz rozwiązanie, eksplorer rozwiązań wyświetli te moduły:

  • endless-tunnel: moduł aplikacji, który wyświetla logikę gry.
  • glm: zrzut repozytorium OpenGL Math, który jest tworzony jako biblioteka statyczna.
  • native_app_glue: opakowanie NDK, które komunikuje się z obiektem NativeActivity.

Czajniczek

Przykładowa aplikacja Czajnik wyświetla klasyczny czajnik renderowany za pomocą OpenGL ES i przeniesiony do rozszerzenia Android Game Development Extension, aby zademonstrować te funkcje:

  • Tworzenie projektu na wiele platform: możesz skompilować aplikację Teapot na Windowsa i Androida.
  • Używanie niestandardowego pakowania Androida: skrypty kompilacji Gradle zostały przeniesione do katalogu sampli, w którym znajduje się plik Teapot.sln.
  • niestandardowe konfiguracje Androida, które pokazują, jak używać Address Sanitizer (ASan) i Hardware Address Sanitizer (HWASan);

W przykładzie Teapot implementacja jest podzielona na kilka części, co jest typowe dla dużych aplikacji i gier wieloplatformowych:

  • GameApplication moduł: definiuje działania użytkownika i stany aplikacji, np. obracanie czajnika przez użytkownika lub aktualizowanie statystyk aplikacji.
  • Moduł GameEngine: implementuje podstawowy moduł renderowania.

Aby skonfigurować przykład i uruchomić go na urządzeniu z Androidem, zapoznaj się z krótkim przewodnikiem. Aby skonfigurować przykład i uruchomić go w systemie Windows:

  1. Zainstaluj GLEW:
    1. Pobierz i rozpakuj GLEW.
    2. Skopiuj pliki binarne z folderu $your-glew-directory\bin\Release\x64 do folderu %SystemRoot%\system32.
  2. Zainstaluj freeglut:
    1. Pobierz i rozpakuj freeglut.
    2. Skopiuj $your-freeglut-directory\bin\x86\freeglut.dll do %SystemRoot%\system32.
  3. Dodaj zależności projektu freeglut:
    1. Otwórz Teapot.sln w Visual Studio.
    2. W menu kliknij Debugowanie > x64 > Lokalny debuger Windows.
    3. Eksploratorze rozwiązań kliknij prawym przyciskiem myszy GameApplication i wybierz Właściwości > C/C++ > Ogólne > Dodatkowe katalogi include.
    4. Dodaj $your-freeglut-dir\include do ścieżki.
      Zrzut ekranu okna Dodatkowe katalogi do uwzględnienia
    5. Kliknij OK.
    6. Kliknij Linker > Ogólne > Dodatkowe katalogi bibliotek.
    7. Dodaj $your-freeglut-dir\lib\x64 do ścieżki. Zrzut ekranu przedstawiający okno Dodatkowe katalogi bibliotek
    8. Kliknij OK.
    9. Kliknij Linker > Ogólne > Dodatkowe katalogi bibliotek.
    10. Dodaj freeglut.lib do ścieżki.
    11. Kliknij OK.
  4. Dodaj zależności projektu GLEW:
    1. W panelu Eksplorator rozwiązania kliknij prawym przyciskiem myszy GameApplication i wybierz Właściwości > C/C++ > Ogólne > Dodatkowe katalogi include.
    2. Dodaj $your-glew-dir\include do ścieżki.
    3. Kliknij OK.
    4. Kliknij Linker > Ogólne > Dodatkowe katalogi bibliotek.
    5. Dodaj $your-glew-dir\lib\Release\x86 do ścieżki.
    6. Kliknij OK.
    7. Kliknij Linker > Ogólne > Dodatkowe katalogi bibliotek.
    8. Dodaj glew32.lib do ścieżki.
    9. Kliknij OK.
  5. Uruchom próbkę w Windowsie:
    1. Na pasku narzędzi Visual Studio kliknij przycisk uruchamiania Lokalny debuger Windowsa.
    2. Plik przykładowy powinien wyglądać tak:
      Zrzut ekranu pokazujący działanie przykładowej aplikacji Teapot w systemie Windows.

To projekt szablonowy, który pokazuje, jak wygenerować natywną bibliotekę Androida na podstawie kodu źródłowego w językach assembly i C/C++. Oto główne komponenty:

  • AssemblyCode-Link-Objects: główna natywna biblioteka Androida utworzona z kodu źródłowego C++ i asemblera.
  • StaticLib: pomocnicza statyczna biblioteka, która eksportuje funkcję from_static_lib_assembly_code_as.

Projekt obsługuje wiele architektur. Każda obsługiwana architektura ma własne pliki źródłowe, które implementują funkcje wyeksportowane z StaticLib. Pamiętaj, aby uwzględnić tylko pliki źródłowe zestawu dla platform, które budujesz. Ten projekt zawiera pliki assembly w kompilacji za pomocą niestandardowych narzędzi do kompilacji.

Aby skonfigurować i skompilować przykład:

  1. W Visual Studio sprawdź, czy niestandardowe narzędzia kompilacji są skonfigurowane pod kątem plików assembly:
    1. W eksploratorze rozwiązania kliknij prawym przyciskiem myszy plik zestawu i wybierz Właściwości. Spowoduje to otwarcie okna Właściwości dla pliku.
    2. Wybierz konfigurację i platformę, np. Wszystkie konfiguracje w przypadku Android-arm64-v8a.
    3. Upewnij się, że ustawienie Ogólne > Wyklucz z kompilacji ma wartość Nie.
    4. Sprawdź, czy w sekcji Ogólne > Typ elementu wybrana jest opcja Narzędzie do tworzenia niestandardowych.
    5. Jeśli chcesz zastosować zmiany, kliknij Zastosuj.
    6. Upewnij się, że w sekcji Właściwości konfiguracji > Niestandardowe narzędzia do kompilacji > Wiersz poleceń wybrana jest opcja $(AsToolExe) -o "$(IntDir)%(FileName).o" %(FullPath). NDK zawiera osobny asembler dla każdej architektury procesora i mapuje $(AsToolExe) na odpowiedni asembler. Ten przykład używa zestawu narzędzi NDK do kompilowania projektów na Androida na platformy x86 i x86_64. Jeśli chcesz używać yasm na platformie Android x86_64, użyj zamiast tego $(YasmToolExe).
    7. Upewnij się, że w sekcji Właściwości konfiguracji > Niestandardowe narzędzia kompilacji > Dane wyjściowe:$(IntDir)%(FileName).o Ten ciąg musi być uwzględniony w ustawieniu Wiersz polecenia.
    8. Upewnij się, że w sekcji Właściwości konfiguracji > Niestandardowe narzędzia kompilacji > Łącz obiekty:Yes.

    Na przykład ustawienia Android-arm64-v8a powinny wyglądać tak jak na tym zrzucie ekranu:

    Zrzut ekranu strony Usługa z informacjami o niestandardowych narzędziach do kompilacji
  2. Kompiluj projekt. Spowoduje to utworzenie pliku libAssmeblyCodeLinkObjects.so:
    1. Otwórz plik AssemblyCode-Link-Objects.sln.
    2. W menu kliknij Generuj > Utwórz rozwiązanie.
  3. Aby sprawdzić, czy funkcje zostały prawidłowo wyeksportowane do biblioteki Androida, użyj narzędzia NDK nm.exe:
    1. W wierszu poleceń przejdź do katalogu z przykładami.
    2. Otwórz lokalizację biblioteki Androida wygenerowaną przez kompilację. Domyślna lokalizacja jest podobna do $sample_dir\$solution_configuration\$solution_platform\$platform i $sample_dir\Debug\Android-arm64-v8a\arm64-v8a na platformie arm64-v8a.
    3. Sprawdź, czy sekcja eksportowanych symboli zawiera funkcje. W tym celu uruchom to polecenie:
        \ndk\toolschains\llvm\prebuilt\windows-x86_64\aarch64-linux-android\bin\nm.exe --defined-only \Debug\Android-arm64-v8a\arm64-v8a\libAssmeblyCodeLinkObjects.so

      W wyjściu powinna pojawić się lista symboli, która zawiera:

         T from_shared_object_assembly_code_as
         T from_static_lib_assembly_code_as

PoolAllocator

Plik PoolAllocator to aplikacja na Androida, która zawiera mechanizm alokacji pamięci oparty na puli i zapewniający bardzo wydajne przydzielanie bloków o stałym rozmiarze.

Przydziałca wstępnie przydziela całą pamięć podczas inicjalizacji za pomocą funkcji mmap. Wolne bloki są śledzone za pomocą połączonej listy. Przydzielanie pamięci to szybka operacja O(1), która zwraca początek połączonej listy, a odzyskiwanie pamięci to również operacja O(1), ponieważ dodaje blok do końca połączonej listy.

Przykład zawiera 2 konfiguracje rozwiązania do korzystania z HWASan.

  • HWASan: ta konfiguracja pokazuje najprostsze podejście do korzystania z HWASan z niestandardowymi przydziałami pamięci. Wewnętrzna implementacja przydziału pamięci jest zastąpiona wywołaniami malloc/free, które są automatycznie śledzone przez HWASan. Moduły przydzielania pamięci nie działają już jako moduły przydzielania na podstawie puli, ale HWASan może nadal pomagać w identyfikowaniu ważnych błędów związanych z pamięcią, takich jak use-after-free.

  • HWASan-Advanced: Ta konfiguracja pokazuje, jak w pełni zintegrować HWAS z niestandardowym alokatorem pamięci bez zmiany oryginalnego mechanizmu alokacji używanego przez alokator. Używa metod tagowania HWASan do oznaczania bloków pamięci w puli przydzielonej z góry, zaokrągla rozmiar bloku do minimalnego rozmiaru bloku wymaganego przez HWASan i resetuje tagi, gdy bloki są zwracane do puli.

Użyj konfiguracji HWASan, ponieważ jest ona prostsza i może pomóc w identyfikacji typowych błędów pamięci. Jeśli chcesz dowiedzieć się, jak działa HWASan, lub zachować wewnętrzną semantykę przydziału pamięci podczas korzystania z HWASan, zapoznaj się z implementacją konfiguracji HWASan-Advanced.