HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题
HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题 关于这个问题,我提问过:链接,但是问题还没解决。我在描述一下问题,如何在Flutter中使用OpenGL,我参考了在Flutter Android中使用外接纹理的方法,类似的代码在 OHOS 中并不工作。我发现 Flutter Android 中的
TextureRegistry、SurfaceTexture,在 OHOS中都有类的定义,
在上述 Java 代码中,glRender 核心实现是在 C++中完成的,关键代码是将 surfaceTexture
传入glRender 中,这个 surfaceTexture
在初始化OpenGL 的 eglCreateWindowSurface
函数中作为第三个参数,这个代码在 Android flutter 中是有效的,但是同样的代码在 OHOS 中不能工作,下面是 ArkTS 的代码:
onAttachedToEngine(binding: FlutterPluginBinding): void {
Log.e("EmuGLRenderPlugin", "EmuGLRenderPlugin onAttachedToEngine");
this.channel = new MethodChannel(binding.getBinaryMessenger(), "gl_render");
this.channel.setMethodCallHandler(this)
this.textureRegistry = binding.getTextureRegistry();
this.surfaceTexture = this.textureRegistry.createSurfaceTexture();
}
onMethodCall(call: MethodCall, result: MethodResult): void {
if (call.method == "makeFlutterTextureId") {
let surfaceId: number = this.surfaceTexture!.getSurfaceId()
let dataPtr: number = call.argument("share_data")
result.success(native.makeGL(surfaceId, dataPtr))
} else {
result.notImplemented()
}
}
在调用 native.makeGL(surfaceId, dataPtr)
的时候,主要是在创建 windows surface 的时候出错:0x300B EGL_BAD_NATIVE_WINDOW,C++ 部分的代码如下:
static int64_t initGL(int64_t surfaceId, int64_t dataPtr) {
s_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (s_eglDisplay == EGL_NO_DISPLAY) {
return -1;
}
EGLint version[2];
if (!eglInitialize(s_eglDisplay, &version[0], &version[1])) {
return -2;
}
EGLConfig eglConfig;
int64_t v = chooseEglConfig(eglConfig);
if (v != 1) {
return -3;
}
EGLint attribList[] = {
EGL_CONTEXT_CLIENT_VERSION, 3,
EGL_NONE
};
s_eglContext = eglCreateContext(s_eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList);
if (s_eglContext == EGL_NO_CONTEXT) {
EGLint error = eglGetError();
OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to create EGL context: %x", error);
return -4;
}
s_eglSurface = eglCreateWindowSurface(s_eglDisplay, eglConfig, (EGLNativeWindowType)surfaceId, nullptr);
if (s_eglSurface == EGL_NO_SURFACE) {
EGLint error = eglGetError();
OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to create window surface: %x", error);
return error;
}
return 0;
}
static int64_t chooseEglConfig(EGLConfig &config) {
EGLint configsCount;
EGLint configSpec[] = {
EGL_RENDERABLE_TYPE, 64,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_ALPHA_SIZE, 8,
EGL_DEPTH_SIZE, 16,
EGL_STENCIL_SIZE, 0,
EGL_SAMPLE_BUFFERS, 1,
EGL_SAMPLES, 4,
EGL_NONE
};
if (!eglChooseConfig(s_eglDisplay, configSpec, &config, 1, &configsCount)) {
EGLint error = eglGetError();
OH_LOG_Print(LOG_APP, LOG_ERROR, 0xFF00, "GL_NATIVE", "Failed to choose config: %x", error);
return error;
} else if (configsCount > 0) {
return 1;
}
return 0;
}
错误就发生在 eglCreateWindowSurface
,eglGetError
返回 EGL_BAD_NATIVE_WINDOW
,查看flutter 的 TextureRegistry
,这个surface 来自于 PixelMap
,但是用 eglCreatePixmapSurface
替换 eglCreateWindowSurface
又报错 0x3009 EGL_BAD_MATCH,但是上述代码在 Android 中是没有问题的,在 OHOS中创建这个 Surface 要如何做?
更多关于HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题的实战教程也可以访问 https://www.itying.com/category-92-b0.html
onAttachedToEngine(binding: FlutterPluginBinding): void { this.textureRegistry = binding.getTextureRegistry(); this.surfaceTexture = this.textureRegistry.registerTexture(this.textureRegistry.getTextureId(); // 得到 surfaceId let surfaceId: number = this.surfaceTexture.getSurfaceId(); }
// 然后在c++层通过surfaceId创建nativeWindow,之后就可以用opengl了 OHNativeWindow *nativeWindow = nullptr; OH_NativeWindow_CreateNativeWindowFromSurfaceId(surface_id, &nativeWindow); OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, SET_BUFFER_GEOMETRY, 360, 480);
更多关于HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
感谢回答,最近没注意看论坛,刚看到你的回答,按照你说的,我修改了相关代码,现在GL 能够初始化成功了,但是在每一帧渲染完成,我调用 eglSwapBuffers 的时候报错:EGL_BAD_ALLOC,类似的代码,在 android 上是OK的, flutter 使用 opengl 外接纹理和 android 是很类似的,ohos 的代码,基本上也是android 上的复制版。在看到你的回答之前,我已经通过 XComponent + PlatformView 的方式基本上解决了这个问题,在iOS 和 android 上正常使用 flutter 的外接 opengl 纹理,在 ohos 上封装一个XComponent的PlatformView,也能实现 opengl 的渲染。不过我还是希望能够和 iOS 与 android 保持一致,使用通用的代码,不知能够提供一个在ohos 上 flutter 使用 opengl 外接纹理的例子。
针对帖子标题“HarmonyOS 鸿蒙Next Flutter OHOS 通过外接纹理使用 OpenGL 的问题”,以下是专业且简洁的回答:
在HarmonyOS鸿蒙系统中,当使用Flutter框架并希望通过外接纹理(External Texture)集成OpenGL时,需确保几个关键点:
-
纹理创建与绑定:首先,在OpenGL中创建纹理对象,并绑定到当前渲染上下文。这通常涉及生成纹理ID、分配纹理内存以及设置纹理参数。
-
Flutter平台通道:利用Flutter的平台通道(Platform Channel)机制,将OpenGL纹理ID或其他必要信息传递给Flutter层。这允许Flutter应用与原生代码进行通信。
-
纹理更新与渲染:在Flutter中,使用
Texture
widget来显示来自OpenGL的纹理。确保在OpenGL中正确更新纹理内容,并通知Flutter层进行渲染。 -
同步与性能:注意OpenGL与Flutter渲染管道之间的同步问题,以避免潜在的渲染错误或性能瓶颈。
-
错误处理:检查OpenGL错误码和Flutter日志,以快速定位并解决问题。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html 。这将提供进一步的帮助和支持。