2016-07-11 20 views
0

Ich verwende GLES20, um ein Shader-Programm zu erstellen. Verbindungsstatus ist falsch und GLES20.glGetProgramInfoLog(program) gibt nur einen leeren String zurück.Android GLES20 - Programm nicht verknüpfen

Die Shader selbst scheinen korrent zu kompilieren, da sowohl für Vertex- als auch für Fragment-Shader gilt.

Da GLES20.glGetProgramInfoLog(program) nur eine leere Zeichenfolge zurückgibt, ist es wirklich schwierig zu debuggen und die Shader sehen für mich korrekt aus, aber ich habe anscheinend etwas verpasst. Hat jemand eine Idee?

Vielen Dank im Voraus.

nun vereinfachte Code und Shader:

private static String vertexSrc = "#version 100\n" + 
     "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + 
     "precision highp float;\n" + 
     "#else\n" + 
     "precision mediump float;\n" + 
     "#endif\n" + 
     "\n" + 
     "attribute vec3 position;\n" + 
     "\n" + 
     "\n" + 
     "void main() {   \n" + 
     "\t\n" + 
     "\tgl_Position = vec4(position, 1.0);\n" + 
     "\n" + 
     "}"; 
private static String fragmentSrc = "#version 100\n" + 
     "#ifdef GL_FRAGMENT_PRECISION_HIGH\n" + 
     "precision highp float;\n" + 
     "#else\n" + 
     "precision mediump float;\n" + 
     "#endif\n" + 
     "\n" + 
     "\n" + 
     "void main() {  \n" + 
     "\n" + 
     "\tgl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n" + 
     "\n" + 
     "}"; 

private void initShader(){ 

    int vertexShader = loadShader(vertexSrc, GLES20.GL_VERTEX_SHADER); 
    int fragmentShader = loadShader(fragmentSrc, GLES20.GL_FRAGMENT_SHADER); 

    int program = GLES20.glCreateProgram(); 
    System.out.println("Created program: " + program); 

    System.out.println("Attaching " + vertexShader + " to " + program); 
    GLES20.glAttachShader(program, vertexShader); 
    System.out.println("Attaching " + fragmentShader + " to " + program); 
    GLES20.glAttachShader(program, fragmentShader); 

    int[] attached = new int[2]; 
    int[] count = new int[1]; 
    GLES20.glGetAttachedShaders(program, 2, count, 0, attached, 0); 
    System.out.println("attached (" + count[0] + "): " + attached[0] + ", " + attached[1]); 

    GLES20.glBindAttribLocation(program, 0, "position"); 
    //GLES20.glBindAttribLocation(program, 1, "texCoord"); 

    GLES20.glLinkProgram(program); 

    int[] lstatus = new int[1]; 
    GLES20.glGetShaderiv(program, GLES20.GL_LINK_STATUS, lstatus, 0); 
    if (lstatus[0] == GL11.GL_FALSE){ 
     System.err.println("Could not link program.\nlink status: " + lstatus[0]); 
     System.err.println("Program-Info-Log: " + GLES20.glGetProgramInfoLog(program)); 
    }else{ 
     System.out.println("program linked: " + program); 
    } 

    GLES20.glValidateProgram(program); 

    int[] vstatus = new int[1]; 
    GLES20.glGetShaderiv(program, GLES20.GL_VALIDATE_STATUS, vstatus, 0); 

    if (vstatus[0] == GL11.GL_FALSE){ 
     System.err.println("Could not validate program.\nvalidate status: " + vstatus[0]); 
     System.err.println("Program-Info-Log: " + GLES20.glGetProgramInfoLog(program)); 
    }else{ 
     System.out.println("program validated: " + program); 
    } 

} 

private int loadShader(String shadercontent, int GL20_XXX_SHADER){ 

    //System.out.println(shadercontent); 

    if(GL20_XXX_SHADER == GLES20.GL_VERTEX_SHADER) 
     System.out.println("Loading vertex shader..."); 
    else if(GL20_XXX_SHADER == GLES20.GL_FRAGMENT_SHADER) 
     System.out.println("Loading fragment shader..."); 

    int shader = GLES20.glCreateShader(GL20_XXX_SHADER); 
    GLES20.glShaderSource(shader, shadercontent); 
    GLES20.glCompileShader(shader); 
    int[] status = new int[1]; 
    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, status, 0); 
    if (status[0] == GL11.GL_FALSE){ 
     System.err.println("Could not load shader: \n" + GLES20.glGetShaderInfoLog(shader)); 
    }else{ 
     System.out.println("Shader compiled: " + shader); 
    } 
    return shader; 
} 

