/* * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * */ package com.jogamp.opengl.util.glsl; import java.io.PrintStream; import java.nio.*; import java.util.*; import javax.media.opengl.*; import com.jogamp.common.nio.Buffers; public class ShaderUtil { public static String getShaderInfoLog(GL _gl, int shaderObj) { final GL2ES2 gl = _gl.getGL2ES2(); int[] infoLogLength=new int[1]; gl.glGetShaderiv(shaderObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0); if(infoLogLength[0]==0) { return "(no info log)"; } int[] charsWritten=new int[1]; byte[] infoLogBytes = new byte[infoLogLength[0]]; gl.glGetShaderInfoLog(shaderObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0); return new String(infoLogBytes, 0, charsWritten[0]); } public static String getProgramInfoLog(GL _gl, int programObj) { final GL2ES2 gl = _gl.getGL2ES2(); int[] infoLogLength=new int[1]; gl.glGetProgramiv(programObj, GL2ES2.GL_INFO_LOG_LENGTH, infoLogLength, 0); if(infoLogLength[0]==0) { return "(no info log)"; } int[] charsWritten=new int[1]; byte[] infoLogBytes = new byte[infoLogLength[0]]; gl.glGetProgramInfoLog(programObj, infoLogLength[0], charsWritten, 0, infoLogBytes, 0); return new String(infoLogBytes, 0, charsWritten[0]); } public static boolean isShaderStatusValid(GL _gl, int shaderObj, int name, PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); int[] ires = new int[1]; gl.glGetShaderiv(shaderObj, name, ires, 0); boolean res = ires[0]==1; if(!res && null!=verboseOut) { verboseOut.println("Shader status invalid: "+ getShaderInfoLog(gl, shaderObj)); } return res; } public static boolean isShaderStatusValid(GL _gl, IntBuffer shaders, int name, PrintStream verboseOut) { boolean res = true; for (int i = shaders.position(); i < shaders.limit(); i++) { res = isShaderStatusValid(_gl, shaders.get(i), name, verboseOut) && res; } return res; } public static boolean isProgramStatusValid(GL _gl, int programObj, int name) { final GL2ES2 gl = _gl.getGL2ES2(); int[] ires = new int[1]; gl.glGetProgramiv(programObj, name, ires, 0); return ires[0]==1; } public static boolean isProgramLinkStatusValid(GL _gl, int programObj, PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); if(!gl.glIsProgram(programObj)) { if(null!=verboseOut) { verboseOut.println("Program name invalid: "+programObj); } return false; } if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_LINK_STATUS)) { if(null!=verboseOut) { verboseOut.println("Program link failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj)); } return false; } return true; } /** * Performs {@link GL2ES2#glValidateProgram(int)} *
* One shall only call this method while debugging and only if all required * resources by the shader are set. *
** Note: It is possible that a working shader program will fail validation. * This has been experienced on NVidia APX2500 and Tegra2. *
* @see GL2ES2#glValidateProgram(int) **/ public static boolean isProgramExecStatusValid(GL _gl, int programObj, PrintStream verboseOut) { final GL2ES2 gl = _gl.getGL2ES2(); gl.glValidateProgram(programObj); if(!isProgramStatusValid(gl, programObj, GL2ES2.GL_VALIDATE_STATUS)) { if(null!=verboseOut) { verboseOut.println("Program validation failed: "+programObj+"\n\t"+ getProgramInfoLog(gl, programObj)); } return false; } return true; } public static void createShader(GL _gl, int type, IntBuffer shaders) { final GL2ES2 gl = _gl.getGL2ES2(); for (int i = shaders.position(); i < shaders.limit(); i++) { shaders.put(i, gl.glCreateShader(type)); } } /** * If supported, queries the natively supported shader binary formats using * {@link GL2ES2#GL_NUM_SHADER_BINARY_FORMATS} and {@link GL2ES2#GL_SHADER_BINARY_FORMATS} * via {@link GL2ES2#glGetIntegerv(int, int[], int)}. */ public static Set