2012-01-06 5 views
6

He modificado la muestra NDK de actividad nativa para incorporar el código OpenGL del ejemplo hello-gl2. Manejo el mensaje APP_CMD_INIT_WINDOW y luego intento crear los sombreadores. La creación del sombreador falla y trato de obtener información a través de getShaderInfoiv, pero eso también falla silenciosamente.Creación de sombreadores OpenGL en NativeActivity

Así que mi pregunta es: ¿cómo puedo crear un sombreador OpenGL ES 2.0 en una aplicación nativa pura de Android?

P.S. Sé que la creación de sombreadores puede fallar si usa Java GLSurfaceView y no los crea en el hilo correcto, pero al mirar la muestra de actividad nativa, ¡parece que solo tiene un hilo!

+0

Disculpa la pregunta posiblemente inútil pero, ¿iniciaste EGL de alguna manera? Creo que el motor OpenGL no está listo para recibir sus solicitudes (eso podría explicar el error silencioso de la llamada getShaderInfoiv). En caso, ¿está cargada la biblioteca OGL 2.0? –

+0

Hola, sí EGL se inicializó –

+0

Sin experiencia en el desarrollo de OpenGL nativo, supongo que el siguiente ejemplo de actividad nativa te deja con el contexto de OpenGL ES 1.0. En el ejemplo de hello-gl2, la elección de la configuración de OpenGL ES 2.0 se realiza dentro del código de Java. – harism

Respuesta

12

Sin duda, es posible crear un sombreador OpenGL ES 2.0 en una aplicación nativa de Android. La clave es usar el contexto adecuado de OpenGL ES 2.0. Hice algo similar en mi aplicación, a saber, el contexto EGL inicializado en la parte nativa y luego creé (y usé) sombreadores solo en el código nativo. Basado en lo que logré hacer, supongo que lo que quieres hacer también es perfectamente posible.

Como tenía un punto de entrada en el código Java (no usé el mecanismo NativeAcvity) también tuve que pasar el identificador de ventana nativo (EGLNativeWindowType) de java a C++ para crear una superficie EGL en código nativo. Sin embargo, dado que simplemente quiere modificar el ejemplo de NativeActivity, puede usar engine->app->window para crear una superficie EGL tal como se presenta en la muestra NativeActivity main.c.

Bien, ¿cómo crear el contexto apropiado de OpenGL ES 2.0 en el código nativo?Acabo de hacer dos cambios en el archivo main.c en la muestra NativeActivity y comprueve que funcionó.

En primer lugar, utiliza los siguientes atributos de 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 
}; 

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

En segundo lugar, más tarde en la creación de contexto utilizado

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

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

Salí del resto del código sin cambios. Imprimí algo de información para asegurarse de que OpenGL ES 2.0 está siendo utilizado:

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

espero que ayude!

+0

Gracias - eso suena exactamente lo que estoy buscando. Verificaré cuando llegue a casa. –

+0

Esos 2 cambios lo clavaron. ¡Gracias! –

+1

¡Me alegro de poder ayudar! Solo lamento haber escrito la respuesta tan tarde que no recibí la recompensa;) – youri

3

Me pregunto por qué decidiste ir a una solución nativa completa, generalmente lo que haces es mantener "nativo" solo tu "componente pesado" como tu motor de renderizado, el motor AI, el motor de física y mantienes el "Device layer" hasta la parte de Java.

De esta manera, la gran ventaja es la portabilidad. Si construyes todo en NDK, entonces tienes que reinventar la rueda si quieres mover tu juego/programa a Iphone, mientras que si mantienes el "núcleo" en C y las capas adicionales en Java, tendrás que reescribir solo la parte fácil del problema

En este tipo de soluciones, tengo una amplia experiencia ya que mi motor 3D (PATRIA 3D) se basa en código nativo que se puede cruzar desde Android NDK a Iphone Objective C (más Windows/Linux/Mac OSx). Al final del día, mi código es un C89 + OpenGL2.0 completamente compatible que se puede compilar directamente (con pequeños cambios) en Android (usando android ndk-build) y Iphone (XCODE).

Siguiendo este enfoque, el motor y realizar el dibujo real en el mismo hilo, permítanme llamarlo el hilo principal.

Si necesita múltiples hilos en su aplicación:

A - Mantener el dibujo, por un principal (el principal) B - Crear los nuevos temas en Java, no lo haga en C (cuando se puerto a otra plataforma, usted construye el multi-threading en la nueva capa)

En cuanto a los sombreadores, la solución de esta manera es muy directa ya que la superficie y el inicio de OpenGL se realiza mediante Java utilizando la biblioteca EGL estándar .

Créame, si puede escribir una vez y utilizar en ambas plataformas, Android y Iphone, duplica los números de "clientes", es algo que no puede ignorar, podría duplicar sus ganancias.

Espero que esto ayude de alguna manera.

+0

Parece ser una publicación muy buena, pero no entiendo la parte de enhebrado, ¿qué pasaría si utilizara C++ 11, que puede usar múltiples hilos, podría estar bien utilizar la solución nativa completa? Debido a que estoy usando el motor personal de C++ con las interfaces de Java (pongo todas las texturas en Java), no es limpio. – Sung

Cuestiones relacionadas