Opengl ES 3.0 shader functions unimplemented on Nexus 5/KitKat 4.4

3.5k views Asked by At

I'm having no luck using any of the OpenGL 3.0 shader functions on my Nexus 5 w/ KitKat 4.4, I get "called unimplemented opengl es api" for functions such as

glCreateProgram()
glShaderSource()
glCompileShader()

e.t.c. I am performing all calls whilst the OpenGL context is active. I can't imagine that these functions would not be implemented, so believe I must be doing something wrong! I have included the following

<GLES3/gl3.h>
<GLES2/gl2ext.h>
<GLES3/gl3platform.h>

and am using

-lGLESv3

in my LOCAL_LDLIBS. I noticed that in EGL/egl.h there is no EGL_OPENGL_ES3_BIT, so during context creation if I don't define EGL_RENDERABLE_TYPE, or if I use EGL_OPENGL_ES2_BIT, the results are the same.

A bit more info on where I am in case it helps: I'm porting my OpenGL game engine from Windows to Android using OpenGL ES 3.0 and the NDK. I have everything compiling ok with no errors, and have tested and verified that windowing, GL context management, Android lifecycle integration and the basic running of the engine works ok. I have a basic scene which simply activates the context, performs a glClearColour then swaps buffers, pulsating from black to red every second, and it works the same as it does on Windows.

Any help would be appreciated!

3

There are 3 answers

0
Rajveer On BEST ANSWER

Turns out I also had to use EGL_CONTEXT_CLIENT_VERSION when using eglCreateContext:

const EGLint attribs2[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
context = eglCreateContext(displayHandle, config, NULL, attribs2);
3
keaukraine On

It seems you are creating context incorrectly. To use OpenGL ES 3.0 in Android you have to create usual ES 2.0 context and then check version of created context. That's how I use it in my Java code and it work just fine.

More info: https://plus.google.com/109538161516040592207/posts/iJmTjpUfR5E

0
Toris On

All functions in the question are supported from OpenGL ES 2.0.

glCreateProgram()
glShaderSource()
glCompileShader()

EGL_CONTEXT_CLIENT_VERSION, 2 is enough for clearing "called unimplemented opengl es api" errors. So, I think the default version of ES on Nexus5 is less than 2 and it's the cause of this problem.

const EGLint attribs2[] = 
{
    EGL_CONTEXT_CLIENT_VERSION, 3, // ES 3.x
    // EGL_CONTEXT_CLIENT_VERSION, 2, // if you want to use ES 2.x
    EGL_NONE
};
context = eglCreateContext(displayHandle, config, EGL_NO_CONTEXT, attribs2);

Refs: glCreateProgram glShaderSource glCompileShader

With EGL_RENDERABLE_TYPE, we have EGL_OPENGL_ES3_BIT_KHR, which requires EGL 1.4. EGL_OPENGL_ES3_BIT_KHR is defined in EGL/eglext.h.

Include EGL/eglext.h

#include <EGL/egl.h>
#include <EGL/eglext.h>

#include <GLES3/gl3.h>

and pass EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR to eglChooseConfig()

const EGLint attribs1[] = 
{
    EGL_RED_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_BLUE_SIZE, 8,
    //EGL_ALPHA_SIZE, 8,
    //EGL_DEPTH_SIZE, 24, // if you want
    EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR, // ES 3.x
    EGL_NONE
};

GLES3/gl3platform.h is included by GLES3/gl3.h. GLES3/gl3.h contains most part of definitions in GLES2/gl2.h.

Ref: EGL_KHR_create_context

And link library depends on which ES version you want.

-lGLESv3

NB1: we can omit EGL_RENDERABLE_TYPE attribute for eglChooseConfig()

EGL_RENDERABLE_TYPE

a bitmask indicating which types of client API contexts the frame buffer configuration must support creating with eglCreateContext ... The default value is EGL_OPENGL_ES_BIT.

EGL_OPENGL_ES_BIT

Config supports creating OpenGL ES 1.0 and/or 1.1 contexts.

Sort rules of configurations which are returned by eglChooseConfig().

EGLConfigs are not sorted with respect to the attributes ... EGL_CONFORMANT, ... EGL_RENDERABLE_TYPE

So, I think having separate configurations depend on ES versions is rare but, eglChooseConfig() may return a configuration which supports ES 1.0/1.1 as a first one.

Ref: eglChooseConfig

From eglCreateContext() footnote

The requested attributes may not be able to be satisfied, but context creation may still succeed.

Ref: eglCreateContext

NB2: Creating ES 2.x context does not mean we can use it for ES 3.x.

I think device manufacturers don't want to implement EGL and ES version dependent functions, so eglCreateContext() with EGL_CONTEXT_CLIENT_VERSION, 2 may return a context which can be used with ES 3.x but it depends on fortune.

Not always but libGLESv3 is just a symbolic link of libGLESv2, on some devices, with some Android versions. It's linked as a temporal bug fix, in old days, and that brought us many version related confusions.

If source cord contains ES 3.x functions, and linked with libGLESv2, linker will complain about undefined references these days.