Android 索引大于GL#u MAX_VERTEX_ATTRIBS(而实际上它';低于硬件限制)

Android 索引大于GL#u MAX_VERTEX_ATTRIBS(而实际上它';低于硬件限制),android,opengl-es,Android,Opengl Es,我在手机上运行应用程序时遇到问题,而它在模拟器上运行正常。我在Android上使用OPENGLES 2.0,问题似乎出在OpenGL上。每次画框时,基本上都会重复以下错误: gles_state_set_error_internal:63: GLES error info:<program> could not be made part of current state. <program> is not linked GLES a_norm-1 gles_state_s

我在手机上运行应用程序时遇到问题,而它在模拟器上运行正常。我在Android上使用OPENGLES 2.0,问题似乎出在OpenGL上。每次画框时,基本上都会重复以下错误:

gles_state_set_error_internal:63: GLES error info:<program> could not be made part of current state. <program> is not linked GLES a_norm-1
gles_state_set_error_internal:62: GLES ctx: 0x7fa2596008, error code:0x502
gles_state_set_error_internal:63: GLES error info:<index> is greater than or equal to GL_MAX_VERTEX_ATTRIBS

对于模拟器,这是29,而对于我的真实手机,这是16。Ok 16较少,但正如您在我的着色器中所看到的,我只使用了3个属性,3问题在于片段着色器。不知怎的,手机中的硬件无法处理除以8的问题,它必须是8.0,这样它才能知道它是一个浮点数

public static final String fragmentLightTexture = "precision mediump float;"+
        "uniform vec3 u_LightPos;"+     // The position of the light in eye space.
        "uniform sampler2D s_Texture;"+ // The input texture.
        "varying vec3 v_Position;"+     // Interpolated position for this fragment
        "varying vec3 v_Normal;"+       // Interpolated normal for this fragment
        "varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
        "void main()"+
        "{"+
            "float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
            "vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
            "float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
            "diffuse = diffuse * (1.5 / (1.0 + (distance/8.0)));\n" + // Attenuation.
            "diffuse = diffuse + 0.2;" + // ambient light
            "gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
        "}";

我不得不说GL_MAX_VERTEX_ATTRIBS的错误消息一点帮助都没有,真的让我无法朝错误的方向进行搜索。

为什么不从第一条错误消息开始,而不是从第二条错误消息开始,后者说程序链接不正确?总是先调试第一个错误。。。后来的错误通常是早期错误传播的结果。回顾这一点,我明白这更能说明问题。它在仿真器上运行的事实让我认为程序是正确的,并且链接由于MAX_ATTRIBS而失败
  public static final String vertexLightTexture = "uniform mat4 u_MVPMatrix;"+  // A constant representing the combined model/view/projection matrix.
            "uniform mat4 u_MVMatrix;"+         // A constant representing the combined model/view matrix.
            "attribute vec4 a_Position;"+       // Per-vertex position information we will pass in.
            "attribute vec3 a_Normal;"+         // Per-vertex normal information we will pass in.
            "attribute vec2 a_TexCoordinate;"+  // Per-vertex texture coordinate information we will pass in.
            "varying vec3 v_Position;"+         // This will be passed into the fragment shader.
            "varying vec3 v_Normal;"+           // This will be passed into the fragment shader.
            "varying vec2 v_TexCoordinate;"+    // This will be passed into the fragment shader.
            "void main()"+
            "{"+
                "v_Position = vec3(u_MVMatrix * a_Position);"+ // Transform the vertex into eye space.
                "v_TexCoordinate = a_TexCoordinate;"+ // Pass through the texture coordinate.
                "v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));"+ // Transform the normal's orientation into eye space.
                "gl_Position = u_MVPMatrix * a_Position;"+ // regular position
            "}";

    public static final String fragmentLightTexture = "precision mediump float;"+
            "uniform vec3 u_LightPos;"+     // The position of the light in eye space.
            "uniform sampler2D s_Texture;"+ // The input texture.
            "varying vec3 v_Position;"+     // Interpolated position for this fragment
            "varying vec3 v_Normal;"+       // Interpolated normal for this fragment
            "varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
            "void main()"+
            "{"+
                "float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
                "vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
                "float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
                "diffuse = diffuse * (1.5 / (1.0 + (distance/8)));\n" + // Attenuation.
                "diffuse = diffuse + 0.2;" + // ambient light
                "gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
            "}";
