Android GLES20 - 程序未链接

Android GLES20 - Program not linking

我正在使用 GLES20 创建着色器程序。 Link 状态为假,GLES20.glGetProgramInfoLog(program) return 只是一个空字符串。

着色器本身似乎可以正确编译,因为 GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, status, 0) 为顶点和片段着色器提供 true。

由于 GLES20.glGetProgramInfoLog(program) return 只是一个空字符串,调试起来真的很困难,着色器对我来说看起来是正确的,但我显然错过了一些东西。有人知道吗?

提前致谢。

现在简化代码和着色器:

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

输出:

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: 

抱歉,我还不能对主要问题发表评论。因此,我必须写一个答案。请您删除glValidateProgram,看看是否是信息日志为空的原因?因为程序在失败后可能有效 link 你可以用 glValidateProgram 覆盖信息日志,在 glLinkProgram.

之后用空字符串

更新

您的错误在于您使用 glGetShaderiv 而不是 glGetProgramiv 检查程序的状态。这会导致 GL_INVALID_OPERATION 错误。在您的手机 phone 的开发人员选项中,您可以打开 OpenGL 跟踪,这将向您显示此错误。这也解释了为什么您的信息日志是空的。 glGetShaderiv 没有成功并且不知道你的程序出了什么问题。 glGetProgramiv 会给你成功的回报。