Shader.java
public class Shader {
private int id;
public Shader(int shaderType, String path) throws IOException {
InputStream inputStream = getClass().getResourceAsStream(path);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
ArrayList<String> source = new ArrayList<String>();
while (bufferedReader.ready()) {
source.add(bufferedReader.readLine()+"\n");
}
init(shaderType, source.toArray(new String[source.size()]));
}
public Shader(int shaderType, String[] source) {
init(shaderType, source);
}
private void init(int shaderType, String[] source) {
GL gl = GLU.getCurrentGL();
id = gl.glCreateShader(shaderType);
gl.glShaderSource(id, source.length, source, getLengths(source));
gl.glCompileShader(id);
checkCompileError(gl);
}
private void checkCompileError(GL gl) {
IntBuffer status = BufferUtil.newIntBuffer(1);
gl.glGetShaderiv(id, GL.GL_COMPILE_STATUS, status);
if (status.get() == GL.GL_FALSE) {
getInfoLog(gl);
} else {
System.out.println("Successfully compiled shader " + id);
}
}
private void getInfoLog(GL gl) {
IntBuffer infoLogLength = BufferUtil.newIntBuffer(1);
gl.glGetShaderiv(id, GL.GL_INFO_LOG_LENGTH, infoLogLength);
int infoLogLengthInt = infoLogLength.get();
ByteBuffer infoLog = BufferUtil.newByteBuffer(infoLogLengthInt);
gl.glGetShaderInfoLog(id, infoLogLengthInt, null, infoLog);
String infoLogString =
Charset.forName("US-ASCII").decode(infoLog).toString();
throw new Error("Shader compile error\n" + infoLogString);
}
public void delete() {
GL gl = GLU.getCurrentGL();
gl.glDeleteShader(id);
}
public int getID() {
return id;
}
private static IntBuffer getLengths(String[] strings) {
IntBuffer intBuffer = BufferUtil.newIntBuffer(strings.length);
for (int i = 0; i < strings.length; i++) {
intBuffer.put(strings[i].length());
}
intBuffer.rewind();
return intBuffer;
}
}
Program.java
public class Program {
private Shader[] attachedShaders = null;
private int id;
public Program(Shader... shaders) {
GL gl = GLU.getCurrentGL();
id = gl.glCreateProgram();
attachedShaders = shaders;
for (Shader shader : attachedShaders) {
gl.glAttachShader(id, shader.getID());
}
}
public void link() {
GL gl = GLU.getCurrentGL();
gl.glLinkProgram(id);
checkLinkAndValidationErrors(gl);
}
private void checkLinkAndValidationErrors(GL gl) {
IntBuffer status = BufferUtil.newIntBuffer(1);
gl.glGetProgramiv(id, GL.GL_LINK_STATUS, status);
if (status.get() == GL.GL_FALSE) {
getInfoLog(gl);
} else {
status.rewind();
gl.glValidateProgram(id);
gl.glGetProgramiv(id, GL.GL_VALIDATE_STATUS, status);
if (status.get() == GL.GL_FALSE) {
getInfoLog(gl);
} else {
System.out.println("Successfully linked program " + id);
}
}
}
private void getInfoLog(GL gl) {
IntBuffer infoLogLength = BufferUtil.newIntBuffer(1);
gl.glGetProgramiv(id, GL.GL_INFO_LOG_LENGTH, infoLogLength);
int infoLogLengthInt = infoLogLength.get();
ByteBuffer infoLog = BufferUtil.newByteBuffer(infoLogLengthInt);
gl.glGetProgramInfoLog(id, infoLogLengthInt, null, infoLog);
String infoLogString =
Charset.forName("US-ASCII").decode(infoLog).toString();
throw new Error("Program compile error\n" + infoLogString);
}
public void delete() {
GL gl = GLU.getCurrentGL();
for (Shader shader : attachedShaders) {
shader.delete();
}
gl.glDeleteProgram(id);
}
public int getID() {
return id;
}
}
Then you can do
Shader vertexShader = new Shader(GL.GL_VERTEX_SHADER, "/shaders/normalizer.vert");
Shader fragmentShader = new Shader(GL.GL_FRAGMENT_SHADER, "/shaders/normalizer.frag");
Program normalizerProgram = new Program(vertexShader, fragmentShader);
(You must ensure you create instances of Shader and Program on the GL Thread)