2012-01-06 16 views
6

Udało mi się zmodyfikować próbkę NDK o natywnej aktywności w celu włączenia kodu OpenGL z przykładu hello-gl2. Obsługuję komunikat APP_CMD_INIT_WINDOW, a następnie próbuję utworzyć moduły cieniujące. Tworzenie modułu cieniującego kończy się niepowodzeniem, a ja próbuję uzyskać informacje za pośrednictwem komendy getShaderInfoiv, ale to również nie działa poprawnie.Tworzenie modułów cieniujących OpenGL w NativeActivity

Moje pytanie brzmi - w jaki sposób mogę utworzyć moduł cieniujący OpenGL ES 2.0 w czystej, natywnej aplikacji dla systemu Android?

P.S. Wiem, że tworzenie shaderów może się nie powieść, jeśli używasz Java GLSurfaceView i nie tworzysz ich we właściwym wątku, ale patrząc na próbkę natywnej aktywności, wydaje się, że ma tylko jeden wątek!

+0

Przepraszamy za prawdopodobnie niepotrzebne pytanie, ale czy w jakiś sposób zainicjowałeś EGL? Wydaje mi się, że silnik OpenGL nie jest w ogóle gotowy do odbioru twoich żądań (może to wyjaśnić cichy błąd wywołania getShaderInfoiv). Na wypadek gdyby załadowano bibliotekę OGL 2.0? –

+0

Cześć, tak, EGL jest inicjalizowany –

+0

Bez doświadczenia w tworzeniu natywnego OpenGL, zgaduję, że po natywnym działaniu przykład pozostawia kontekst OpenGL ES 1.0. W przykładzie hello-gl2 wybór konfiguracji OpenGL ES 2.0 odbywa się za pomocą kodu Java. – harism

Odpowiedz

12

Z pewnością możliwe jest stworzenie modułu cieniującego OpenGL ES 2.0 w natywnej aplikacji Android. Kluczową sprawą jest użycie właściwego kontekstu OpenGL ES 2.0. Zrobiłem coś podobnego w mojej aplikacji, mianowicie zainicjowałem kontekst EGL w natywnej części, a następnie stworzył (i użyłem) shaderów tylko w natywnym kodzie. Na podstawie tego, co udało mi się zrobić, zakładam, że to, co chcesz zrobić, jest również całkowicie możliwe.

Ponieważ miałem punkt wejścia w kodzie Java (nie korzystałem z mechanizmu NativeAcvity) musiałem również przekazać macierzysty uchwyt okna (EGLNativeWindowType) z java do C++, aby utworzyć powierzchnię EGL w natywnym kodzie. Ponieważ jednak chcesz po prostu zmodyfikować przykład NativeActivity, możesz użyć engine->app->window do utworzenia powierzchni EGL na podstawie prezentowanej w NativeActivity main.c próbce.

OK, jak stworzyć właściwy kontekst OpenGL ES 2.0 w natywnym kodzie?Właśnie dokonałem dwóch zmian w pliku main.c w przykładzie NativeActivity i sprawdziłem, czy działa.

Po pierwsze, stosuje się następującą EGL atrybutów

const EGLint attribs[] = { 
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //important 
EGL_BLUE_SIZE, 8, 
EGL_GREEN_SIZE, 8, 
EGL_RED_SIZE, 8, 
EGL_NONE 
}; 

w eglChooseConfig(display, attribs, &config, 1, &numConfigs);.

drugie później tworzenia kontekstu, stosowane

const EGLint attrib_list [] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 

w context = eglCreateContext(display, config, NULL, attrib_list);

że lewy resztę zmiany kodu. Wydrukowałem pewne informacje, aby upewnić się, że OpenGL ES 2.0 jest używany:

I/native-activity( 955): Details: [Version: OpenGL ES 2.0 1403843], [Vendor: Qualcomm], [Renderer: Adreno 205], [Extensions: GL_AMD_compressed_3DC_texture GL_AMD_compressed_ATC_texture ... ] 

Mam nadzieję, że pomoże!

+0

Dzięki - to brzmi dokładnie to, czego szukam. Sprawdzę, kiedy wrócę do domu. –

+0

Te 2 zmiany przybili to. Dzięki! –

+1

Cieszę się, że mogę pomóc! Żałuję tylko, że tak późno napisałem odpowiedź, że nie dostałem nagrody;) – youri

3

Zastanawiam się, dlaczego zdecydowałeś się na pełne rozwiązanie Native, zwykle to, co robisz, to utrzymywanie "natywnego" tylko "ciężkiego komponentu", takiego jak silnik renderujący, silnik AI, silnik fizyki i trzymasz "Warstwa urządzenia" do części Java.

W ten sposób ogromną zaletą jest przenośność. Jeśli budujesz wszystko w NDK, musisz ponownie wymyślić koło, jeśli chcesz przenieść swoją grę/program do iPhone'a, a jeśli zachowasz "rdzeń" w C i dodatkowe warstwy w Javie, będziesz musiał przepisać tylko łatwa część problemu.

W tego rodzaju rozwiązaniach mam duże doświadczenie, ponieważ mój silnik 3D (PATRIA 3D) jest zbudowany na natywnym kodzie, który można przenosić z Android NDK na Iphone Objective C (plus Windows/Linux/Mac OSx). Pod koniec dnia mój kod jest w pełni zgodny z C89 + OpenGL2.0, który można kompilować prosto (z drobnymi zmianami) na Androida (za pomocą Android ndk-build) i Iphone (XCODE).

Postępując zgodnie z tym podejściem, silnik i wykonaj rzeczywisty rysunek w tym samym wątku, pozwól mi nazwać go głównym wątkiem.

Jeśli potrzebujesz wielo wątki w aplikacji:

A - zachować rysunek na głównej jednym (głównym) B - utworzyć nowe wątki w Javie, nie rób tego w C (kiedy port na inną platformę, budujesz wielowątkowość na nowej warstwie)

W odniesieniu do shaderów, rozwiązanie w ten sposób jest bardzo proste, ponieważ powierzchnia i inicjalizacja OpenGL jest wykonywana przez Javę przy użyciu standardowej biblioteki EGL .

Uwierz mi, jeśli możesz napisać raz i używać na obu platformach, Androida i iPhone'a, podwajasz liczbę "klientów", to jest coś, czego nie możesz zignorować, może potencjalnie podwoić zarobki.

Mam nadzieję, że to pomoże w pewien sposób.

+0

Wydaje się, że jest to bardzo dobry post, ale nie mam do czynienia z wątkiem, co jeśli użyłbym C++ 11, który może używać wielu wątków, może być w porządku, aby użyć pełnego natywnego rozwiązania? Ponieważ używam osobistego silnika C++ z interfejsami java (umieszczam wszystkie tekstury w Javie), to nie jest zadowalające. – Sung

Powiązane problemy