1 /******************************************************************************* 2 * Copyright 2011 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.graphics; 18 19 import com.badlogic.gdx.graphics.VertexAttributes.Usage; 20 import com.badlogic.gdx.graphics.glutils.ShaderProgram; 21 22 /** A single vertex attribute defined by its {@link Usage}, its number of components and its shader alias. The Usage is needed for 23 * the fixed function pipeline of OpenGL ES 1.x. Generic attributes are not supported in the fixed function pipeline. The number 24 * of components defines how many components the attribute has. The alias defines to which shader attribute this attribute should 25 * bind. The alias is used by a {@link Mesh} when drawing with a {@link ShaderProgram}. The alias can be changed at any time. 26 * 27 * @author mzechner */ 28 public final class VertexAttribute { 29 /** the attribute {@link Usage} **/ 30 public final int usage; 31 /** the number of components this attribute has **/ 32 public final int numComponents; 33 /** whether the values are normalized to either -1f and +1f (signed) or 0f and +1f (unsigned) */ 34 public final boolean normalized; 35 /** the OpenGL type of each component, e.g. {@link GL20#GL_FLOAT} or {@link GL20#GL_UNSIGNED_BYTE} */ 36 public final int type; 37 /** the offset of this attribute in bytes, don't change this! **/ 38 public int offset; 39 /** the alias for the attribute used in a {@link ShaderProgram} **/ 40 public String alias; 41 /** optional unit/index specifier, used for texture coordinates and bone weights **/ 42 public int unit; 43 private final int usageIndex; 44 45 /** Constructs a new VertexAttribute. 46 * 47 * @param usage the usage, used for the fixed function pipeline. Generic attributes are not supported in the fixed function 48 * pipeline. 49 * @param numComponents the number of components of this attribute, must be between 1 and 4. 50 * @param alias the alias used in a shader for this attribute. Can be changed after construction. */ 51 public VertexAttribute (int usage, int numComponents, String alias) { 52 this(usage, numComponents, alias, 0); 53 } 54 55 /** Constructs a new VertexAttribute. 56 * 57 * @param usage the usage, used for the fixed function pipeline. Generic attributes are not supported in the fixed function 58 * pipeline. 59 * @param numComponents the number of components of this attribute, must be between 1 and 4. 60 * @param alias the alias used in a shader for this attribute. Can be changed after construction. 61 * @param index unit/index of the attribute, used for boneweights and texture coordinates. */ 62 public VertexAttribute (int usage, int numComponents, String alias, int index) { 63 this(usage, numComponents, usage == Usage.ColorPacked ? GL20.GL_UNSIGNED_BYTE : GL20.GL_FLOAT, 64 usage == Usage.ColorPacked, alias, index); 65 } 66 67 private VertexAttribute (int usage, int numComponents, int type, boolean normalized, String alias) { 68 this(usage, numComponents, type, normalized, alias, 0); 69 } 70 71 private VertexAttribute (int usage, int numComponents, int type, boolean normalized, String alias, int index) { 72 this.usage = usage; 73 this.numComponents = numComponents; 74 this.type = type; 75 this.normalized = normalized; 76 this.alias = alias; 77 this.unit = index; 78 this.usageIndex = Integer.numberOfTrailingZeros(usage); 79 } 80 81 public static VertexAttribute Position () { 82 return new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE); 83 } 84 85 public static VertexAttribute TexCoords (int unit) { 86 return new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + unit, unit); 87 } 88 89 public static VertexAttribute Normal () { 90 return new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE); 91 } 92 93 public static VertexAttribute ColorPacked () { 94 return new VertexAttribute(Usage.ColorPacked, 4, GL20.GL_UNSIGNED_BYTE, true, ShaderProgram.COLOR_ATTRIBUTE); 95 } 96 97 public static VertexAttribute ColorUnpacked () { 98 return new VertexAttribute(Usage.ColorUnpacked, 4, GL20.GL_FLOAT, false, ShaderProgram.COLOR_ATTRIBUTE); 99 } 100 101 public static VertexAttribute Tangent () { 102 return new VertexAttribute(Usage.Tangent, 3, ShaderProgram.TANGENT_ATTRIBUTE); 103 } 104 105 public static VertexAttribute Binormal () { 106 return new VertexAttribute(Usage.BiNormal, 3, ShaderProgram.BINORMAL_ATTRIBUTE); 107 } 108 109 public static VertexAttribute BoneWeight (int unit) { 110 return new VertexAttribute(Usage.BoneWeight, 2, "a_boneWeight" + unit, unit); 111 } 112 113 /** Tests to determine if the passed object was created with the same parameters */ 114 @Override 115 public boolean equals (final Object obj) { 116 if (!(obj instanceof VertexAttribute)) { 117 return false; 118 } 119 return equals((VertexAttribute)obj); 120 } 121 122 public boolean equals (final VertexAttribute other) { 123 return other != null && usage == other.usage && numComponents == other.numComponents && alias.equals(other.alias) 124 && unit == other.unit; 125 } 126 127 /** @return A unique number specifying the usage index (3 MSB) and unit (1 LSB). */ 128 public int getKey () { 129 return (usageIndex << 8) + (unit & 0xFF); 130 } 131 132 @Override 133 public int hashCode () { 134 int result = getKey(); 135 result = 541 * result + numComponents; 136 result = 541 * result + alias.hashCode(); 137 return result; 138 } 139 } 140