/** * Validates and returns the location of a shader attribute.<br> * Uses either the cached value {@link #getCachedAttribLocation(String)} if valid, or the GLSL * queried via {@link GL2ES2#glGetAttribLocation(int, String)}.<br> * The location will be cached and set in the {@link GLArrayData} object. * * @return -1 if there is no such attribute available, otherwise >= 0 * @throws GLException if no program is attached * @throws GLException if the program is not linked and no location was cached. * @see #getCachedAttribLocation(String) * @see #bindAttribLocation(GL2ES2, int, GLArrayData) * @see #bindAttribLocation(GL2ES2, int, String) * @see GL2ES2#glGetAttribLocation(int, String) * @see #getAttribute(String) */ public int getAttribLocation(GL2ES2 gl, GLArrayData data) { if (null == shaderProgram) throw new GLException("No program is attached"); final String name = data.getName(); int location = getCachedAttribLocation(name); if (0 <= location) { data.setLocation(location); } else { if (!shaderProgram.linked()) throw new GLException("Program is not linked"); location = data.setLocation(gl, shaderProgram.program()); if (0 <= location) { Integer idx = new Integer(location); activeAttribLocationMap.put(name, idx); if (DEBUG) { System.err.println("ShaderState: glGetAttribLocation: " + name + ", loc: " + location); } } else if (verbose) { System.err.println( "ShaderState: glGetAttribLocation failed, no location for: " + name + ", loc: " + location); if (DEBUG) { Thread.dumpStack(); } } } activeAttribDataMap.put(data.getName(), data); return location; }
public StringBuilder toString(StringBuilder sb, boolean alsoUnlocated) { if (null == sb) { sb = new StringBuilder(); } sb.append("ShaderState[ "); sb.append(Platform.getNewline()).append(" "); if (null != shaderProgram) { shaderProgram.toString(sb); } else { sb.append("ShaderProgram: null"); } sb.append(Platform.getNewline()).append(" enabledAttributes ["); { Iterator<String> names = activedAttribEnabledMap.keySet().iterator(); Iterator<Boolean> values = activedAttribEnabledMap.values().iterator(); while (names.hasNext()) { sb.append(Platform.getNewline()) .append(" ") .append(names.next()) .append(": ") .append(values.next()); } } sb.append(Platform.getNewline()).append(" ],").append(" activeAttributes ["); for (Iterator<GLArrayData> iter = activeAttribDataMap.values().iterator(); iter.hasNext(); ) { final GLArrayData ad = iter.next(); if (alsoUnlocated || 0 <= ad.getLocation()) { sb.append(Platform.getNewline()).append(" ").append(ad); } } sb.append(Platform.getNewline()).append(" ],").append(" managedAttributes ["); for (Iterator<GLArrayData> iter = managedAttributes.iterator(); iter.hasNext(); ) { final GLArrayData ad = iter.next(); if (alsoUnlocated || 0 <= ad.getLocation()) { sb.append(Platform.getNewline()).append(" ").append(ad); } } sb.append(Platform.getNewline()).append(" ],").append(" activeUniforms ["); for (Iterator<GLUniformData> iter = activeUniformDataMap.values().iterator(); iter.hasNext(); ) { final GLUniformData ud = iter.next(); if (alsoUnlocated || 0 <= ud.getLocation()) { sb.append(Platform.getNewline()).append(" ").append(ud); } } sb.append(Platform.getNewline()).append(" ],").append(" managedUniforms ["); for (Iterator<GLUniformData> iter = managedUniforms.iterator(); iter.hasNext(); ) { final GLUniformData ud = iter.next(); if (alsoUnlocated || 0 <= ud.getLocation()) { sb.append(Platform.getNewline()).append(" ").append(ud); } } sb.append(Platform.getNewline()).append(" ]").append(Platform.getNewline()).append("]"); return sb; }
/** * Enables a vertex attribute array, usually invoked by {@link * GLArrayDataEditable#enableBuffer(GL, boolean)}. * * <p>This method uses the {@link GLArrayData}'s location if set and is the preferred alternative * to {@link #enableVertexAttribArray(GL2ES2, String)}. If data location is unset it will be * retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)} set and cached in this state. * * <p>Even if the attribute is not found in the current shader, it is marked enabled in this * state. * * @return false, if the name is not found, otherwise true * @throws GLException if the program is not linked and no location was cached. * @see #glEnableVertexAttribArray * @see #glDisableVertexAttribArray * @see #glVertexAttribPointer * @see #getVertexAttribPointer * @see GLArrayDataEditable#enableBuffer(GL, boolean) */ public boolean enableVertexAttribArray(GL2ES2 gl, GLArrayData data) { if (0 > data.getLocation()) { getAttribLocation(gl, data); } else { // ensure data is the current bound one activeAttribDataMap.put(data.getName(), data); } return enableVertexAttribArray(gl, data.getName(), data.getLocation()); }
/** * Binds a shader {@link GLArrayData} attribute to a location. Multiple names can be bound to one * location. The value will be cached and can be retrieved via {@link * #getCachedAttribLocation(String)} and {@link #getAttribute(String)}before or after linking. The * {@link GLArrayData}'s location will be set as well. * * @throws GLException if no program is attached * @throws GLException if the program is already linked * @see javax.media.opengl.GL2ES2#glBindAttribLocation(int, int, String) * @see #getAttribLocation(GL2ES2, String) * @see #getCachedAttribLocation(String) * @see #getAttribute(String) */ public void bindAttribLocation(GL2ES2 gl, int location, GLArrayData data) { if (null == shaderProgram) throw new GLException("No program is attached"); if (shaderProgram.linked()) throw new GLException("Program is already linked"); final String name = data.getName(); final Integer loc = new Integer(location); activeAttribLocationMap.put(name, loc); data.setLocation(gl, shaderProgram.program(), location); activeAttribDataMap.put(data.getName(), data); }
/** * Binds or unbinds the {@link GLArrayData} lifecycle to this ShaderState. * * <p>If an attribute location is cached (ie {@link #bindAttribLocation(GL2ES2, int, String)}) it * is promoted to the {@link GLArrayData} instance. * * <p>The attribute will be destroyed with {@link #destroy(GL2ES2)} and it's location will be * reset when switching shader with {@link #attachShaderProgram(GL2ES2, ShaderProgram)}. * * <p>The data will not be transfered to the GPU, use {@link #vertexAttribPointer(GL2ES2, * GLArrayData)} additionally. * * <p>The data will also be {@link GLArrayData#associate(Object, boolean) associated} with this * ShaderState. * * @param attribute the {@link GLArrayData} which lifecycle shall be managed * @param own true if <i>owning</i> shall be performs, false if <i>disowning</i>. * @see #bindAttribLocation(GL2ES2, int, String) * @see #getAttribute(String) * @see GLArrayData#associate(Object, boolean) */ public void ownAttribute(GLArrayData attribute, boolean own) { if (own) { final int location = getCachedAttribLocation(attribute.getName()); if (0 <= location) { attribute.setLocation(location); } managedAttributes.add(managedAttributes.size(), attribute); } else { managedAttributes.remove(attribute); } attribute.associate(this, own); }
private final void relocateAttribute(GL2ES2 gl, GLArrayData attribute) { // get new location .. final String name = attribute.getName(); final int loc = getAttribLocation(gl, name); attribute.setLocation(loc); if (0 <= loc) { if (isVertexAttribArrayEnabled(name)) { // enable attrib, VBO and pass location/data gl.glEnableVertexAttribArray(loc); } if (attribute.isVBO()) { gl.glBindBuffer(GL.GL_ARRAY_BUFFER, attribute.getVBOName()); gl.glVertexAttribPointer(attribute); gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0); } else { gl.glVertexAttribPointer(attribute); } } }
/** * Set the {@link GLArrayData} vertex attribute data. * * <p>This method uses the {@link GLArrayData}'s location if set. If data location is unset it * will be retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)}, set and cached in this * state. * * @return false, if the location could not be determined, otherwise true * @throws GLException if no program is attached * @throws GLException if the program is not linked and no location was cached. * @see #glEnableVertexAttribArray * @see #glDisableVertexAttribArray * @see #glVertexAttribPointer * @see #getVertexAttribPointer */ public boolean vertexAttribPointer(GL2ES2 gl, GLArrayData data) { int location = data.getLocation(); if (0 > location) { location = getAttribLocation(gl, data); } if (0 <= location) { // only pass the data, if the attribute exists in the current shader if (DEBUG) { System.err.println("ShaderState: glVertexAttribPointer: " + data); } gl.glVertexAttribPointer(data); return true; } return false; }
/** * Disables a vertex attribute array * * <p>This method uses the {@link GLArrayData}'s location if set and is the preferred alternative * to {@link #disableVertexAttribArray(GL2ES2, String)}. If data location is unset it will be * retrieved via {@link #getAttribLocation(GL2ES2, GLArrayData)} set and cached in this state. * * <p>Even if the attribute is not found in the current shader, it is removed from this state * enabled list. * * @return false, if the name is not found, otherwise true * @throws GLException if no program is attached * @throws GLException if the program is not linked and no location was cached. * @see #glEnableVertexAttribArray * @see #glDisableVertexAttribArray * @see #glVertexAttribPointer * @see #getVertexAttribPointer */ public boolean disableVertexAttribArray(GL2ES2 gl, GLArrayData data) { if (0 > data.getLocation()) { getAttribLocation(gl, data); } return disableVertexAttribArray(gl, data.getName(), data.getLocation()); }
/** @return true if the {@link GLArrayData} attribute is enable */ public final boolean isVertexAttribArrayEnabled(GLArrayData data) { return isVertexAttribArrayEnabled(data.getName()); }
public boolean isActiveAttribute(GLArrayData attribute) { return attribute == activeAttribDataMap.get(attribute.getName()); }