Search code examples
c++android-ndkshaderglslesopengl-es-3.0

How to convert these OpenGL Shaders to OpenGL ES shaders for GLES3 for android NDK?


The following Shaders fail with a return of -1, when i try.

col_attr = glGetAttribLocation(prog, "v_col");

i tried different settings including switching ,

gl_FragColor

to

outColor

and

#version 300 es

to

#version 150 core

and many more, before i realized i'm completely lost and there are so many variables i dont know. i just need these simple shaders converted to something that works with GLESv3 for Android NDK in C++. All the help is highly appreciated. Thank you.

Original Vertex Shader

#version 150 core
in vec3 v_pos;
in vec4 v_col;
out vec4 color;
uniform mat4 projection;
uniform mat4 view;
void main(){
        color = v_col;                    
        gl_Position = projection * view * vec4(v_pos, 1.0);
}

Original Fragment Shader

#version 150 core
in vec4 color;
void main(){
            gl_FragColor = color;
}

Update: Found that only the Fragment Shader fails at compilation.

New Vertex Shader - Compiles!

return "#version 300 es                 \n"
       "in vec3 v_pos;                 \n"
       "in vec4 v_col;                 \n"
       "out vec4 color;                \n"
       "uniform mat4 projection;        \n"
       "uniform mat4 view;            \n"
       "void main()                    \n"
       "{                              \n"
       "   color = v_col;                \n"
       "   gl_Position = projection * view * vec4(v_pos, 1.0);   \n"
       "}                              \n";

New Fragment Shader - Doesn't Compile!

return "#version 300 es                 \n"
       "in vec4 color;                  \n"
       "out vec4 outColor;              \n"
       "void main()                     \n"
       "{                               \n"
       "   outColor = color;            \n"
       "}                               \n";

New Fragment Shader - Compiles!

return "#version 300 es                 \n"
        "precision mediump float;       \n"
       "in vec4 color;                  \n"
       "out vec4 outColor;              \n"
       "void main()                     \n"
       "{                               \n"
       "   outColor = color;            \n"
       "}                               \n";

Solution

  • You've to declare the fragment shader output variable out vec4 outColor.
    Further you've to add a precision qualifier:

    A valid GLSL ES 3.00 fragment shader would be:

    #version 300 es
    
    precision mediump float; 
    
    in vec4 color;
    out vec4 outColor;
    
    void main(){
        outColor = color;
    }
    

    The version information (#version 300 es) has to be changed in the vertex shader, too.

    See OpenGL ES Shading Language 3.00 Specification - 4.3.6 Output Variables page 42:

    Fragment outputs are declared as in the following examples:

    out vec4 FragmentColor;
    out uint Luminosity;
    

    See OpenGL ES Shading Language 3.00 Specification - 4.5.4 Default Precision Qualifiers page 56:

    The fragment language has no default precision qualifier for floating point types. Hence for float, floating point vector and matrix variable declarations, either the declaration must include a precision qualifier or the default float precision must have been previously declared.