При начальной инициализации OpenGL ES для создания поверхности нужно вызвать eglCreateWindowSurface:
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);
Как получить этот самый win?
При вызове state->window получаю NULL.
Добрый день.
Никогда этого не делал, но пример можно посмотреть в сэмплах NDK (native-activity). Там все это реализовано.
eyenie, спасибо за подсказку. Почему-то на этот пример (native-activity) я не обратил внимания.
Это SurfaceHolder
Gordon
К сожалению, нет. SurfaceHolder используется лишь на стороне явы. EGL из NDK будет требовать объект Surface, преобразованный к ANativeWindow.
Сделать это можно двумя путями:
1- базироваться на NativeActivity и отправлять в eglCreateWindowSurface переданный по сообщению указатель на ANativeWindow.
2- базироваться на собственной ява-подушке, из своего surfaceCreated() делать holder.getSurface() и скармливать объект в native метод, где из получаемго jobject путем ANativeWindow_fromSurface() получать заветный указатель на ANativeWindow. И уже потом eglCreateWindowSurface() итд итп...
Можно сделать без зависимости от NativeActivity (это сразу снижает требования к ОС до Android 2.2).
Перечень полезных ссылок:
http://www.netmite.com/android/mydroid/donut/frameworks/base/core… i_EGLImpl.cpp
http://gitorious.org/android-eeepc/base/blobs/71b8a66f99ebfe60e90… ibagl/egl.cpp
http://www.java2s.com/Open-Source/Android/android-core/platform-f… Impl.java.htm
http://www.netmite.com/android/mydroid/frameworks/base/libs/ui/EG… aySurface.cpp
Пример реализации (в примере window_handle - это указатель jobject* на объект класса SurfaceView):
EGLSurface eglCreateWindowSurfaceAndroid (EGLDisplay egl_display, EGLConfig egl_config, const void* window_handle, EGLint format) { try { jobject view = ( jobject)window_handle; if ( !view) throw xtl::make_null_argument_exception ( "", "window"); //создание поверхности через JNI JNIEnv& env = syslib::android::get_env ( ); local_ref<jclass> egl_class = env.FindClass ( EGL_CLASS_NAME); local_ref<jclass> egl_config_class = env.FindClass ( EGL_CONFIG_CLASS_NAME); local_ref<jclass> egl_display_class = env.FindClass ( EGL_DISPLAY_CLASS_NAME); if ( !egl_class) throw xtl::format_operation_exception ( "", "EGLImpl class '%s' not found in JNI environment", EGL_CLASS_NAME); if ( !egl_config_class) throw xtl::format_operation_exception ( "", "EGLConfigImpl class '%s' not found in JNI environment", EGL_CONFIG_CLASS_NAME); if ( !egl_display_class) throw xtl::format_operation_exception ( "", "EGLDisplayImpl class '%s' not found in JNI environment", EGL_DISPLAY_CLASS_NAME); jmethodID egl_class_constructor = env.GetMethodID ( egl_class.get ( ), "<init>", "()V"); jmethodID egl_config_class_constructor = env.GetMethodID ( egl_config_class.get ( ), "<init>", "(I)V"); jmethodID egl_display_class_constructor = env.GetMethodID ( egl_display_class.get ( ), "<init>", "(I)V"); jmethodID egl_create_window_surface = env.GetMethodID ( egl_class.get ( ), "eglCreateWindowSurface", "(Ljavax/microedition/khronos/egl/EGLDisplay;Ljavax/microedition/khronos/egl/EGLConfig;Ljava/lang/Object;[I)Ljavax/microedition/khronos/egl/EGLSurface;"); if ( !egl_class_constructor) throw xtl::format_operation_exception ( "", "EGLImpl default constructor not found in class '%s'", EGL_CLASS_NAME); if ( !egl_config_class_constructor) throw xtl::format_operation_exception ( "", "EGLConfigImpl constructor not found in class '%s'", EGL_CONFIG_CLASS_NAME); if ( !egl_display_class_constructor) throw xtl::format_operation_exception ( "", "EGLDisplayImpl constructor not found in class '%s'", EGL_DISPLAY_CLASS_NAME); if ( !egl_create_window_surface) throw xtl::format_operation_exception ( "", "EGLImpl::eglCreateWindowSurface not found in class '%s'", EGL_CLASS_NAME); local_ref<jobject> egl = env.NewObject ( egl_class.get ( ), egl_class_constructor); if ( !egl) throw xtl::format_operation_exception ( "", "EGLImpl constructor failed"); local_ref<jobject> egl_config_wrapper = env.NewObject ( egl_config_class.get ( ), egl_config_class_constructor, egl_config); if ( !egl_config_wrapper) throw xtl::format_operation_exception ( "", "EGLConfigImpl constructor failed"); local_ref<jobject> egl_display_wrapper = env.NewObject ( egl_display_class.get ( ), egl_display_class_constructor, egl_display); if ( !egl_display_wrapper) throw xtl::format_operation_exception ( "", "EGLDisplayImpl constructor failed"); local_ref<jobject> egl_surface_wrapper = env.CallObjectMethod ( egl.get ( ), egl_create_window_surface, egl_display_wrapper.get ( ), egl_config_wrapper.get ( ), view, 0); if ( !egl_surface_wrapper) throw xtl::format_operation_exception ( "", "EGLImpl::eglCreateWindowSurface failed"); local_ref<jclass> egl_surface_class = env.GetObjectClass ( egl_surface_wrapper.get ( )); if ( !egl_surface_class) throw xtl::format_operation_exception ( "", "JNIEnv::GetObjectClass failed (for EGLSurfaceImpl)"); jfieldID egl_surface_field = env.GetFieldID ( egl_surface_class.get ( ), "mEGLSurface", "I"); if ( !egl_surface_field) throw xtl::format_operation_exception ( "", "Field 'mEGLSurface' not found for EGLSurfaceImpl"); return ( EGLSurface)env.GetIntField ( egl_surface_wrapper.get ( ), egl_surface_field); } catch ( xtl::exception& e) { e.touch ( "render::low_level::opengl::egl::eglCreateWindowSurfaceAndroid"); throw; } }
Тема в архиве.