Kotlin/Android/OpenGL ES:无法使用法线实现 3D 光照。通缉指数:4294967295。最大指数:16

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

我正在尝试使用 OpenGL ES 在模型上实现 3d 光照。我遵循了本指南 https://arm-software.github.io/opengl-es-sdk-for-android/lighting.html,但我不明白为什么我一直收到此错误:信息:无效的顶点属性索引。通缉指数:4294967295 最大指数:16.

坐标和范数都是大小为 9 的 Float 数组,稍后将转换为 floatBuffers。当我只想绘制形状时,一切正常(因此 vertexBuffer 可能没问题),但是当我尝试使用规范时,一切都崩溃了。

对于解决此问题的任何帮助,我将不胜感激。

缓冲区创建:

    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)
            }
        }

顶点着色器代码

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";```


片段着色器:

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

绘图代码:

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)
    }

错误消息:

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

4294967295分别为十六进制ffffffff -1。 glGetAttribLocation returns 如果属性资源在喜欢的程序中不存在,则此值。你得到这个值,因为其中一个属性不是活动的程序资源。
如果某个属性未被使用(直接或间接),它会被着色器编译器或链接器优化,并且不会被赋予属性索引。

在您的情况下,属性没有属性索引,因为顶点着色器输出 fragColour 不是片段着色器的输入。在片段着色器中使用fragColour

precision mediump float;

varying vec3 fragColour;

void main() 
{
    gl_FragColor = vec4(fragColour, 1.0);
}