GLSL 着色器未编译,无错误消息

GLSL Shader not Compiling, no Error Message

我正在尝试使用我从 LWJGL 编写的 GLSL 着色器。它只是一个简单的基于片段的 phong 着色器。着色器过去运行良好,即使在这台计算机上也是如此。有一天,突然间,它无缘无故地停止了编译。当我尝试编译它并检查信息日志时,我收到此消息:

Exception in thread "Thread-1" org.lwjgl.opengl.OpenGLException: Invalid value (1281)
    at org.lwjgl.opengl.Util.checkGLError(Util.java:59)
    at org.lwjgl.opengl.GL20.glGetShaderi(GL20.java:542)
    at aspect.render.shader.ShaderProgram.getLogInfo(ShaderProgram.java:161)
    at aspect.render.shader.ShaderProgram.<init>(ShaderProgram.java:69)
    at aspect.render.shader.ShaderProgram.loadPrebuilt(ShaderProgram.java:168)
    at aspect.core.AspectLauncher.run(AspectLauncher.java:143)

我的 OpenGL 信息:

GL VENDOR: Intel
GL RENDERER: Intel(R) HD Graphics 3000
GL VERSION: 3.1.0 - Build 9.17.10.3347
GLSL VERSION: 1.40 - Intel Build 9.17.10.3347

这是着色器本身:

顶点:

#version 140

uniform int numLights;
uniform bool useLighting;

varying vec3 normal;
varying vec3 ambient;
varying vec3 color;

varying vec3 diffuse[8];
varying vec3 lightDir[8];
varying vec3 dist[8];

varying vec2 texCoord;

void main() { 
    vec4 position = gl_ModelViewMatrix * gl_Vertex;
    gl_Position = gl_ProjectionMatrix * position;
    normal = normalize(gl_NormalMatrix * gl_Normal);
    texCoord = gl_MultiTexCoord0.st;
    color = gl_Color.rgb;

    ambient = gl_FrontMaterial.emission.rgb + gl_LightModel.ambient.rgb * gl_FrontMaterial.ambient.rgb;

    if (useLighting) {
        for (int i = 0; i < numLights; i++) {

            float diffuseIntensity;

            if (gl_LightSource[i].position.w != 0.0) {
                vec3 toLight = (gl_LightSource[i].position - position).xyz;

                dist[i] = toLight;
                lightDir[i] = normalize(toLight);

                diffuseIntensity = dot(normalize(toLight), normal);
            } else {
                lightDir[i] = normalize(gl_LightSource[i].position.xyz);

                diffuseIntensity = dot(normalize(gl_LightSource[i].position.xyz), normal);
            }

            diffuseIntensity = max(diffuseIntensity, 0.0);

            diffuse[i] = gl_FrontMaterial.diffuse.rgb * gl_LightSource[i].diffuse.rgb * diffuseIntensity;

        }
    }
}

片段:

#version 140

uniform bool useTexture;
uniform bool useLighting;
uniform sampler2D tex;
uniform int numLights;

varying vec3 normal;
varying vec3 ambient;
varying vec3 color;

varying vec3 diffuse[8];
varying vec3 lightDir[8];
varying vec3 dist[8];

varying vec2 texCoord;

void main() {


    vec4 texColor;

    if (useTexture) {
        texColor = texture2D(tex, texCoord);
    } else {
        texColor = vec4(1.0);
    }

    if (texColor.a == 0.0) {
        discard;
    } else {
        texColor.a = 1.0;
    }

    vec3 lightColor;

    if (useLighting) {
        lightColor = ambient;

        for (int i = 0; i < numLights; i++) {
            float specularIntensity;

            float att = 1.0;

            if (gl_LightSource[i].position.w != 0.0) {

                float dist = length(dist[i]);

                att = 1.0 / (gl_LightSource[i].constantAttenuation +
                             gl_LightSource[i].linearAttenuation * dist +
                             gl_LightSource[i].quadraticAttenuation * dist * dist);

                vec3 halfVector = normalize(lightDir[i]) + vec3(0.0, 0.0, 1.0);

                specularIntensity = dot(normalize(halfVector), normalize(normal));
            } else {
                vec3 halfVector = normalize(lightDir[i]) + vec3(0.0, 0.0, 1.0);

                specularIntensity = dot(normalize(halfVector), normalize(normal));
            }

            specularIntensity = max(specularIntensity, 0.0);

            lightColor += diffuse[i] * att;
            lightColor += gl_FrontMaterial.specular.rgb * gl_LightSource[i].specular.rgb * pow(specularIntensity, gl_FrontMaterial.shininess) * att;
        }
    } else {
        lightColor = color;
    }

    gl_FragColor = texColor * vec4(lightColor, 1.0);
}

