Creating OpenGL Shaders in NativeActivity

I modified the active activity NDK sample to include the OpenGL code from the hello-gl2 example. I process the APP_CMD_INIT_WINDOW message and then try to create shaders. Creating a shader fails, and I'm trying to get the information through getShaderInfoiv, but that doesn't work either.

So my question is: how can I create an OpenGL ES 2.0 shader in a pure native Android application?

PS I know that creating a shader can fail if you use Java GLSurfaceView and do not create them in the correct thread, but looking at a sample of its own activity, it only has one thread!

+6
source share
2 answers

Of course, you can create an OpenGL ES 2.0 shader in an Android application. The main thing is to use the correct OpenGL ES 2.0 context. I did something similar in my application, namely, initialized the EGL context in my own part, and then created (and used) shaders only in my own code. Based on what I was able to do, I assume that what you want to do is also quite possible.

Since I had an entry point to Java code (did not use the NativeAcvity mechanism), I also had to pass my own window handle ( EGLNativeWindowType ) from java to C ++ to create an EGL surface in my own code. However, since you just want to modify the NativeActivity example, you can use engine->app->window to create an EGL surface, as shown in the NativeActivity main.c example.

OK, how to create the correct OpenGL ES 2.0 context in native code? I just made two changes to the main.c file in the NativeActivity sample and checked its operation.

First, the following EGL attributes were used.

 const EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //important EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; 

in eglChooseConfig(display, attribs, &config, 1, &numConfigs); .

Secondly, later in context creation it is used

 const EGLint attrib_list [] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; 

in context = eglCreateContext(display, config, NULL, attrib_list);

I left the rest of the code unchanged. I printed some information to make sure OpenGL ES 2.0 is used:

 I/native-activity( 955): Details: [Version: OpenGL ES 2.0 1403843], [Vendor: Qualcomm], [Renderer: Adreno 205], [Extensions: GL_AMD_compressed_3DC_texture GL_AMD_compressed_ATC_texture ... ] 

Hope this helps!

+12
source

I wonder why you decided to switch to a complete Native solution, usually what you do is to save only your “heavy component”, such as your rendering engine, AI engine, physics engine, and you save "Device Level" to the Java part.

Thus, portability is a huge advantage. If you build everything in the NDK, you will have to reinvent the wheel if you want to move your game / program to Iphone, and if you keep the “core” in C and additional layers in Java, you will only have to rewrite the easy part of the problem.

In such solutions, I have a lot of experience, since my 3D engine (PATRIA 3D) is built on my own code, which can be ported from Android NDK to Iphone Objective-C (plus Windows / Linux / Mac OSx). In the end, my code is fully compatible with C89 + OpenGL2.0, which can be compiled directly (with minor modifications) on Android (using android ndk-build) and Iphone (XCODE).

Following this approach, the engine and execute the actual drawing on the same thread, let me call it the main thread.

If you need multiple threads in an application:

A - Keep the drawing on the main (main) B - Create new threads in Java, do not do this in C (when porting to another platform, you create multithreading at a new level)

For shaders, the solution in this way is very simple, since the surface and init of OpenGL is executed by Java using the standard EGL library.

Believe me, if you can write once and use it on both Android and Iphone platforms, you double the number of “customers”, this is something you cannot ignore, it can potentially double your income.

Hope this helps in some way.

+3
source

Source: https://habr.com/ru/post/905357/


All Articles