int vertexShader = MyGLRenderer.loadShader(GLES20.GL_VERTEX_SHADER, Shaders.vertexLightTexture);
    int fragmentShader = MyGLRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,Shaders.fragmentLightTexture);
    // create empty OpenGL ES Program
    mProgram = GLES20.glCreateProgram();

    // add the vertex shader to program
    GLES20.glAttachShader(mProgram, vertexShader);

    // add the fragment shader to program
    GLES20.glAttachShader(mProgram, fragmentShader);

    // creates OpenGL ES program executables
    GLES20.glLinkProgram(mProgram);
 public void draw(float[] mvpMatrix, float[] mvMatrix, float[] lightPosition){
        // group all wall elements at once
        // Add program to OpenGL ES environment
        GLES20.glUseProgram(mProgram);

        // Get handle to shape's transformation matrix]
        int mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVPMatrix");
        System.err.println("GLES MVPMatrix" + mMVPMatrixHandle);
        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

        // Get handle to shape's transformation matrix]
        int mMVMatrixHandle = GLES20.glGetUniformLocation(mProgram, "u_MVMatrix");
        System.err.println("GLES MVMatrix" + mMVMatrixHandle);
        // Apply the view transformation
        GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mvMatrix, 0);

        // Get handle to textures locations
        int mSamplerLoc = GLES20.glGetUniformLocation(mProgram, "s_Texture");
        System.err.println("GLES s_tex" + mSamplerLoc);

        // Set the active texture unit to texture unit 0.
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

        // Bind the texture to this unit.
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);
        // Set the sampler texture unit to 0, where we have saved the texture.
        GLES20.glUniform1i(mSamplerLoc, 0);

        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "a_Position");
        System.err.println("GLES a_pos" + mPositionHandle);
        // Use the buffered data from GPU memory
        int vertexStride = COORDINATES_PER_VERTEX * 4;
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, positionBufferIndex);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, vertexStride, 0);

        // get handle to vertex shader's vPosition member
        int mNormalHandle = GLES20.glGetAttribLocation(mProgram, "a_Normal");
        System.err.println("GLES a_norm" + mNormalHandle);
        // Use the buffered data from GPU memory
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, normalBufferIndex);
        GLES20.glEnableVertexAttribArray(mNormalHandle);
        GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, vertexStride, 0);

        // Get handle to texture coordinates location
        int mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate" );
        System.err.println("GLES a_tex" + mTextureCoordinateHandle);
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, uvBufferIndex);
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false, 0, 0);
        // Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

        // Pass in the light position in eye space.
        int mLightPosHandle = GLES20.glGetUniformLocation(mProgram, "u_LightPos");
        System.err.println("GLES u_light" + mLightPosHandle);
        GLES20.glUniform3f(mLightPosHandle, lightPosition[0], lightPosition[1], lightPosition[2]);

        // Draw the Square
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBufferIndex);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,numberOfIndices,GLES20.GL_UNSIGNED_SHORT,0);
        // Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mNormalHandle);
        GLES20.glDisableVertexAttribArray(mTextureCoordinateHandle);
}
public static final String fragmentLightTexture = "precision mediump float;"+
        "uniform vec3 u_LightPos;"+     // The position of the light in eye space.
        "uniform sampler2D s_Texture;"+ // The input texture.
        "varying vec3 v_Position;"+     // Interpolated position for this fragment
        "varying vec3 v_Normal;"+       // Interpolated normal for this fragment
        "varying vec2 v_TexCoordinate;"+// Interpolated texture coordinate per fragment.\n" +
        "void main()"+
        "{"+
            "float distance = length(u_LightPos - v_Position);"+ // Will be used for attenuation
            "vec3 lightVector = normalize(u_LightPos - v_Position);" +// Get a lighting direction vector from the light to the vertex
            "float diffuse = max(dot(v_Normal, lightVector), 0.0);" + // dot product for the illumination angle.
            "diffuse = diffuse * (1.5 / (1.0 + (distance/8.0)));\n" + // Attenuation.
            "diffuse = diffuse + 0.2;" + // ambient light
            "gl_FragColor = (diffuse * texture2D(s_Texture, v_TexCoordinate));" +// Multiply the color by the diffuse illumination level and texture value to get final output color.
        "}";