Ausgang:

D/libEGL: eglInitialize EGLDisplay = 0x9f7467c4 
I/OpenGLRenderer: Initialized EGL, version 1.4 
D/mali_winsys: new_window_surface returns 0x3000, [1536x2048]-format:1 
D/libEGL: eglInitialize EGLDisplay = 0xae57b4c4 
D/mali_winsys: new_window_surface returns 0x3000, [1536x1872]-format:1 
I/System.out: Loading vertex shader... 
D/libGLESv1: DTS_GLAPI : DTS is not allowed for Package : net.mypackage.myapp 
I/System.out: Shader compiled: 1 
I/System.out: Loading fragment shader... 
I/System.out: Shader compiled: 2 
I/System.out: Created program: 3 
I/System.out: Attaching 1 to 3 
I/System.out: Attaching 2 to 3 
I/System.out: attached (2): 1, 2 
W/System.err: Could not link program. 
W/System.err: link status: 0 
W/System.err: Program-Info-Log: 
W/System.err: Could not validate program. 
W/System.err: validate status: 0 
W/System.err: Program-Info-Log: 
+0

Ich versuchte auch mit fast leeren Shadern und immer noch das gleiche Problem. Sieht aus wie die Quelle des Problems nicht in den Shadern ist. –

+0

Haben Sie auf anderen Geräten versucht? Wenn ein Fehler im Shader-Code vorliegt, kann ein anderes Gerät Ihnen bessere Informationen darüber geben. Ich vermute, dass Sie in einer bestimmten GLES-Implementierung auf einen Fehler gestoßen sind. Eine Vereinfachung könnte daher eine gute Idee sein. Eine zufällige Sache zu versuchen: In Ihrem VS ist texCoord0 implizit highp, und in Ihrem PS ist es implizit mediump, versuchen Sie, dass sie übereinstimmen. – Columbo

+0

@Columbo Ich habe mit 2 physikalischen Deevices einen 1 Emulator probiert. Die Sache ist, dass der Emulator den Link- und Validierungsstatus erfüllt. Ich werde heute mit genauer Präzision testen und zurückkommen. –

Antwort

1

Leider kann ich nicht kommentieren, noch auf die Hauptfrage. Deshalb muss ich eine Antwort schreiben. Könnten Sie bitte das glValidateProgram entfernen, um zu sehen, ob dies der Grund ist, warum das Info-Log leer ist? Da das Programm nach einer fehlgeschlagenen Verbindung möglicherweise gültig ist, könnte das Info-Log mit glValidateProgram mit einer leeren Zeichenfolge nach glLinkProgram überschrieben werden.

UPDATE

Ihr Fehler ist, dass Sie mit glGetShaderiv statt glGetProgramiv Ihres Programms Status überprüfen. Dies führt zu einem Fehler GL_INVALID_OPERATION. In den Entwickleroptionen Ihres Mobiltelefons können Sie die OpenGL-Ablaufverfolgung aktivieren, die Ihnen diesen Fehler anzeigt. Das erklärt auch, warum Ihr Info-Log leer ist. glGetShaderiv war nicht erfolgreich und weiß nicht, was mit deinem Programm nicht stimmt. glGetProgramiv würde Ihnen erfolgreich zurück geben.

+0

Danke, aber das Info-Log ist noch leer. Ich habe gelesen, dass dies ein Fehler ist. –

+0

Haben Sie versucht, explizit die Version der Shader anzugeben? Ich meine # Version 100 oder so etwas an der Spitze von jedem? Ich habe Probleme erlebt, wenn ich nicht explizit die Version in GLES/GLSL angegeben habe. – DanielB

+0

Ich habe jetzt versucht, #version 100', ohne Erfolg. Trotzdem werden die Shader erfolgreich kompiliert, aber das Programm wird nicht verlinkt. –