/** Begin building a mesh */ public void begin(final VertexAttributes attributes, int primitiveType) { if (this.attributes != null) throw new RuntimeException("Call end() first"); this.attributes = attributes; this.vertices.clear(); this.indices.clear(); this.parts.clear(); this.vindex = 0; this.istart = 0; this.part = null; this.stride = attributes.vertexSize / 4; this.vertex = new float[stride]; VertexAttribute a = attributes.findByUsage(Usage.Position); if (a == null) throw new GdxRuntimeException("Cannot build mesh without position attribute"); posOffset = a.offset / 4; posSize = a.numComponents; a = attributes.findByUsage(Usage.Normal); norOffset = a == null ? -1 : a.offset / 4; a = attributes.findByUsage(Usage.Color); colOffset = a == null ? -1 : a.offset / 4; colSize = a == null ? 0 : a.numComponents; a = attributes.findByUsage(Usage.ColorPacked); cpOffset = a == null ? -1 : a.offset / 4; a = attributes.findByUsage(Usage.TextureCoordinates); uvOffset = a == null ? -1 : a.offset / 4; setColor(null); this.primitiveType = primitiveType; }
@Override public boolean equals(final Object obj) { if (!(obj instanceof VertexAttributes)) return false; VertexAttributes other = (VertexAttributes) obj; if (this.attributes.length != other.size()) return false; for (int i = 0; i < attributes.length; i++) { if (!attributes[i].equals(other.attributes[i])) return false; } return true; }
@Override public void unbind(final ShaderProgram shader, final int[] locations) { final GL20 gl = Gdx.gl20; final int numAttributes = attributes.size(); if (locations == null) { for (int i = 0; i < numAttributes; i++) { shader.disableVertexAttribute(attributes.get(i).alias); } } else { for (int i = 0; i < numAttributes; i++) { final int location = locations[i]; if (location >= 0) { shader.disableVertexAttribute(location); } } } gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, 0); isBound = false; }
@Override public void bind(ShaderProgram shader, int[] locations) { final GL20 gl = Gdx.gl20; gl.glBindBuffer(GL20.GL_ARRAY_BUFFER, bufferHandle); if (isDirty) { gl.glBufferData(GL20.GL_ARRAY_BUFFER, buffer.limit(), buffer, usage); isDirty = false; } final int numAttributes = attributes.size(); if (locations == null) { for (int i = 0; i < numAttributes; i++) { final VertexAttribute attribute = attributes.get(i); final int location = shader.getAttributeLocation(attribute.alias); if (location < 0) { continue; } shader.enableVertexAttribute(location); if (attribute.usage == Usage.ColorPacked) shader.setVertexAttribute( location, attribute.numComponents, GL20.GL_UNSIGNED_BYTE, true, attributes.vertexSize, attribute.offset); else shader.setVertexAttribute( location, attribute.numComponents, GL20.GL_FLOAT, false, attributes.vertexSize, attribute.offset); } } else { for (int i = 0; i < numAttributes; i++) { final VertexAttribute attribute = attributes.get(i); final int location = locations[i]; if (location < 0) { continue; } shader.enableVertexAttribute(location); if (attribute.usage == Usage.ColorPacked) shader.setVertexAttribute( location, attribute.numComponents, GL20.GL_UNSIGNED_BYTE, true, attributes.vertexSize, attribute.offset); else shader.setVertexAttribute( location, attribute.numComponents, GL20.GL_FLOAT, false, attributes.vertexSize, attribute.offset); } } isBound = true; }