2016-09-22 2 views
1

Ich versuche mit OpenGL2.0 und erstellen Sie mehrere Würfel im 3D-Raum, für Android-Geräte.Warum gibt GLES20.glGetAttribLocation unterschiedliche Werte für verschiedene Geräte zurück?

Der Code es perfekt in einigen Geräten läuft, in anderen aber nicht, und ich weiß nicht, warum ... (Alle Geräte verfügen über OpenGL 2.0 unterstützt, und haben kürzlich Android Versionen [5.0 oder 6.0])

ich weiß nur, dass das Problem in einem -1 Rückgabewert (siehe unten)

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 ... 

die cubeNormalParam1 = GLES20.glGetAttribLocation(cubeProgram1, "a_Normal"); kehrt Wert 2 in einigen Geräten und -1 in anderen . Diejenigen, die haben -1 Wert, geben Fehler und läuft nicht ...

Ich versuche festzustellen, ob die vertex_shader Fehler haben, aber ich kann keine Probleme sehen ...

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

Warum Dies geschieht? Ist die Hardware?

Jede Lösung, um dies zu beheben?


Cube zu zeichnen Ich habe dies:

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"); 
    } 
+0

Was meinen Sie mit "verschiedenen Geräten"? Verschiedene GPUs? –

+0

Verschiedene Android-Handys und VR-Brillen, zum Beispiel. Es funktioniert in Brillen und einigen Handys, aber in anderen Handys funktioniert nicht (S7 Edge, z. B..). Die GPU von allen unterstützt OpenGL 1.0, 2.0, 3.0. –

+0

Der Fehler ist E/Menü: Zeichnen cube: glError 1281. –

Antwort

0

Die Lösung - mit -1 Wert multipliziert

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

oder

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

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

Ist das nicht die beste Lösung, aber jetzt funktioniert es.

+0

Dies funktioniert nicht - Sie verstecken nur den Fehler, nicht wirklich beheben. Sie verwandeln eine -1 (Attribut nicht verwendet) in eine +1 (die die Bindungsstelle für ein völlig anderes Attribut ist). – solidpixel

+0

Das stimmt, ich verstecke den Fehler und repariere ihn nicht. Aber ist die einzige Lösung, die ich finden kann, damit es im Gerät funktioniert, und es läuft. Ich kann eine andere Lösung dafür nicht finden: \ –

+0

Der Fehler ist, den Aufruf von GLES20.glEnableVertexAttribArray (cubeNormalParam1) zu beenden, wenn der von 'GLES20.glGetAttribLocation()' zurückgegebene Ort -1 ist. Überspringe 'GLES20.glVertexAttibPointer' auch. – solidpixel

5
Why GLES20.glGetAttribLocation returns different values for different devices? 

... weil verschiedene Geräte unterschiedliche Hardware für den Aufbau von Bindung Tabellen haben, und in einigen Fällen aus vollständig optimieren können redundante Berechnungen und Repack der verwendeten Attribute um Platz zu sparen. Dies ist genau, warum die API einen Funktionsaufruf zum Abrufen bindenden Standorten auf dem Gerät zur Laufzeit hat; wenn sie deterministische Konstanten wären, würden Sie überhaupt keinen Laufzeitaufruf benötigen ...

Die Tatsache, dass -1 zurückgegeben wird, ist kein Fehler; Es zeigt nur, dass das Attribut nicht benötigt wird (z. B. definiert, kann aber optimiert werden, da es nicht zur Fragmentpixelfarbe beiträgt), so dass dies keine Probleme verursachen sollte.

aber es bedeutet, dass Sie nicht sicher (zB) annehmen können, dass a_Position immer Attribut 0, ist a_Color immer 1, a_Normal ist immer 2, etc. Wenn Sie hart, dass dann in Ihrem Code codiert haben es ganz möglich, dass Sie die falschen Daten zu jedem Attribut hochladen. Sie müssen die Bindungsstellen abfragen, um die zu verwendenden Bindungsnummern zu erhalten (oder verwenden Sie die in OpenGL ES 3.x hinzugefügte statische Bindung der Shader-Seite).

Welcher GL-API-Aufruf setzt den GL-Fehlerstatus?

+0

Ich benutze OpenGL2.0. Der Fehler erscheint mehrmals ständig ist dieser. 10301-10382/com.google.vrtoolkit.cardboard.samples.treasurehunt E/Menu: Zeichenwürfel: glError 1281 –

+0

... ja, das sagt Ihnen, was der Fehler ist, aber nicht welcher Funktionsaufruf das verursacht einstellen. Ohne weitere Informationen darüber, welcher Funktionsaufruf schief geht, ist es unmöglich zu helfen. Rufen Sie Ihre checkError Funktion nach jeder API aufrufen, die Sie machen, und berichten über die spezifische Funktion, die den Fehler setzt - gerade berichtet, dass am Ende „etwas schief gegangen ist“, ist nicht besonders hilfreich für das Debuggen ... – solidpixel

+0

Danke, ich das tun Das Problem ist, jetzt läuft die Anwendung und zeigt nichts, bleib schwarz. Ich legte die DrawCube-Funktion, bei der Aktualisierung, in der Frage. Vielleicht ist der Fehler da ... aber ich kann es nicht finden, weil die App läuft und nicht kaputt geht. initialy, war der Fehler hier: GLES20.glEnableVertexAttribArray (cubeNormalParam1); Es war auf, onSurfaceCreated (EGLConfig config) { (und es gibt -1, deshalb glaube ich, das Problem war da) Ich habe es für die CubeDraw() geändert, und jetzt läuft es (mit Fehler 1281), aber auf dem Bildschirm wird nichts angezeigt. –

Verwandte Themen