/** * 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; }
/** * 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); } } }
/** * 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()); }