最后,我加载着色器的代码:

public class ShaderProgram {

    private final int programID;

    public ShaderProgram(int programID) {
        this.programID = programID;
    }

    public ShaderProgram(Shader... shaders) {

        int id;

        try {
            id = glCreateProgram();
        } catch (Exception ex) {
            Logger.getLogger(ShaderProgram.class.getName()).log(Level.SEVERE, null, ex);
            programID = 0;
            return;
        }

        for (Shader shader : shaders) {
            glAttachShader(id, shader.id);
        }

        glLinkProgram(id); 
        if (glGetProgrami(id, GL_LINK_STATUS) == GL_FALSE) {
            System.err.println(getLogInfo(id)); // This is the line that causes the error. It actually throws an exception (doesn't just print error info)
            programID = 0;
            return;
        }

        glValidateProgram(id);
        if (glGetProgrami(id, GL_VALIDATE_STATUS) == GL_FALSE) {
            System.err.println(getLogInfo(id));
            programID = 0;
            return;
        }

        programID = id;
    }

    public static String getLogInfo(int obj) {
        return glGetShaderInfoLog(obj, glGetShaderi(obj, GL_INFO_LOG_LENGTH));
    }

    public static ShaderProgram loadPrebuilt(String name) {
        Shader vert = Shader.loadPrebuilt(name + ".vert", Shader.Type.VERTEX);
        Shader frag = Shader.loadPrebuilt(name + ".frag", Shader.Type.FRAGMENT);

        return new ShaderProgram(vert, frag);
    }
}

这是单个着色器文件(片段或顶点)的 class

public class Shader {

    public final int id;

    public Shader(int id) {
        this.id = id;
    }

    public Shader(File file, Shader.Type type) {
        int shader = 0;
        try {
            shader = create(readIntoString(new FileInputStream(file)), type);
        } catch (IOException ex) {
            Logger.getLogger(Shader.class.getName()).log(Level.SEVERE, null, ex);
        }
        id = shader;
    }

    public Shader (String program, Shader.Type type) {
        id = create(program, type);
    }


    public static Shader loadPrebuilt(String name, Shader.Type type) {
        try {
            return new Shader(readIntoString(name), type);
        } catch (IOException | URISyntaxException ex) {
            Logger.getLogger(ShaderProgram.class.getName()).log(Level.SEVERE, null, ex);
            return new Shader(0);
        }
    }

    private int create(String program, Type type) {
        int shader = 0;
        try {
            shader = glCreateShader(type.glType);

            glShaderSource(shader, program);

            glCompileShader(shader);

            if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) {
                System.err.println("Error creating shader (" + type.name() + "): " + getLogInfo(shader));
            }

        } catch (Exception ex) {
            glDeleteShader(shader);
            Logger.getLogger(ShaderProgram.class.getName()).log(Level.SEVERE, null, ex);
            shader = 0;
        }

        return shader;
    }

    private static String readIntoString(String filename) throws IOException, URISyntaxException {
        InputStream stream = Shader.class.getResourceAsStream(filename);

        return readIntoString(stream);
    }

    private static String readIntoString(InputStream stream) throws IOException {

        String version = glGetString(GL_SHADING_LANGUAGE_VERSION);
        version = version.substring(0, version.indexOf(" ")).replaceFirst("\.", "");

        return "#version " + version + "\n\n" + loadTextFile(stream);
    }
}

失败的行是这样的:

ShaderProgram.loadPrebuilt("phong");

文件加载正常。如果我打印它,它会打印出我想要的内容,并且在我尝试获取 ShaderProgram.java

中的日志信息之前它不会失败

ShaderProgram 构造函数中的代码序列中:

if (glGetProgrami(id, GL_LINK_STATUS) == GL_FALSE) {
    System.err.println(getLogInfo(id));

id 是一个 程序 id。您将它传递给 getLogInfo() 方法:

public static String getLogInfo(int obj) {
    return glGetShaderInfoLog(obj, glGetShaderi(obj, GL_INFO_LOG_LENGTH));
}

glGetShaderInfoLog()glGetShaderi() 都期望 shader id 作为第一个参数。要获取有关程序的信息,您需要改为使用程序的相应调用:

public static String getLogInfo(int obj) {
    return glGetProgramInfoLog(obj, glGetProgrami(obj, GL_INFO_LOG_LENGTH));
}