ele pode causar erros se tentarmos renderizacao com o shader padrao no GL 3.1 + Assim, nossos metodos para se criar um programa final ficara assim::/** * Make this shader the active program. */public void use() { glUseProgram(program);}/** * Destroy this shader program. */public void destroy() { //a flag for GL -- the program will not actually be deleted until it's no longer in use glDeleteProgram(program);}/** * Gets the location of the specified uniform name. * @param str the name of the uniform * @return the location of the uniform in this program */public int getUniformLocation(String str) { return glGetUniformLocation(program, str);}Definir valores uniformes:Tal como discutido anteriormente na serie, usamos glUniform para passar dados uniformes para os nossos shaders. Um utilitario ShaderProgram completa pode incluir diversos utilitarios para obter e definir uniformes (veja aqui). Nosso exemplo simples ira lidar com o minimo de: matrizes e uniformes inteiros (para sampler2D)./** * Sets the uniform data at the specified location (the uniform type may be int, bool or sampler2D). * @param loc the location of the int/bool/sampler2D uniform * @param i the value to set */public void setUniformi(int loc, int i) { if (loc==-1) return; glUniform1i(loc, i);}/** * Sends a 4x4 matrix to the shader program. * @param loc the location of the mat4 uniform * @param transposed whether the matrix should be transposed * @param mat the matrix to send */public void setUniformMatrix(int loc, boolean transposed, Matrix4f mat) { if (loc==-1) return; if (buf16Pool == null) buf16Pool = BufferUtils.createFloatBuffer(16); buf16Pool.clear(); mat.store(buf16Pool); buf16Pool.flip(); glUniformMatrix4(loc, transposed, buf16Pool);}Codigo fonte completo:public class ShaderProgram { protected static FloatBuffer buf16Pool; /** * Makes the "default shader" (0) the active program. In GL 3.1+ core profile, * you may run into glErrors if you try rendering with the default shader. */ public static void unbind() { glUseProgram(0); } public final int program; public final int vertex; public final int fragment; protected String log; public ShaderProgram(String vertexSource, String fragmentSource) throws LWJGLException { this(vertexSource, fragmentSource, null); } /** * Creates a new shader from vertex and fragment source, and with the given * map of attrib locations * @param vertexShader the vertex shader source string * @param fragmentShader the fragment shader source string * @param attributes a map of attrib locations for GLSL 120 * @throws LWJGLException if the program could not be compiled and linked */ public ShaderProgram(String vertexShader, String fragmentShader, Map<Integer, String> attributes) throws LWJGLException { //compile the String source vertex = compileShader(vertexShader, GL_VERTEX_SHADER); fragment = compileShader(fragmentShader, GL_FRAGMENT_SHADER); //create the program program = glCreateProgram(); //attach the shaders glAttachShader(program, vertex); glAttachShader(program, fragment); //bind the attrib locations for GLSL 120 if (attributes != null) for (Entry<Integer, String> e : attributes.entrySet()) glBindAttribLocation(program, e.getKey(), e.getValue()); //link our program glLinkProgram(program); //grab our info log String infoLog = glGetProgramInfoLog(program, glGetProgrami(program, GL_INFO_LOG_LENGTH)); //if some log exists, append it if (infoLog!=null && infoLog.trim().length()!=0) log += infoLog; //if the link failed, throw some sort of exception if (glGetProgrami(program, GL_LINK_STATUS) == GL_FALSE) throw new LWJGLException( "Failure in linking program. Error log:\n" + infoLog); //detach and delete the shaders which are no longer needed glDetachShader(program, vertex); glDetachShader(program, fragment); glDeleteShader(vertex); glDeleteShader(fragment); } /**