/** * Replace a shader in a program and re-links the program. * * @param gl * @param oldShader the to be replace Shader * @param newShader the new ShaderCode * @param verboseOut the optional verbose output stream * @return true if all steps are valid, shader compilation, attachment and linking; otherwise * false. * @see ShaderState#glEnableVertexAttribArray * @see ShaderState#glDisableVertexAttribArray * @see ShaderState#glVertexAttribPointer * @see ShaderState#getVertexAttribPointer * @see ShaderState#glReleaseAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes * @see ShaderState#glResetAllVertexAttributes */ public synchronized boolean replaceShader( GL2ES2 gl, ShaderCode oldShader, ShaderCode newShader, PrintStream verboseOut) { if (!init(gl) || !newShader.compile(gl, verboseOut)) { return false; } boolean shaderWasInUse = inUse(); if (shaderWasInUse) { useProgram(gl, false); } if (null != oldShader && allShaderCode.remove(oldShader)) { if (attachedShaderCode.remove(oldShader)) { ShaderUtil.detachShader(gl, shaderProgram, oldShader.shader()); } } add(newShader); if (attachedShaderCode.add(newShader)) { ShaderUtil.attachShader(gl, shaderProgram, newShader.shader()); } gl.glLinkProgram(shaderProgram); programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, System.err); if (programLinked && shaderWasInUse) { useProgram(gl, true); } return programLinked; }
/** * Warning slow O(n) operation .. * * @param id * @return */ public synchronized ShaderCode getShader(int id) { for (Iterator<ShaderCode> iter = allShaderCode.iterator(); iter.hasNext(); ) { ShaderCode shaderCode = iter.next(); if (shaderCode.id() == id) { return shaderCode; } } return null; }
/** * Adds a new shader to a this non running program. * * <p>Compiles and attaches the shader, if not done yet. * * @return true if the shader was successfully added, false if compilation failed. */ public synchronized boolean add(GL2ES2 gl, ShaderCode shaderCode, PrintStream verboseOut) { if (!init(gl)) { return false; } if (allShaderCode.add(shaderCode)) { if (!shaderCode.compile(gl, verboseOut)) { return false; } if (attachedShaderCode.add(shaderCode)) { ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader()); } } return true; }
/** * Detaches all shader codes and deletes the program. If <code>destroyShaderCode</code> is true it * destroys the shader codes as well. */ public synchronized void release(GL2ES2 gl, boolean destroyShaderCode) { useProgram(gl, false); for (Iterator<ShaderCode> iter = allShaderCode.iterator(); iter.hasNext(); ) { ShaderCode shaderCode = iter.next(); if (attachedShaderCode.remove(shaderCode)) { ShaderUtil.detachShader(gl, shaderProgram, shaderCode.shader()); } if (destroyShaderCode) { shaderCode.destroy(gl); } } allShaderCode.clear(); attachedShaderCode.clear(); if (0 != shaderProgram) { gl.glDeleteProgram(shaderProgram); shaderProgram = 0; } }
/** * Links the shader code to the program. * * <p>Compiles and attaches the shader code to the program if not done by yet * * <p>Within this process, all GL resources (shader and program objects) are created if necessary. * * @param gl * @param verboseOut * @return true if program was successfully linked and is valid, otherwise false * @see #init(GL2ES2) */ public synchronized boolean link(GL2ES2 gl, PrintStream verboseOut) { if (!init(gl)) { programLinked = false; // mark unlinked due to user attempt to [re]link return false; } for (Iterator<ShaderCode> iter = allShaderCode.iterator(); iter.hasNext(); ) { final ShaderCode shaderCode = iter.next(); if (!shaderCode.compile(gl, verboseOut)) { programLinked = false; // mark unlinked due to user attempt to [re]link return false; } if (attachedShaderCode.add(shaderCode)) { ShaderUtil.attachShader(gl, shaderProgram, shaderCode.shader()); } } // Link the program gl.glLinkProgram(shaderProgram); programLinked = ShaderUtil.isProgramLinkStatusValid(gl, shaderProgram, System.err); return programLinked; }