Why GLES20.glGetAttribLocation returns different values for different devices?

拜拜、爱过 提交于 2020-01-06 03:41:57

问题


I'm trying using OpenGL2.0 and create multiple cubes in 3D space, for android devices.

The code it runs perfectly in some devices, but not in others, and i don't know why... (All devices have OpenGL 2.0 supported, and have recent android versions [5.0 or 6.0])

I only know that the problem is in a -1 return value (see down)

int vertexShader = loadGLShader(GLES20.GL_VERTEX_SHADER, R.raw.vertex);
int gridShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.grid_fragment);
int passthroughShader = loadGLShader(GLES20.GL_FRAGMENT_SHADER, R.raw.fragment_color);

     cubeProgram1 = GLES20.glCreateProgram();
     GLES20.glAttachShader(cubeProgram1, vertexShader);
     GLES20.glAttachShader(cubeProgram1, passthroughShader);
     GLES20.glLinkProgram(cubeProgram1);
     GLES20.glUseProgram(cubeProgram1);

    cubePositionParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Position");
    cubeNormalParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal"); ----> Returns -1 Value
    cubeLightPosParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_LightPos");
    cubeModelParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_Model") cubeModelViewParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_MVMatrix");
    cubeModelViewProjectionParam1 = GLES20.glGetUniformLocation(cubeProgram1, "u_MVP");

....

 GLES20.glEnableVertexAttribArray(cubeNormalParam1); ---> Returns -1 ... 

The cubeNormalParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal"); returns value 2 in some devices, and -1 in others. Those who have -1 value, give error and doesn't run...

I'm trying see if the vertex_shader have errors but i can't see any problems...

uniform mat4 u_Model;
uniform mat4 u_MVP;
uniform mat4 u_MVMatrix;
uniform vec3 u_LightPos;

attribute vec4 a_Position;
attribute vec4 a_Color;
attribute vec3 a_Normal;
attribute vec2 a_TexCoordinate;

varying vec4 v_Color;
varying vec3 v_Grid;
varying vec2 v_TexCoordinate;

void main() {
   v_Grid = vec3(u_Model * a_Position);


   vec3 modelViewVertex = vec3(u_MVMatrix * a_Position);
   vec3 modelViewNormal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

   float distance = length(u_LightPos - modelViewVertex);
   vec3 lightVector = normalize(u_LightPos - modelViewVertex);
   float diffuse = max(dot(modelViewNormal, lightVector), 0.5);

   diffuse = diffuse * (1.0 / (1.0 + (0.00001 * distance * distance)));
   v_Color = a_Color * diffuse;

   v_TexCoordinate = a_TexCoordinate;

   gl_Position = u_MVP * a_Position;
}

Why this happen? Is the Hardware?

Any Solution to fix this?


To draw Cube i've this:

public void drawCube1() {
        cubeNumber = 1;

        GLES20.glUseProgram(cubeProgram1);
        GLES20.glUniform3fv(cubeLightPosParam1, 1, lightPosInEyeSpace, 0);
        // Set the Model in the shader, used to calculate lighting
        GLES20.glUniformMatrix4fv(cubeModelParam1, 1, false, modelCube, 0);
        // Set the ModelView in the shader, used to calculate lighting
        GLES20.glUniformMatrix4fv(cubeModelViewParam1, 1, false, modelView, 0);
        // Set the ModelViewProjection matrix in the shader.
        GLES20.glUniformMatrix4fv(cubeModelViewProjectionParam1, 1, false, modelViewProjection1, 0);
        // Set the position of the cube
        GLES20.glVertexAttribPointer(
                cubePositionParam1, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, cubeVertices);
        // Set the normal positions of the cube, again for shading
        GLES20.glVertexAttribPointer(cubeNormalParam1, 3, GLES20.GL_FLOAT, false, 0, cubeNormals);
        // 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, mTextura1);

        isLookingAtObject_Number(cubeNumber);

        // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
        GLES20.glUniform1i(mTextureUniform, 0);

        GLES20.glVertexAttribPointer(mTextureCoordinate, 2, GLES20.GL_FLOAT, false, 0, cubeTexture);
        GLES20.glEnableVertexAttribArray(mTextureCoordinate);

        GLES20.glEnableVertexAttribArray(cubePositionParam1);
        GLES20.glEnableVertexAttribArray(cubeNormalParam1);

        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 36);
        checkGLError("Drawing cube");
    }

回答1:


Why GLES20.glGetAttribLocation returns different values for different devices?

... because different devices will have different hardware for setting up binding tables, and in some cases may completely optimize out redundant computations and repack the used attributes to save space. This is exactly why the API has a function call for getting binding locations on the device at runtime; if they were deterministic constants you wouldn't need a run-time call at all ...

The fact it returns -1 isn't an error; it is just showing that the attribute isn't needed (e.g. defined, but can optimized out because it doesn't contribute to the fragment pixel color), so this shouldn't cause any problems.

However it does mean that you can't safely assume (e.g.) that a_Position is always attribute 0, a_Color is always 1, a_Normal is always 2, etc. If you've hard coded that in your code then it's entirely possible you are uploading the wrong data to each attribute. You must query the binding locations to get the binding numbers to use (or use the shader-side static binding added in OpenGL ES 3.x).

Which actual GL API call is setting the GL error state?




回答2:


The Solution - multiplying with -1 value

 ... = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") * -1;

or

int value;
if( GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") < 0){
      value = -1;
}
else {
      value = 1;
}

... = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal") * value;

Is not the best solution, but now it works.



来源:https://stackoverflow.com/questions/39642623/why-gles20-glgetattriblocation-returns-different-values-for-different-devices

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!