Мобильные платформыФорумОбщее

Android NDK - Инициализация OpenGL ES

#0
18:18, 2 мая 2012

При начальной инициализации OpenGL ES для создания поверхности нужно вызвать eglCreateWindowSurface:
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list);

Как получить этот самый win?
При вызове state->window получаю NULL.

#1
20:40, 3 мая 2012

Добрый день.
  Никогда этого не делал, но пример можно посмотреть в сэмплах NDK (native-activity). Там все это реализовано.

#2
5:08, 4 мая 2012

eyenie, спасибо за подсказку. Почему-то на этот пример (native-activity) я не обратил внимания.

#3
13:45, 13 мая 2012

Это SurfaceHolder

#4
22:24, 13 мая 2012

Gordon
К сожалению, нет. SurfaceHolder используется лишь на стороне явы. EGL из NDK будет требовать объект Surface, преобразованный к ANativeWindow.
Сделать это можно двумя путями:
1- базироваться на NativeActivity и отправлять в eglCreateWindowSurface переданный по сообщению указатель на ANativeWindow.
2- базироваться на собственной ява-подушке, из своего surfaceCreated() делать holder.getSurface() и скармливать объект в native метод, где из получаемго jobject путем ANativeWindow_fromSurface() получать заветный указатель на ANativeWindow. И уже потом eglCreateWindowSurface() итд итп...

#5
11:06, 20 мая 2012

Можно сделать без зависимости от 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;
  }
}
Мобильные платформыФорумОбщее

Тема в архиве.