Reputation: 697
So here is the deal. I have been using OpenGL API on windows [Win32] for about 3 years. I have written multiple shaders in the same.
Now I want to port my project on Android. My question is, If I want to write the project using C++ [NDK], and use OpenGL ES is it possible?
Short answer I got was 'YES', but, is that a right way? Am I better off using 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?
Yes its these are multiple questions, but they point at the similar problem, is it practical to use NDK for real-life projects.
Upvotes: 3
Views: 1924
Reputation: 10393
It is up to you how much of your application you write in C++ and how much you write in 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). 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. You will probably want to encapsulate your JNI calls within Java classes that listen to the SurfaceHolder
or SurfaceTexture
callbacks. 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. The disadvantage of GLSurfaceView
is that it unnecessarily couples a whole load of ostensibly unrelated things. 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).
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. It's the quick and dirty option.
Upvotes: 6
Reputation: 57173
The short answer is yes, you can use NDK for real-life projects. If you use NativeActivity, you can have an app with no Java code at all. Many games are built with Unity engine and have all OpenGL done in C++ with no performance complaints. Actually, the opposite is true, but in real life the performance penalty of Java-to-GL wrapper is pretty low.
Upvotes: 1