From 4e428ecc61c6c66460daa04ee1d6a077e17c1075 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Wed, 21 Mar 2012 16:26:48 +0000 Subject: [PATCH] Improved shader error log --- .../opengl/src/processing/opengl/PGL.java | 66 ++++++---- .../opengl/src/processing/opengl/PShader.java | 123 +++++++++++------- 2 files changed, 121 insertions(+), 68 deletions(-) diff --git a/java/libraries/opengl/src/processing/opengl/PGL.java b/java/libraries/opengl/src/processing/opengl/PGL.java index 163d1df8f..5bea8d280 100644 --- a/java/libraries/opengl/src/processing/opengl/PGL.java +++ b/java/libraries/opengl/src/processing/opengl/PGL.java @@ -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 diff --git a/java/libraries/opengl/src/processing/opengl/PShader.java b/java/libraries/opengl/src/processing/opengl/PShader.java index 325e35a5f..1900ead54 100644 --- a/java/libraries/opengl/src/processing/opengl/PShader.java +++ b/java/libraries/opengl/src/processing/opengl/PShader.java @@ -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; + } }