Java源码示例:com.badlogic.gdx.graphics.VertexAttribute
示例1
public static String morphTargetsPrefix(Renderable renderable){
String prefix = "";
// TODO optimize double loop
for(VertexAttribute att : renderable.meshPart.mesh.getVertexAttributes()){
for(int i=0 ; i<PBRCommon.MAX_MORPH_TARGETS ; i++){
if(att.usage == PBRVertexAttributes.Usage.PositionTarget && att.unit == i){
prefix += "#define " + "position" + i + "Flag\n";
}else if(att.usage == PBRVertexAttributes.Usage.NormalTarget && att.unit == i){
prefix += "#define " + "normal" + i + "Flag\n";
}else if(att.usage == PBRVertexAttributes.Usage.TangentTarget && att.unit == i){
prefix += "#define " + "tangent" + i + "Flag\n";
}
}
}
return prefix;
}
示例2
PositionalLight( RayHandler rayHandler, int rays, Color color, float distance, float x, float y, float directionDegree ) {
super( rayHandler, rays, color, directionDegree, distance );
start.x = x;
start.y = y;
sin = new float[ rays ];
cos = new float[ rays ];
endX = new float[ rays ];
endY = new float[ rays ];
lightMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum, 0, new VertexAttribute( Usage.Position, 2,
"vertex_positions" ), new VertexAttribute( Usage.ColorPacked, 4, "quad_colors" ), new VertexAttribute(
Usage.Generic, 1, "s" ) );
softShadowMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum * 2, 0, new VertexAttribute(
Usage.Position, 2, "vertex_positions" ), new VertexAttribute( Usage.ColorPacked, 4, "quad_colors" ),
new VertexAttribute( Usage.Generic, 1, "s" ) );
setMesh();
}
示例3
public Renderer20 (int maxVertices, boolean hasNormals, boolean hasColors, int numTexCoords, ShaderProgram shader) {
this.maxVertices = maxVertices;
this.numTexCoords = numTexCoords;
this.shader = shader;
VertexAttribute[] attribs = buildVertexAttributes(hasNormals, hasColors, numTexCoords);
mesh = new Mesh(false, maxVertices, 0, attribs);
vertices = new float[maxVertices * (mesh.getVertexAttributes().vertexSize / 4)];
vertexSize = mesh.getVertexAttributes().vertexSize / 4;
normalOffset = mesh.getVertexAttribute(Usage.Normal) != null ? mesh.getVertexAttribute(Usage.Normal).offset / 4 : 0;
colorOffset = mesh.getVertexAttribute(Usage.ColorPacked) != null ? mesh.getVertexAttribute(Usage.ColorPacked).offset / 4
: 0;
texCoordOffset = mesh.getVertexAttribute(Usage.TextureCoordinates) != null ? mesh
.getVertexAttribute(Usage.TextureCoordinates).offset / 4 : 0;
}
示例4
private Mesh buildMeshFromVertices(List<Double> vertexCoords) {
if ((vertexCoords.size() % 3) != 0) {
throw new RuntimeException("Vertex coordinates size is " + vertexCoords.size() + "; must be a multiple of 3");
}
float[] data = new float[vertexCoords.size()];
for (int i = 0; i < vertexCoords.size(); i++) {
data[i] = (float) vertexCoords.get(i).doubleValue();
}
Mesh mesh = new Mesh( true, vertexCoords.size() / 3, 0,
new VertexAttribute(VertexAttributes.Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
mesh.setVertices(data);
return mesh;
}
示例5
private Mesh buildMeshFromVerticesAndTexCoords(List<Double> vertexCoords, List<Double> texCoords) {
if ((vertexCoords.size() % 3) != 0) {
throw new RuntimeException("Vertex coordinates size is " + vertexCoords.size() + "; must be a multiple of 3");
}
if ((texCoords.size() % 2) != 0) {
throw new RuntimeException("Texture coordinates size is " + texCoords.size() + "; must be a multiple of 2");
}
if (vertexCoords.size() / 3 != texCoords.size() / 2) {
throw new RuntimeException("There is vertex data for " + vertexCoords.size() / 3 + " triangle(s), "
+ "and texture data for " + texCoords.size() / 2 + " triangle(s) -- these should match");
}
float[] data = new float[vertexCoords.size() + texCoords.size()];
int vertexIndex = 0;
int texIndex = 0;
int dataIndex = 0;
for (int i = 0; i < vertexCoords.size() / 3; i++) {
data[dataIndex++] = (float) vertexCoords.get(vertexIndex++).doubleValue();
data[dataIndex++] = (float) vertexCoords.get(vertexIndex++).doubleValue();
data[dataIndex++] = (float) vertexCoords.get(vertexIndex++).doubleValue();
data[dataIndex++] = (float) texCoords.get(texIndex++).doubleValue();
data[dataIndex++] = (float) texCoords.get(texIndex++).doubleValue();
}
Mesh mesh = new Mesh( true, vertexCoords.size() / 3, 0,
new VertexAttribute(VertexAttributes.Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE),
new VertexAttribute(VertexAttributes.Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + "0"));
mesh.setVertices(data);
return mesh;
}
示例6
protected String morphTargetsPrefix(Renderable renderable){
String prefix = "";
for(VertexAttribute att : renderable.meshPart.mesh.getVertexAttributes()){
for(int i=0 ; i<PBRCommon.MAX_MORPH_TARGETS ; i++){
if(att.usage == PBRVertexAttributes.Usage.PositionTarget && att.unit == i){
prefix += "#define " + "position" + i + "Flag\n";
}
}
}
return prefix;
}
示例7
private int computeVertexColorLayers(Renderable renderable) {
int num = 0;
VertexAttributes vertexAttributes = renderable.meshPart.mesh.getVertexAttributes();
final int n = vertexAttributes.size();
for (int i = 0; i < n; i++) {
final VertexAttribute attr = vertexAttributes.get(i);
if (attr.usage == VertexAttributes.Usage.ColorUnpacked) num++;
}
return num;
}
示例8
public long computeMorphTargetsMask(Renderable renderable){
int morphTargetsFlag = 0;
VertexAttributes vertexAttributes = renderable.meshPart.mesh.getVertexAttributes();
final int n = vertexAttributes.size();
for (int i = 0; i < n; i++) {
final VertexAttribute attr = vertexAttributes.get(i);
if (attr.usage == PBRVertexAttributes.Usage.PositionTarget) morphTargetsFlag |= (1 << attr.unit);
if (attr.usage == PBRVertexAttributes.Usage.NormalTarget) morphTargetsFlag |= (1 << (attr.unit + 8));
if (attr.usage == PBRVertexAttributes.Usage.TangentTarget) morphTargetsFlag |= (1 << (attr.unit + 16));
}
return morphTargetsFlag;
}
示例9
protected long computeMorphTargetsMask(Renderable renderable){
int morphTargetsFlag = 0;
VertexAttributes vertexAttributes = renderable.meshPart.mesh.getVertexAttributes();
final int n = vertexAttributes.size();
for (int i = 0; i < n; i++) {
final VertexAttribute attr = vertexAttributes.get(i);
if (attr.usage == PBRVertexAttributes.Usage.PositionTarget) morphTargetsFlag |= (1 << attr.unit);
}
return morphTargetsFlag;
}
示例10
private Mesh createFullscreenQuad () {
// vertex coord
verts[X1] = -1;
verts[Y1] = -1;
verts[X2] = 1;
verts[Y2] = -1;
verts[X3] = 1;
verts[Y3] = 1;
verts[X4] = -1;
verts[Y4] = 1;
// tex coords
verts[U1] = 0f;
verts[V1] = 0f;
verts[U2] = 1f;
verts[V2] = 0f;
verts[U3] = 1f;
verts[V3] = 1f;
verts[U4] = 0f;
verts[V4] = 1f;
Mesh tmpMesh = new Mesh(VertexDataType.VertexArray, true, 4, 0, new VertexAttribute(Usage.Position, 2, "a_position"),
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"));
tmpMesh.setVertices(verts);
return tmpMesh;
}
示例11
private void createBackPlane () {
plane = new Mesh(true, 4, 4, new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE),
new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
// @formatter:off
float size = 10f;
float verts[] = {-size / 2, 0, size / 2, size / 2, 0, size / 2, size / 2, 0, -size / 2, -size / 2, 0, -size / 2};
// float verts[] = {size, 0, size, size, 0, 0, 0, 0, 0, 0, 0, size};
float normals[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0};
// @formatter:on
int vidx = 0, nidx = 0;
int length = 6 * 4;
float[] vertices = new float[length];
for (int i = 0; i < length;) {
vertices[i++] = verts[vidx++];
vertices[i++] = verts[vidx++];
vertices[i++] = verts[vidx++];
vertices[i++] = normals[nidx++];
vertices[i++] = normals[nidx++];
vertices[i++] = normals[nidx++];
}
plane.setVertices(vertices);
plane.setIndices(new short[] {0, 1, 2, 3});
}
示例12
private static VertexAttribute[] createVertexAttributes (boolean hasNormals, int uvs) {
VertexAttribute[] attributes = new VertexAttribute[1 + (hasNormals ? 1 : 0) + uvs];
int idx = 0;
attributes[idx++] = new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE);
if (hasNormals) attributes[idx++] = new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE);
for (int i = 0; i < uvs; i++) {
attributes[idx++] = new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + i);
}
return attributes;
}
示例13
/**
* Directional lights simulate light source that locations is at infinite
* distance. Direction and intensity is same everywhere. -90 direction is
* straight from up.
*
* @param rayHandler
* @param rays
* @param color
* @param directionDegree
*/
public DirectionalLight( RayHandler rayHandler, int rays, Color color, float directionDegree ) {
super( rayHandler, rays, color, directionDegree, Float.POSITIVE_INFINITY );
vertexNum = (vertexNum - 1) * 2;
start = new Vector2[ rayNum ];
end = new Vector2[ rayNum ];
for( int i = 0; i < rayNum; i++ ) {
start[i] = new Vector2();
end[i] = new Vector2();
}
setDirection( direction );
// lightMesh = new Mesh(staticLight, vertexNum, 0, new VertexAttribute(
// Usage.Position, 2, "vertex_positions"), new VertexAttribute(
// Usage.ColorPacked, 4, "quad_colors"), new VertexAttribute(
// Usage.Generic, 1, "s"));
//
// softShadowMesh = new Mesh(staticLight, vertexNum, 0,
// new VertexAttribute(Usage.Position, 2, "vertex_positions"),
// new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
// new VertexAttribute(Usage.Generic, 1, "s"));
lightMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum, 0, new VertexAttribute( Usage.Position, 2,
"vertex_positions" ), new VertexAttribute( Usage.ColorPacked, 4, "quad_colors" ), new VertexAttribute(
Usage.Generic, 1, "s" ) );
softShadowMesh = new Mesh( VertexDataType.VertexArray, staticLight, vertexNum, 0, new VertexAttribute( Usage.Position, 2,
"vertex_positions" ), new VertexAttribute( Usage.ColorPacked, 4, "quad_colors" ), new VertexAttribute(
Usage.Generic, 1, "s" ) );
update();
}
示例14
private Mesh createLightMapMesh() {
// vertex coord
verts[X1] = -1;
verts[Y1] = -1;
verts[X2] = 1;
verts[Y2] = -1;
verts[X3] = 1;
verts[Y3] = 1;
verts[X4] = -1;
verts[Y4] = 1;
// tex coords
verts[U1] = 0f;
verts[V1] = 0f;
verts[U2] = 1f;
verts[V2] = 0f;
verts[U3] = 1f;
verts[V3] = 1f;
verts[U4] = 0f;
verts[V4] = 1f;
Mesh tmpMesh = new Mesh( true, 4, 0, new VertexAttribute( Usage.Position, 2, "a_position" ), new VertexAttribute(
Usage.TextureCoordinates, 2, "a_texCoord" ) );
tmpMesh.setVertices( verts );
return tmpMesh;
}
示例15
private VertexAttribute[] parseAttributes(JsonValue attributes) {
Array<VertexAttribute> vertexAttributes = new Array<VertexAttribute>();
int unit = 0;
int blendWeightCount = 0;
for (JsonValue value = attributes.child; value != null; value = value.next) {
String attribute = value.asString();
String attr = (String) attribute;
if (attr.equals("POSITION")) {
vertexAttributes.add(VertexAttribute.Position());
} else if (attr.equals("NORMAL")) {
vertexAttributes.add(VertexAttribute.Normal());
} else if (attr.equals("COLOR")) {
vertexAttributes.add(VertexAttribute.ColorUnpacked());
} else if (attr.equals("COLORPACKED")) {
vertexAttributes.add(VertexAttribute.ColorPacked());
} else if (attr.equals("TANGENT")) {
vertexAttributes.add(VertexAttribute.Tangent());
} else if (attr.equals("BINORMAL")) {
vertexAttributes.add(VertexAttribute.Binormal());
} else if (attr.startsWith("TEXCOORD")) {
vertexAttributes.add(VertexAttribute.TexCoords(unit++));
} else if (attr.startsWith("BLENDWEIGHT")) {
vertexAttributes.add(VertexAttribute.BoneWeight(blendWeightCount++));
} else {
throw new GdxRuntimeException("Unknown vertex attribute '" + attr
+ "', should be one of position, normal, uv, tangent or binormal");
}
}
return vertexAttributes.toArray(VertexAttribute.class);
}
示例16
/**
* Creates chain light from specified vertices
*
* @param rayHandler
* not {@code null} instance of RayHandler
* @param rays
* number of rays - more rays make light to look more realistic
* but will decrease performance, can't be less than MIN_RAYS
* @param color
* color, set to {@code null} to use the default color
* @param distance
* distance of light
* @param rayDirection
* direction of rays
* <ul>
* <li>1 = left</li>
* <li>-1 = right</li>
* </ul>
* @param chain
* float array of (x, y) vertices from which rays will be
* evenly distributed
*/
public ChainLight(RayHandler rayHandler, int rays, Color color,
float distance, int rayDirection, float[] chain) {
super(rayHandler, rays, color, distance, 0f);
rayStartOffset = ChainLight.defaultRayStartOffset;
this.rayDirection = rayDirection;
vertexNum = (vertexNum - 1) * 2;
endX = new float[rays];
endY = new float[rays];
startX = new float[rays];
startY = new float[rays];
this.chain = (chain != null) ?
new FloatArray(chain) : new FloatArray();
lightMesh = new Mesh(
VertexDataType.VertexArray, false, vertexNum, 0,
new VertexAttribute(Usage.Position, 2, "vertex_positions"),
new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
softShadowMesh = new Mesh(
VertexDataType.VertexArray, false, vertexNum * 2,
0, new VertexAttribute(Usage.Position, 2, "vertex_positions"),
new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
setMesh();
}
示例17
/**
* Creates directional light which source is at infinite distance,
* direction and intensity is same everywhere
*
* <p>-90 direction is straight from up
*
* @param rayHandler
* not {@code null} instance of RayHandler
* @param rays
* number of rays - more rays make light to look more realistic
* but will decrease performance, can't be less than MIN_RAYS
* @param color
* color, set to {@code null} to use the default color
* @param directionDegree
* direction in degrees
*/
public DirectionalLight(RayHandler rayHandler, int rays, Color color,
float directionDegree) {
super(rayHandler, rays, color, Float.POSITIVE_INFINITY, directionDegree);
vertexNum = (vertexNum - 1) * 2;
start = new Vector2[rayNum];
end = new Vector2[rayNum];
for (int i = 0; i < rayNum; i++) {
start[i] = new Vector2();
end[i] = new Vector2();
}
lightMesh = new Mesh(
VertexDataType.VertexArray, staticLight, vertexNum, 0,
new VertexAttribute(Usage.Position, 2, "vertex_positions"),
new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
softShadowMesh = new Mesh(
VertexDataType.VertexArray, staticLight, vertexNum, 0,
new VertexAttribute(Usage.Position, 2, "vertex_positions"),
new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
update();
}
示例18
private Mesh createLightMapMesh() {
float[] verts = new float[VERT_SIZE];
// vertex coord
verts[X1] = -1;
verts[Y1] = -1;
verts[X2] = 1;
verts[Y2] = -1;
verts[X3] = 1;
verts[Y3] = 1;
verts[X4] = -1;
verts[Y4] = 1;
// tex coords
verts[U1] = 0f;
verts[V1] = 0f;
verts[U2] = 1f;
verts[V2] = 0f;
verts[U3] = 1f;
verts[V3] = 1f;
verts[U4] = 0f;
verts[V4] = 1f;
Mesh tmpMesh = new Mesh(true, 4, 0, new VertexAttribute(
Usage.Position, 2, "a_position"), new VertexAttribute(
Usage.TextureCoordinates, 2, "a_texCoord"));
tmpMesh.setVertices(verts);
return tmpMesh;
}
示例19
private VertexAttribute[] buildVertexAttributes (boolean hasNormals, boolean hasColor, int numTexCoords) {
Array<VertexAttribute> attribs = new Array<VertexAttribute>();
attribs.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
if (hasNormals) attribs.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
if (hasColor) attribs.add(new VertexAttribute(Usage.ColorPacked, 4, ShaderProgram.COLOR_ATTRIBUTE));
for (int i = 0; i < numTexCoords; i++) {
attribs.add(new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + i));
}
VertexAttribute[] array = new VertexAttribute[attribs.size];
for (int i = 0; i < attribs.size; i++)
array[i] = attribs.get(i);
return array;
}
示例20
private VertexAttribute[] parseAttributes (JsonValue attributes) {
Array<VertexAttribute> vertexAttributes = new Array<VertexAttribute>();
int unit = 0;
int blendWeightCount = 0;
for (JsonValue value = attributes.child; value != null; value = value.next) {
String attribute = value.asString();
String attr = (String)attribute;
if (attr.equals("POSITION")) {
vertexAttributes.add(VertexAttribute.Position());
} else if (attr.equals("NORMAL")) {
vertexAttributes.add(VertexAttribute.Normal());
} else if (attr.equals("COLOR")) {
vertexAttributes.add(VertexAttribute.ColorUnpacked());
} else if (attr.equals("COLORPACKED")) {
vertexAttributes.add(VertexAttribute.Color());
} else if (attr.equals("TANGENT")) {
vertexAttributes.add(VertexAttribute.Tangent());
} else if (attr.equals("BINORMAL")) {
vertexAttributes.add(VertexAttribute.Binormal());
} else if (attr.startsWith("TEXCOORD")) {
vertexAttributes.add(VertexAttribute.TexCoords(unit++));
} else if (attr.startsWith("BLENDWEIGHT")) {
vertexAttributes.add(VertexAttribute.BoneWeight(blendWeightCount++));
} else {
throw new GdxRuntimeException("Unknown vertex attribute '" + attr
+ "', should be one of position, normal, uv, tangent or binormal");
}
}
return vertexAttributes.toArray(VertexAttribute.class);
}
示例21
private Mesh createFullscreenQuad() {
// vertex coord
verts[X1] = -1;
verts[Y1] = -1;
verts[X2] = 1;
verts[Y2] = -1;
verts[X3] = 1;
verts[Y3] = 1;
verts[X4] = -1;
verts[Y4] = 1;
// tex coords
verts[U1] = 0f;
verts[V1] = 0f;
verts[U2] = 1f;
verts[V2] = 0f;
verts[U3] = 1f;
verts[V3] = 1f;
verts[U4] = 0f;
verts[V4] = 1f;
Mesh tmpMesh = new Mesh( VertexDataType.VertexArray, true, 4, 0, new VertexAttribute( Usage.Position, 2, "a_position" ),
new VertexAttribute( Usage.TextureCoordinates, 2, "a_texCoord0" ) );
tmpMesh.setVertices( verts );
return tmpMesh;
}
示例22
public ViewportQuadMesh() {
this(new VertexAttribute(Usage.Position, 2, "a_position"),
new VertexAttribute(Usage.TextureCoordinates, 2, "a_texCoord0"));
}
示例23
public ViewportQuadMesh(VertexAttribute... vertexAttributes) {
mesh = new Mesh(true, 4, 0, vertexAttributes);
mesh.setVertices(verts);
}
示例24
private static StillSubMesh readStillSubMesh (BufferedReader in, boolean flipV) throws IOException {
String name = readString(in);
IntArray indices = readFaces(in);
int numVertices = readInt(in);
int numAttributes = readInt(in);
if (!readString(in).equals("position")) throw new GdxRuntimeException("first attribute must be position.");
int numUvs = 0;
boolean hasNormals = false;
for (int i = 1; i < numAttributes; i++) {
String attributeType = readString(in);
if (!attributeType.equals("normal") && !attributeType.equals("uv"))
throw new GdxRuntimeException("attribute name must be normal or uv");
if (attributeType.equals("normal")) {
if (i != 1) throw new GdxRuntimeException("attribute normal must be second attribute");
hasNormals = true;
}
if (attributeType.equals("uv")) {
numUvs++;
}
}
VertexAttribute[] vertexAttributes = createVertexAttributes(hasNormals, numUvs);
int vertexSize = new VertexAttributes(vertexAttributes).vertexSize / 4;
float[] vertices = new float[numVertices * vertexSize];
int idx = 0;
int uvOffset = hasNormals ? 6 : 3;
for (int i = 0; i < numVertices; i++) {
readFloatArray(in, vertices, idx);
if (flipV) {
for (int j = idx + uvOffset + 1; j < idx + uvOffset + numUvs * 2; j += 2) {
vertices[j] = 1 - vertices[j];
}
}
idx += vertexSize;
}
Mesh mesh = new Mesh(true, numVertices, indices.size, vertexAttributes);
mesh.setVertices(vertices);
mesh.setIndices(convertToShortArray(indices));
return new StillSubMesh(name, mesh, GL20.GL_TRIANGLES);
}
示例25
/**
* Creates new positional light and automatically adds it to the specified
* {@link RayHandler} instance.
*
* @param rayHandler
* not null instance of RayHandler
* @param rays
* number of rays - more rays make light to look more realistic
* but will decrease performance, can't be less than MIN_RAYS
* @param color
* light color
* @param distance
* light distance (if applicable)
* @param x
* horizontal position in world coordinates
* @param y
* vertical position in world coordinates
* @param directionDegree
* direction in degrees (if applicable)
*/
public PositionalLight(RayHandler rayHandler, int rays, Color color, float distance, float x, float y, float directionDegree) {
super(rayHandler, rays, color, distance, directionDegree);
start.x = x;
start.y = y;
lightMesh = new Mesh(VertexDataType.VertexArray, false, vertexNum, 0, new VertexAttribute(Usage.Position, 2,
"vertex_positions"), new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
softShadowMesh = new Mesh(VertexDataType.VertexArray, false, vertexNum * 2, 0, new VertexAttribute(Usage.Position, 2,
"vertex_positions"), new VertexAttribute(Usage.ColorPacked, 4, "quad_colors"),
new VertexAttribute(Usage.Generic, 1, "s"));
setMesh();
}