android ndk 上 OpenGLES 1.1 中具有 GLSurfaceView 模式的 FrameBuffers

在 Android NDK 中,是否可以使 OpenGL ES 1.1 与典型的 java 端 GLSurfaceView 模式(覆盖 GLSurfaceView.Renderer onDrawFrame、onSurfaceCreated 等的方法)一起工作,同时在 C++ 端使用框架、颜色和深度缓冲区和 VBO?

in Android NDK, is it possible to make OpenGL ES 1.1 work with the typical java-side GLSurfaceView pattern (overriding methods from GLSurfaceView.Renderer onDrawFrame, onSurfaceCreated, etc.) while using in the C++ side the frame, color and depth buffers, and VBO?

我正在尝试使用以下方法创建它们:

I am trying to create them using this:

void ES1Renderer::on_surface_created() {
    // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
    glGenFramebuffersOES(1, &defaultFramebuffer);
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);

    // Create color renderbuffer object.
    glGenRenderbuffersOES(1, &colorRenderbuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);

    // create depth renderbuffer object.
    glGenRenderbuffersOES(1, &depthRenderbuffer);
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer);
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
}

但是,这似乎没有正确获取上下文,我认为这是在初始化 GLSurfaceView 和渲染器时创建的(java 端).

However, it seems that this does not get the context appropriately, which is I think created when the GLSurfaceView and renderer are initialized (java side).

我不是 NDK 和 OpenGLES 方面的专家,但我必须移植一个使用 OpenGL ES 1.1 的 iOS 应用程序,我的目标是尽可能多地重用代码.由于该应用程序还利用了特定于平台的 UI 组件(按钮、列表等),在绘制 GL 图形时,我认为这将是最好的方法.但是,我现在正在考虑使用本机活动,尽管我不确定与其他 java 组件的关系.

I am no expert either on NDK nor OpenGLES, but I have to port an iOS app which is using OpenGL ES 1.1, and i aim to reuse as much code as i can. Since the app is also leveraging the platform-specific UI components (buttons, lists, etc.), while drawing GL graphics, I thought this would be the best way to go. However, I am now considering using a native activity, though I am not sure about what will be the relationship with the other java components.

推荐答案

当然,是的.标准方法是您创建一个 GLSurfaceView,就像在 Java 中使用 OpenGL 时一样,创建并连接您的 GLSurfaceView.Renderer 实现,然后启动渲染线程.

Absolutely, yes. The standard approach is that you create a GLSurfaceView like you would when using OpenGL from Java, create and hook up your GLSurfaceView.Renderer implementation, and let the rendering thread start up.

从您的 Renderer 方法,例如 onSurfaceCreated()onDrawFrame(),您现在可以调用 JNI 函数来调用您的本机代码.在这些原生函数中,您可以根据自己的意愿进行任何 OpenGL API 调用.例如,在您从 onSurfaceCreated() 调用的函数中,您可能会创建一些对象并设置一些初始状态.在您从 onSurfaceChanged() 调用的函数中,您可以设置视口和投影.在您从 onDrawFrame() 调用的函数中,您进行渲染.

From your Renderer methods, like onSurfaceCreated() and onDrawFrame(), you can now call the JNI functions that invoke functions in your native code. In those native functions, you can make any OpenGL API calls your heart desires. For example, in the function you call from onSurfaceCreated() you might create some objects and set up some initial state. In the function you call from onSurfaceChanged(), you might set up your viewport and projection. In the function you call from onDrawFrame(), you do your rendering.

您甚至可以从 Java 和本机代码进行 OpenGL 调用.Java OpenGL API 只是围绕原生函数的一个非常薄的层.函数是从本机代码调用还是通过 Java API 调用,这没有什么区别.

You can even make OpenGL calls from both Java and native code. The Java OpenGL API is just a very thin layer around the native functions. It doesn't make a difference if the functions are called from native code or through the Java API.

您唯一需要注意的是调用 all 您的本机代码,该代码从 onSurfaceCreated 的 GLSurfaceView.Renderer 实现调用 OpenGL API()onSurfaceChanged()onDrawFrame().调用这些方法时,您处于渲染线程中,并且拥有当前的 OpenGL 上下文.如果从其他任何地方调用原生 OpenGL 代码,则很可能是您在错误的线程中和/或您没有当前的 OpenGL 上下文.

The only thing you need to watch out for is that you invoke all your native code that makes OpenGL API calls from the GLSurfaceView.Renderer implementations of onSurfaceCreated(), onSurfaceChanged() and onDrawFrame(). When these methods are called, you are in the rendering thread, and have a current OpenGL context. If native OpenGL code is invoked from anywhere else, chances are that you are in the wrong thread and/or you do not have a current OpenGL context.

当然还有更复杂的设置,您可以在其中创建自己的 OpenGL 上下文,明确地将它们设为当前等.但我强烈建议您坚持使用上述简单方法,除非您有充分的理由需要更多内容.对于大多数标准的 OpenGL 渲染,我所描述的应该已经足够了.

There are of course more complex setups where you create your own OpenGL contexts, make them current explicitly, etc. But I would strongly recommend to stick with the simple approach above unless you have a very good reason why you need something more. For most standard OpenGL rendering, what I described should be perfectly sufficient.

相关文章