繁体   English   中英

使用Android版NDK编写OpenGL代码

[英]using NDK for Android to write OpenGL code

所以这里是交易。 我已经在Windows [Win32]上使用OpenGL API大约3年了。 我在同一篇文章中编写了多个着色器。

现在,我想在Android上移植我的项目。 我的问题是,如果要使用C ++ [NDK]编写项目,并使用OpenGL ES,可以吗?

我得到的简短答案是“是”,但这是正确的方法吗? 我最好使用Java吗? 因为我基于基于VR的OpenGL应用程序性能是主要因素,所以我使用NDK是否会导致性能下降?

是的,这是多个问题,但它们指向类似的问题,将NDK用于实际项目是否可行。

取决于您使用C ++编写多少应用程序以及使用Java编写多少代码。 每个JNI调用都有一个相关的开销,因此在决定如何拆分Java代码和本机代码时,您可能需要牢记这一点(例如,用C ++编写整个渲染循环将每帧只招致一个JNI调用,通过Java包装器调用OpenGL API进行渲染循环可能会导致每帧数千个JNI调用)。 什么可能是“正确的”取决于您的特定要求。

至少,你需要得到无论是Surface (从SurfaceHolder由一个提供SurfaceView )或SurfaceTexture (从获得TextureView ),并通过JNI传递到你的本地应用程序,在那里你可以使用ANativeWindow_fromSurfaceANativeWindow_fromSurfaceTexture (请参阅此处 )获得一个本机窗口,您可以使用该窗口创建OpenGL ES表面和上下文。 您可能希望将JNI调用封装在侦听SurfaceHolderSurfaceTexture回调的Java类中。 例如:

public class GlSurfaceHolder {
    private SurfaceHolder mSurfaceHolder;
    private SurfaceHolder.Callback mSurfaceHolderCallback;

    public GlSurfaceHolder(SurfaceHolder surfaceHolder) {
        mSurfaceHolder = surfaceHolder;
        mSurfaceHolderCallback = new SurfaceHolder.Callback() {
            // JNI calls in here
        }

        mSurfaceHolder.addCallback(mSurfaceHolderCallback);
    }
};

如果不需要此级别的控制,则可以考虑使用GLSurfaceView ,它是一个SurfaceView ,可以管理自己的OpenGL ES曲面,上下文和渲染循环。 GLSurfaceView的缺点是,它不必要地耦合了表面上无关的事物的整个负载。 分离这些功能不仅从单一职责原则的角度来看更加整洁,而且还允许您潜在地在单独的线程中执行渲染(这当然需要与UI线程同步,但可能会带来性能上的好处)。

如果您甚至不关心在Java端运行的任何应用程序,则可以使用NativeActivity便利类,该类将前面提到的所有功能以及其他一些东西捆绑到Android Activity中。 这是快速而肮脏的选择。

简短的答案是,可以将NDK用于实际项目。 如果您使用NativeActivity,则可以拥有一个完全没有Java代码的应用程序。 许多游戏都是使用Unity引擎构建的,并且所有OpenGL都是以C ++编写的,没有任何性能抱怨。 实际上, 事实恰恰相反 ,但是在现实生活中,Java到GL包装器的性能损失非常低。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM