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 会给你成功的回报。
我正在使用 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 会给你成功的回报。