Android GLES20 - 程序没有链接

时间:2016-07-11 08:55:56

标签: android opengl-es-2.0

我正在使用GLES20来创建着色器程序。链接状态为false,GLES20.glGetProgramInfoLog(program)只返回一个空字符串。

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

由于GLES20.glGetProgramInfoLog(program)只返回一个空字符串,它很难调试,着色器对我来说看起来很正确,但我显然错过了一些东西。有人有什么想法吗?

提前致谢。

现在简化了代码和着色器:

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: 

1 个答案:

答案 0 :(得分:2)

对不起,我无法发表评论,但仍然是主要问题。因此我必须写一个答案。你可以删除glValidateProgram,看看是否是信息日志为空的原因?因为程序在链接失败后可能有效,所以你可以在glLinkProgram之后使用带有空字符串的glValidateProgram覆盖信息日志。

<强>更新

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