简体   繁体   English

使用Android版NDK编写OpenGL代码

[英]using NDK for Android to write OpenGL code

So here is the deal. 所以这里是交易。 I have been using OpenGL API on windows [Win32] for about 3 years. 我已经在Windows [Win32]上使用OpenGL API大约3年了。 I have written multiple shaders in the same. 我在同一篇文章中编写了多个着色器。

Now I want to port my project on Android. 现在,我想在Android上移植我的项目。 My question is, If I want to write the project using C++ [NDK], and use OpenGL ES is it possible? 我的问题是,如果要使用C ++ [NDK]编写项目,并使用OpenGL ES,可以吗?

Short answer I got was 'YES', but, is that a right way? 我得到的简短答案是“是”,但这是正确的方法吗? Am I better off using Java? 我最好使用Java吗? Are there any performance degrade because I am using NDK, as I am aiming for a VR based OpenGL application performance is the main factor? 因为我基于基于VR的OpenGL应用程序性能是主要因素,所以我使用NDK是否会导致性能下降?

Yes its these are multiple questions, but they point at the similar problem, is it practical to use NDK for real-life projects. 是的,这是多个问题,但它们指向类似的问题,将NDK用于实际项目是否可行。

It is up to you how much of your application you write in C++ and how much you write in Java. 取决于您使用C ++编写多少应用程序以及使用Java编写多少代码。 Each JNI call has an associated overhead, so you may want to keep that in mind when decided how to split your Java and native code (for example, writing your entire render loop in C++ will incur just one JNI call per frame, while writing your render loop by calling the OpenGL API via the Java wrapper could incur thousands of JNI calls per frame). 每个JNI调用都有一个相关的开销,因此在决定如何拆分Java代码和本机代码时,您可能需要牢记这一点(例如,用C ++编写整个渲染循环将每帧只招致一个JNI调用,通过Java包装器调用OpenGL API进行渲染循环可能会导致每帧数千个JNI调用)。 What might be considered "correct" depends on your specific requirements. 什么可能是“正确的”取决于您的特定要求。

At a minimum, you will need to obtain either a Surface (from the SurfaceHolder that is provided by a SurfaceView ) or a SurfaceTexture (obtained from a TextureView ) and pass it via the JNI to your native application, where you can use ANativeWindow_fromSurface or ANativeWindow_fromSurfaceTexture (see here ) to obtain a native window with which you can create your OpenGL ES surface and context. 至少,你需要得到无论是Surface (从SurfaceHolder由一个提供SurfaceView )或SurfaceTexture (从获得TextureView ),并通过JNI传递到你的本地应用程序,在那里你可以使用ANativeWindow_fromSurfaceANativeWindow_fromSurfaceTexture (请参阅此处 )获得一个本机窗口,您可以使用该窗口创建OpenGL ES表面和上下文。 You will probably want to encapsulate your JNI calls within Java classes that listen to the SurfaceHolder or SurfaceTexture callbacks. 您可能希望将JNI调用封装在侦听SurfaceHolderSurfaceTexture回调的Java类中。 For example: 例如:

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);
    }
};

If you don't need this level of control, you might consider using GLSurfaceView , which is a SurfaceView that manages its own OpenGL ES surface, context and render loop. 如果不需要此级别的控制,则可以考虑使用GLSurfaceView ,它是一个SurfaceView ,可以管理自己的OpenGL ES曲面,上下文和渲染循环。 The disadvantage of GLSurfaceView is that it unnecessarily couples a whole load of ostensibly unrelated things. GLSurfaceView的缺点是,它不必要地耦合了表面上无关的事物的整个负载。 Decoupling these functions is not only neater from the perspective of the single responsibility principle , it allows you to potentially perform your rendering in a separate thread (which will of course require synchronization with the UI thread, but may have performance benefits). 分离这些功能不仅从单一职责原则的角度来看更加整洁,而且还允许您潜在地在单独的线程中执行渲染(这当然需要与UI线程同步,但可能会带来性能上的好处)。

If you don't even care about any of your application running Java-side, you can use the NativeActivity convenience class, which bundles all of the previously mentioned functions as well as some other stuff into an Android Activity. 如果您甚至不关心在Java端运行的任何应用程序,则可以使用NativeActivity便利类,该类将前面提到的所有功能以及其他一些东西捆绑到Android Activity中。 It's the quick and dirty option. 这是快速而肮脏的选择。

The short answer is yes, you can use NDK for real-life projects. 简短的答案是,可以将NDK用于实际项目。 If you use NativeActivity, you can have an app with no Java code at all. 如果您使用NativeActivity,则可以拥有一个完全没有Java代码的应用程序。 Many games are built with Unity engine and have all OpenGL done in C++ with no performance complaints. 许多游戏都是使用Unity引擎构建的,并且所有OpenGL都是以C ++编写的,没有任何性能抱怨。 Actually, the opposite is true , but in real life the performance penalty of Java-to-GL wrapper is pretty low. 实际上, 事实恰恰相反 ,但是在现实生活中,Java到GL包装器的性能损失非常低。

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

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