ShaderProgram UtilityEste pagina demonstra passos necessarios para se criar o sua propria classe re-utilizavel atraves do utilitario ShaderProgram. Voce tambem pode usar o mais avancado utilitario de ShaderProgram ja incluido no LWJGL-basico: ver aqui.Para nossos propositos, vamos usar apenas um vertice e um fragmento de shader para criar os nossos programas de sombreamento. Planejamos visar o GL 2.1, que tambem tera de especificar os locais de atributos manualmente. Se for usar versoes mais recentes do OpenGL (ou seja, GLSL 330 +), entao podemos especificar os locais de atributos com qualificadores do tipo em seu lugar. Os passos basicos para a criacao de um programa de shader como este sao:Compilar o codigo fonte em um vertice shader shader objeto.Compilar o codigo fonte em um fragmento de shader shader objeto.Criar um programa com ID glCreateProgram.Anexar os objetos vertex e shader para o nosso programa com glAttachShader.Se nos estamos usando 2.1, e aqui que ligaria quaisquer atributos manualmente. Por exemplo, poderiamos vincular o atributo posicao de indice 0. Para isso, usamos glBindAttribLocation. Se nos estamos usando versoes mais recentes do GLSL, podemos pular essa etapa.Em seguida, ligar o programa com glLinkProgram.Se o programa conseguiu compilar, agora podemos separar e excluir os objetos de sombreamento da vertice e fragmento como eles nao sao mais necessarios - usando glDetachShader e glDeleteShader, respectivamente. Estes sao apenas avisam para o OpenGL, que os objetos serao apagados quando eles nao estao mais associados com quaisquer estados de renderizacao.Exemplo: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);}protected int compileShader(String source, int type) throws LWJGLException { //create a shader object int shader = glCreateShader(type); //pass the source string glShaderSource(shader, source); //compile the source glCompileShader(shader); //if info/warnings are found, append it to our shader log String infoLog = glGetShaderInfoLog(shader, glGetShaderi(shader, GL_INFO_LOG_LENGTH)); if (infoLog!=null && infoLog.trim().length()!=0) log += getName(type) +": "+infoLog + "\n"; //if the compiling was unsuccessful, throw an exception if (glGetShaderi(shader, GL_COMPILE_STATUS) == GL_FALSE) throw new LWJGLException("Failure in compiling " + getName(type) + ". Error log:\n" + infoLog); return shader;}Usando o programa:Em OpenGL, so podemos ter um programa unico de shader em uso ao mesmo tempo. Chamamos glUseProgram (programa) para especificar o programa ativo. Devemos especificar o glUseProgram (0) para usar o "default" do shader. No entanto, uma vez que estamos tentando trabalhar com o pipeline programavel, nao devemos mais nos preocupar com o shader padrao, ja que nao existe tal coisa no GL moderna. Na verdade,