index大于GL_MAX_VERTEX_ATTRIBS(虽然它实际上低于硬件限制)

时间:2017-04-11 16:33:59

标签: android opengl-es

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

var sizeRange = ["11x17 - Starting Price <span>$19.99</span>",
        "24x36 - Starting Price <span>$29.99</span>",
        "70x90 - Starting Price <span>$39.99</span>",
        "120x50 - Starting Price <span>$49.99</span>",
        "67x18 - Starting Price <span>$59.99</span>",
        "19x30 - Starting Price <span>$69.99</span>"]

$('#sliderPrice').html( sizeRange[0] );

$(document).on('input change', '#range-slider', function() { 
   var v=$(this).val();

   $('#sliderStatus').html( $(this).val() );
   $('#sliderPrice').html( sizeRange[v] );

   $("#img").prop("src", imageUrl[v]);
});

我的手机是Allview P5 Energy,运行Android 5.1,内核3.10.65+ 运行我的代码的模拟器是Google Nexus 4,4.2.2。 API 17。

由于错误代码表明我可能试图为每个顶点编写太多属性,因此我使用以下代码片段检查了我的(模拟)硬件支持的最大属性数量:

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.确定16少了但是你可以在我的着色器中看到,我只使用3个属性,3&lt; 16 ...着色器如下:< / p>

IntBuffer max = IntBuffer.allocate(1);
 GLES20.glGetIntegerv(GLES20.GL_MAX_VERTEX_ATTRIBS,max);
 System.err.println("GLES MAX IS"+max.get(0));

我用来将数据传递到着色器的代码如下(首先用于初始化):

  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.
            "}";

在init方法中,我还将顶点,法线和纹理坐标放在GPU内存中的缓冲区中。然后,对于每个帧,我执行此代码,基本上对于我尝试写入的每个数据元素,我得到上述错误。这是为每个帧调用的draw方法:

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

任何建议都会非常有用,我已经尝试了很多,比如使用一个简单的立方体模型而不是我想要绘制的高多边形图,但到目前为止没有任何工作可以摆脱手机上的错误。在模拟器上,任何模型都画得很好......

1 个答案:

答案 0 :(得分:0)

问题出在片段着色器中。不知怎的,手机中的硬件无法处理除以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的错误消息根本没有帮助,真的让我离开去搜索错误的方向。