Search code examples
androidkotlinopengl-esglslshader

Kotlin/Android/OpenGL ES: Cannot implement 3D Lighting using normals. Wanted index: 4294967295. Max index: 16


I'm trying to implement 3d Lighting on a model using OpenGL ES. I followed this guide https://arm-software.github.io/opengl-es-sdk-for-android/lighting.html, but I cannot figure out why I keep getting this error : Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16.

Both coordinates and norms are Float array of size 9 which are later cast to floatBuffers. When I just want to draw shape everything works (therefore vertexBuffer is probably ok), but when I try to use norms everything breaks down.

I would really appreciate any help with this problem.

Buffers creation:

    private var vertexBuffer: FloatBuffer =
        ByteBuffer.allocateDirect(triangleCoordinates.size * 4).run {
            order(ByteOrder.nativeOrder())
            asFloatBuffer().apply {
                put(triangleCoordinates)
                position(0)
            }
        }


    private var normalsBuffer: FloatBuffer =
        ByteBuffer.allocateDirect(normals.size * 4).run {
            order(ByteOrder.nativeOrder())
            asFloatBuffer().apply {
                put(normals)
                position(0)
            }
        }

vertex Shader Code

private val vertexShaderCode =
        "attribute vec4 vertexPosition;\n" +
                "attribute vec3 vertexColour;\n" +
                "attribute vec3 vertexNormal;\n" +
                "varying vec3 fragColour;\n" +
                "uniform mat4 modelView;\n" +
                "void main(){\n" +
                /* [Setup scene vectors.] */
                "    vec3 transformedVertexNormal = normalize((modelView * vec4(vertexNormal, 0.0)).xyz);" +
                "    vec3 inverseLightDirection = normalize(vec3(0.0, 1.0, 1.0));\n" +
                "    fragColour = vec3(0.0);\n" +
                /* [Setup scene vectors.] */
                "\n" +
                /* [Calculate the diffuse component.] */
                "    vec3 diffuseLightIntensity = vec3(1.0, 1.0, 1.0);\n" +
                "    vec3 vertexDiffuseReflectionConstant = vertexColour;\n" +
                "    float normalDotLight = max(0.0, dot(transformedVertexNormal, inverseLightDirection));\n" +
                "    fragColour += normalDotLight * vertexDiffuseReflectionConstant * diffuseLightIntensity;\n" +

                "    /* Make sure the fragment colour is between 0 and 1. */" +
                "    clamp(fragColour, 0.0, 1.0);\n" +
                "\n" +
                "    gl_Position = modelView * vertexPosition;\n" +
                "}\n";```


Fragment shader:

private val fragmentShaderCode =
        "precision mediump float;" +
                "uniform vec4 vertexColour;" +
                "void main() {" +
                "  gl_FragColor = vertexColour;" +
                "}"

Drawing code:

fun draw(mvpMatrix: FloatArray) {

        positionHandle = glGetAttribLocation(program, "vertexPosition")
        vertexNormalLocation = glGetAttribLocation(program, "vertexNormal")

        mColorHandle = glGetUniformLocation(program, "vertexColour").also { colorHandle ->
            glUniform4fv(colorHandle, 1, color, 0)
        }

        vPMatrixHandle = glGetUniformLocation(program, "modelView")
        glUniformMatrix4fv(vPMatrixHandle, 1, false, mvpMatrix, 0)

        glUseProgram(program)

        glVertexAttribPointer(
            positionHandle,
            3,
            GLES20.GL_FLOAT,
            false,
            vertexStride,
            vertexBuffer
        )

        glVertexAttribPointer(
            vertexNormalLocation,
            3,
            GL_FLOAT,
            false,
            0,
            normalsBuffer
        )

        glEnableVertexAttribArray(positionHandle)
        glEnableVertexAttribArray(vertexNormalLocation)


        glDrawArrays(GL_TRIANGLES, 0, vertexCount)
        glDisableVertexAttribArray(positionHandle)
    }

Error mgs:

2021-09-19 13:41:59.783 19419-19472/com.example.druggame E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glVertexAttribPointer:637 GL error 0x501
    Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16
2021-09-19 13:41:59.783 19419-19472/com.example.druggame E/emuglGLESv2_enc: device/generic/goldfish-opengl/system/GLESv2_enc/GL2Encoder.cpp:s_glEnableVertexAttribArray:1028 GL error 0x501
    Info: Invalid vertex attribute index. Wanted index: 4294967295. Max index: 16

Solution

  • 4294967295 is hexadecimal ffffffff respectively -1. glGetAttribLocation returns this value if an attribute resource does not exist in the liked program. You get this value, because one of the attribute is not an active program resource.
    If an attribute is not used (directly or indirectly), it is optimized by the shader compiler or linker and is not given an attribute index.

    In your case the attributes have no attribute indes, because the vertex shader output fragColour is not an input to the fragment shader. Use fragColour in the fragment shader:

    precision mediump float;
    
    varying vec3 fragColour;
    
    void main() 
    {
        gl_FragColor = vec4(fragColour, 1.0);
    }