我正在使用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:
答案 0 :(得分:2)
对不起,我无法发表评论,但仍然是主要问题。因此我必须写一个答案。你可以删除glValidateProgram,看看是否是信息日志为空的原因?因为程序在链接失败后可能有效,所以你可以在glLinkProgram之后使用带有空字符串的glValidateProgram覆盖信息日志。
<强>更新强>
你的错是你用glGetShaderiv而不是glGetProgramiv检查程序的状态。这会导致GL_INVALID_OPERATION错误。在手机的开发者选项中,您可以启用OpenGL跟踪,这将向您显示此错误。这也解释了为什么您的信息日志为空。 glGetShaderiv没有成功,也不知道你的程序有什么问题。 glGetProgramiv会让你成功回来。