Improved shader error log

This commit is contained in:
codeanticode
2012-03-21 16:26:48 +00:00
parent eea9814d03
commit 4e428ecc61
2 changed files with 121 additions and 68 deletions
@@ -105,6 +105,9 @@ public class PGL {
// OpenGL constants
public static final int GL_FALSE = GL.GL_FALSE;
public static final int GL_TRUE = GL.GL_TRUE;
public static final int GL_LESS = GL.GL_LESS;
public static final int GL_LEQUAL = GL.GL_LEQUAL;
public static final int GL_CCW = GL.GL_CCW;
@@ -223,8 +226,13 @@ public class PGL {
public static final int GL_READ_FRAMEBUFFER = GL2.GL_READ_FRAMEBUFFER;
public static final int GL_DRAW_FRAMEBUFFER = GL2.GL_DRAW_FRAMEBUFFER;
public static final int GL_VERTEX_SHADER = GL2.GL_VERTEX_SHADER;
public static final int GL_FRAGMENT_SHADER = GL2.GL_FRAGMENT_SHADER;
public static final int GL_VERTEX_SHADER = GL2.GL_VERTEX_SHADER;
public static final int GL_FRAGMENT_SHADER = GL2.GL_FRAGMENT_SHADER;
public static final int GL_INFO_LOG_LENGTH = GL2.GL_INFO_LOG_LENGTH;
public static final int GL_SHADER_SOURCE_LENGTH = GL2.GL_SHADER_SOURCE_LENGTH;
public static final int GL_COMPILE_STATUS = GL2.GL_COMPILE_STATUS;
public static final int GL_LINK_STATUS = GL2.GL_LINK_STATUS;
public static final int GL_VALIDATE_STATUS = GL2.GL_VALIDATE_STATUS;
public static final int GL_MULTISAMPLE = GL.GL_MULTISAMPLE;
public static final int GL_POINT_SMOOTH = GL2.GL_POINT_SMOOTH;
@@ -841,6 +849,38 @@ public class PGL {
}
public void glGetShaderiv(int shader, int pname, int[] params, int offset) {
gl2.glGetShaderiv(shader, pname, params, offset);
}
public String glGetShaderInfoLog(int shader) {
int[] val = { 0 };
gl2.glGetShaderiv(shader, GL2.GL_INFO_LOG_LENGTH, val, 0);
int length = val[0];
byte[] log = new byte[length];
gl2.glGetShaderInfoLog(shader, length, val, 0, log, 0);
return new String(log);
}
public void glGetProgramiv(int prog, int pname, int[] params, int offset) {
gl2.glGetProgramiv(prog, pname, params, offset);
}
public String glGetProgramInfoLog(int prog) {
int[] val = { 0 };
gl2.glGetShaderiv(prog, GL2.GL_INFO_LOG_LENGTH, val, 0);
int length = val[0];
byte[] log = new byte[length];
gl2.glGetProgramInfoLog(prog, length, val, 0, log, 0);
return new String(log);
}
/////////////////////////////////////////////////////////////////////////////////
// Viewport
@@ -1055,28 +1095,6 @@ public class PGL {
}
public String getShaderLog(int id) {
IntBuffer val = IntBuffer.allocate(1);
gl2.glGetObjectParameterivARB(id, GL2.GL_OBJECT_INFO_LOG_LENGTH_ARB, val);
int length = val.get();
if (length <= 1) {
return "";
}
// Some error occurred...
ByteBuffer infoLog = ByteBuffer.allocate(length);
val.flip();
gl2.glGetInfoLogARB(id, length, val, infoLog);
byte[] infoBytes = new byte[length];
infoLog.get(infoBytes);
return new String(infoBytes);
}
///////////////////////////////////////////////////////////////////////////////////
// Java specific stuff
@@ -43,6 +43,9 @@ public class PShader {
protected String vertexFilename;
protected String fragmentFilename;
protected String vertexShaderSource;
protected String fragmentShaderSource;
protected int programObject;
protected int vertexShader;
@@ -293,32 +296,61 @@ public class PShader {
}
protected void init() {
if (programObject == 0 || contextIsOutdated()) {
if (programObject == 0 || contextIsOutdated()) {
context = pgl.getContext();
programObject = pg.createGLSLProgramObject();
boolean hasVert = false;
if (vertexFilename != null) {
loadVertexShader(vertexFilename);
hasVert = loadVertexShader(vertexFilename);
} else if (vertexURL != null) {
loadVertexShader(vertexURL);
hasVert = loadVertexShader(vertexURL);
} else {
PGraphics.showException("Vertex shader filenames and URLs are both null!");
}
boolean hasFrag = false;
if (fragmentFilename != null) {
loadFragmentShader(fragmentFilename);
hasFrag = loadFragmentShader(fragmentFilename);
} else if (fragmentURL != null) {
loadFragmentShader(fragmentURL);
hasFrag = loadFragmentShader(fragmentURL);
} else {
PGraphics.showException("Fragment shader filenames and URLs are both null!");
}
checkLogInfo("Vertex shader " + vertexFilename + " compilation: ", vertexShader);
checkLogInfo("Fragment shader " + fragmentFilename + " compilation: ", fragmentShader);
boolean vertRes = true;
if (hasVert) {
vertRes = compileVertexShader();
}
boolean fragRes = true;
if (hasFrag) {
fragRes = compileFragmentShader();
}
pgl.glLinkProgram(programObject);
pgl.glValidateProgram(programObject);
if (vertRes && fragRes) {
if (hasVert) {
pgl.glAttachShader(programObject, vertexShader);
}
if (hasFrag) {
pgl.glAttachShader(programObject, fragmentShader);
}
pgl.glLinkProgram(programObject);
int[] linked = new int[1];
pgl.glGetProgramiv(programObject, PGL.GL_LINK_STATUS, linked, 0);
if (linked[0] == PGL.GL_FALSE) {
PGraphics.showException("Cannot link shader program:\n" + pgl.glGetProgramInfoLog(programObject));
}
pgl.glValidateProgram(programObject);
int[] validated = new int[1];
pgl.glGetProgramiv(programObject, PGL.GL_VALIDATE_STATUS, validated, 0);
if (validated[0] == PGL.GL_FALSE) {
PGraphics.showException("Cannot validate shader program:\n" + pgl.glGetProgramInfoLog(programObject));
}
}
}
}
@@ -339,9 +371,9 @@ public class PShader {
*
* @param file String
*/
protected void loadVertexShader(String filename) {
String shaderSource = PApplet.join(parent.loadStrings(filename), "\n");
attachVertexShader(shaderSource);
protected boolean loadVertexShader(String filename) {
vertexShaderSource = PApplet.join(parent.loadStrings(filename), "\n");
return vertexShaderSource != null;
}
/**
@@ -349,12 +381,13 @@ public class PShader {
*
* @param file String
*/
protected void loadVertexShader(URL url) {
protected boolean loadVertexShader(URL url) {
try {
String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachVertexShader(shaderSource);
vertexShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
return vertexShaderSource != null;
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
PGraphics.showException("Cannot load vertex shader " + url.getFile());
return false;
}
}
@@ -363,9 +396,9 @@ public class PShader {
*
* @param file String
*/
protected void loadFragmentShader(String filename) {
String shaderSource = PApplet.join(parent.loadStrings(filename), "\n");
attachFragmentShader(shaderSource);
protected boolean loadFragmentShader(String filename) {
fragmentShaderSource = PApplet.join(parent.loadStrings(filename), "\n");
return fragmentShaderSource != null;
}
/**
@@ -373,51 +406,53 @@ public class PShader {
*
* @param url URL
*/
protected void loadFragmentShader(URL url) {
protected boolean loadFragmentShader(URL url) {
try {
String shaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
attachFragmentShader(shaderSource);
fragmentShaderSource = PApplet.join(PApplet.loadStrings(url.openStream()), "\n");
return fragmentShaderSource != null;
} catch (IOException e) {
PGraphics.showException("Cannot load shader " + url.getFile());
PGraphics.showException("Cannot load fragment shader " + url.getFile());
return false;
}
}
/**
* @param shaderSource a string containing the shader's code
*/
protected void attachVertexShader(String shaderSource) {
protected boolean compileVertexShader() {
vertexShader = pg.createGLSLVertShaderObject();
pgl.glShaderSource(vertexShader, shaderSource);
pgl.glShaderSource(vertexShader, vertexShaderSource);
pgl.glCompileShader(vertexShader);
pgl.glAttachShader(programObject, vertexShader);
int[] compiled = new int[1];
pgl.glGetShaderiv(vertexShader, PGL.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == PGL.GL_FALSE) {
PGraphics.showException("Cannot compile vertex shader:\n" + pgl.glGetShaderInfoLog(vertexShader));
return false;
} else {
return true;
}
}
/**
* @param shaderSource a string containing the shader's code
*/
protected void attachFragmentShader(String shaderSource) {
protected boolean compileFragmentShader() {
fragmentShader = pg.createGLSLFragShaderObject();
pgl.glShaderSource(fragmentShader, shaderSource);
pgl.glShaderSource(fragmentShader, fragmentShaderSource);
pgl.glCompileShader(fragmentShader);
pgl.glAttachShader(programObject, fragmentShader);
}
/**
* Check the log error for the opengl object obj. Prints error
* message if needed.
*/
protected void checkLogInfo(String title, int obj) {
String log = pgl.getShaderLog(obj);
if (!log.equals("")) {
System.out.println(title);
System.out.println(log);
}
int[] compiled = new int[1];
pgl.glGetShaderiv(fragmentShader, PGL.GL_COMPILE_STATUS, compiled, 0);
if (compiled[0] == PGL.GL_FALSE) {
PGraphics.showException("Cannot compile fragment shader:\n" + pgl.glGetShaderInfoLog(fragmentShader));
return false;
} else {
return true;
}
}