package com.peterhi.ui.gl;
import java.nio.charset.Charset;
import javax.media.opengl.GL;
import javax.media.opengl.GL3;
import javax.media.opengl.GLException;
public abstract class GLShader extends GLObject {
private String source;
public GLShader(GL gl) {
super(gl);
if (!gl.hasGLSL()) {
throw new IllegalArgumentException();
}
setId((Integer )glInvoke("glCreateShader", int.class, getShaderKind()));
}
public GLShader(GL gl, String source) {
this(gl);
setSource(source);
}
public String getSource() {
if (isDisposed()) {
throw new GLException();
}
return source;
}
public void setSource(String value) {
if (value == null) {
throw new NullPointerException();
}
if (value.isEmpty()) {
throw new IllegalArgumentException();
}
if (isDisposed()) {
throw new GLException();
}
glInvoke("glShaderSource",
int.class, getId(),
int.class, 1,
String[].class, new String[] { value },
int[].class, new int[] { value.length() },
int.class, 0
);
source = value;
}
public void compile() {
if (isDisposed()) {
throw new GLException();
}
if (source == null || source.isEmpty()) {
throw new GLException();
}
glInvoke("glCompileShader",
int.class, getId()
);
int[] status = new int[1];
glInvoke("glGetShaderiv",
int.class, getId(),
int.class, GL3.GL_COMPILE_STATUS,
int[].class, status,
int.class, 0
);
if (status[0] == GL.GL_TRUE) {
return;
}
int[] length = new int[1];
glInvoke("glGetShaderiv",
int.class, getId(),
int.class, GL3.GL_INFO_LOG_LENGTH,
int[].class, length,
int.class, 0
);
byte[] chars = new byte[length[0]];
glInvoke("glGetShaderInfoLog",
int.class, getId(),
int.class, length[0],
int[].class, length,
int.class, 0,
char[].class, chars,
int.class, 0
);
String message = new String(chars, Charset.forName("utf-8"));
throw new GLException(message);
}
@Override
public void dispose() {
if (isDisposed()) {
return;
}
glInvoke("glDeleteShader",
int.class, getId()
);
super.dispose();
}
protected abstract int getShaderKind();
}