Создание шейдеров OpenGL в NativeActivity - PullRequest
6 голосов
/ 07 января 2012

Я настроил пример NDK для нативной активности, чтобы включить код OpenGL из примера hello-gl2.Я обрабатываю сообщение APP_CMD_INIT_WINDOW и затем пытаюсь создать шейдеры.Создание шейдера завершается неудачно, и я пытаюсь получить информацию через getShaderInfoiv, но это тоже происходит молча.

Итак, мой вопрос - как я могу создать шейдер OpenGL ES 2.0 в чистом родном приложении Android?

PS Я знаю, что создание шейдера может завершиться неудачей, если вы используете Java GLSurfaceView и не создаете их в правильном потоке, но, глядя на пример native-Activity, кажется, что он имеет только один поток!

Ответы [ 2 ]

12 голосов
/ 14 января 2012

Конечно, можно создать шейдер OpenGL ES 2.0 в собственном приложении Android. Ключевым моментом является использование правильного контекста OpenGL ES 2.0. Я сделал нечто подобное в своем приложении, а именно: инициализировал контекст EGL в нативной части, а затем создал (и использовал) шейдеры только в нативном коде. Исходя из того, что мне удалось сделать, я предполагаю, что то, что вы хотите сделать, также вполне возможно.

Поскольку у меня была точка входа в код Java (не использовался механизм NativeAcvity), мне также пришлось передать дескриптор собственного окна (EGLNativeWindowType) из Java в C ++, чтобы создать поверхность EGL в собственном коде. Однако, поскольку вы хотите просто изменить пример NativeActivity, вы можете использовать engine->app->window для создания поверхности EGL, как показано в примере NativeActivity main.c.

ОК, как создать надлежащий контекст OpenGL ES 2.0 в нативном коде? Я только что сделал два изменения в файле main.c в образце NativeActivity и проверил, как он работает.

Во-первых, использовались следующие атрибуты EGL

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
};

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

Во-вторых, позже при создании контекста использовали

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

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

Я оставил остальную часть кода без изменений. Я напечатал некоторую информацию, чтобы убедиться, что OpenGL ES 2.0 используется:

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 ... ]

Надеюсь, это поможет!

3 голосов
/ 11 января 2012

Интересно, почему вы решили перейти на полноценное решение Native, обычно вы оставляете «родным» только свой «тяжелый компонент», такой как движок рендеринга, движок ИИ, физический движок, и вы сохраняете «Уровень устройства "до Java-части.

Таким образом, огромное преимущество - это мобильность.Если вы все строите в NDK, вам придется заново изобретать колесо, если вы хотите переместить свою игру / программу на Iphone, в то время как если вы сохраните «ядро» в C и дополнительные слои в Java, вам придется переписывать тольколегкая часть проблемы.

В таких решениях у меня большой опыт, поскольку мой 3D-движок (PATRIA 3D) построен на собственном коде, который можно переносить с Android NDK на Iphone Objective C (плюс Windows)./ Linux / Mac OSx).В конце концов, мой код полностью совместим с C89 + OpenGL2.0, который можно скомпилировать прямо (с небольшими изменениями) на Android (с помощью android ndk-build) и Iphone (XCODE).

Следуя такому подходу, движок и фактическое рисование выполняются в одном и том же потоке, позвольте мне назвать его основным потоком.

Если вам нужно многопоточность в вашем приложении:

A - Сохранить рисунок на главном (основном) B - Создать новые потоки на Java, не делайте этого на C(когда вы портируете на другую платформу, вы создаете многопоточность на новом слое)

Что касается шейдеров, решение в этом направлении очень простое, поскольку поверхность и инициализация OpenGL выполняются Javaиспользуя стандартную библиотеку EGL.

Поверьте, если вы можете написать один раз и использовать на обеих платформах, Android и Iphone, вы удваиваете числа клиентов, это то, что вы не можете игнорировать, это может потенциально удвоить вашзаработок.

Надеюсь, это как-то поможет.

...