我正在尝试使用我从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$1.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);
}
}
这是单个着色器文件(片段或顶点)的类
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中的日志信息之前它不会失败
答案 0 :(得分:0)
在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()
都希望着色器 ID作为第一个参数。要获取有关程序的信息,您需要使用相应的程序调用:
public static String getLogInfo(int obj) {
return glGetProgramInfoLog(obj, glGetProgrami(obj, GL_INFO_LOG_LENGTH));
}