private static void convertTexCoords2D(FloatBuffer input, Buffer output) { if (output.capacity() < input.capacity()) throw new RuntimeException("Output must be at least as large as input!"); input.clear(); output.clear(); Vector2f temp = new Vector2f(); int vertexCount = input.capacity() / 2; ShortBuffer sb = null; IntBuffer ib = null; if (output instanceof ShortBuffer) sb = (ShortBuffer) output; else if (output instanceof IntBuffer) ib = (IntBuffer) output; else throw new UnsupportedOperationException(); for (int i = 0; i < vertexCount; i++) { BufferUtils.populateFromBuffer(temp, input, i); if (sb != null) { sb.put((short) (temp.getX() * Short.MAX_VALUE)); sb.put((short) (temp.getY() * Short.MAX_VALUE)); } else { int v1 = (int) (temp.getX() * ((float) (1 << 16))); int v2 = (int) (temp.getY() * ((float) (1 << 16))); ib.put(v1).put(v2); } } }
/** * Gets all x,y coordinates, that have the lowest z-value, therefore making an appropriate measure * for a 3D->2D conversion * * @param verticesBuffer the vertices buffer * @return the coordinates */ private List<Vector2f> getCoordinates(FloatBuffer verticesBuffer) { // get Coordinates into an array float[] vertices = new float[verticesBuffer.capacity()]; for (int i = 0; i < verticesBuffer.capacity(); i++) { vertices[i] = verticesBuffer.get(i); } // read closest points based on their z-value // find smallest z-value float z = Float.MAX_VALUE; for (int i = 2; i < vertices.length; i += 3) { if (vertices[i] < z) { z = vertices[i]; } } // add all points with a z-value that are equals Vector2f vertex; List<Vector2f> finalList = new ArrayList<Vector2f>(); for (int i = 2; i < vertices.length; i += 9) { if (vertices[i] == z) { vertex = new Vector2f(); vertex.x = vertices[i - 2]; vertex.y = vertices[i - 1]; finalList.add(vertex); } } return finalList; }
protected int updateCoordinateBuffers(TaggedAxis1D taggedAxis, int width, int height) { List<Tag> tags = taggedAxis.getSortedTags(); int size = tags.size(); if (vertexCoords == null || vertexCoords.capacity() < size * 4) vertexCoords = Buffers.newDirectFloatBuffer(size * 4); if (textureCoords == null || textureCoords.capacity() < size * 2) textureCoords = Buffers.newDirectFloatBuffer(size * 2); vertexCoords.rewind(); textureCoords.rewind(); int x1 = getColorBarMinX(width); int x2 = getColorBarMaxX(width); int count = 0; for (Tag tag : tags) { if (tag.hasAttribute(TEX_COORD_ATTR)) { float textureCoord = tag.getAttributeFloat(TEX_COORD_ATTR); float vertexCoord = (float) taggedAxis.valueToScreenPixel(tag.getValue()); vertexCoords.put(x1).put(vertexCoord).put(x2).put(vertexCoord); textureCoords.put(textureCoord).put(textureCoord); count += 2; } } return count; }
private void prepareBuffers(GLCanvas canvas) { mBufferNames = new int[3]; GL11 gl = canvas.getGLInstance(); GLId.glGenBuffers(3, mBufferNames, 0); gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[0]); gl.glBufferData( GL11.GL_ARRAY_BUFFER, mXyBuffer.capacity() * (Float.SIZE / Byte.SIZE), mXyBuffer, GL11.GL_STATIC_DRAW); gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBufferNames[1]); gl.glBufferData( GL11.GL_ARRAY_BUFFER, mUvBuffer.capacity() * (Float.SIZE / Byte.SIZE), mUvBuffer, GL11.GL_STATIC_DRAW); gl.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mBufferNames[2]); gl.glBufferData( GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity(), mIndexBuffer, GL11.GL_STATIC_DRAW); // These buffers are never used again. mXyBuffer = null; mUvBuffer = null; mIndexBuffer = null; }
private static void convertToFixed(FloatBuffer input, IntBuffer output) { if (output.capacity() < input.capacity()) throw new RuntimeException("Output must be at least as large as input!"); input.clear(); output.clear(); for (int i = 0; i < input.capacity(); i++) { output.put((int) (input.get() * (float) (1 << 16))); } output.flip(); }
private static void convertToUByte(FloatBuffer input, ByteBuffer output) { if (output.capacity() < input.capacity()) throw new RuntimeException("Output must be at least as large as input!"); input.clear(); output.clear(); for (int i = 0; i < input.capacity(); i++) { output.put((byte) (input.get() * 255f)); } output.flip(); }
private static void absPut(FloatBuffer b) { int n = b.capacity(); b.clear(); for (int i = 0; i < n; i++) b.put(i, (float) ic(i)); b.limit(n); b.position(0); }
private static void checkSlice(FloatBuffer b, FloatBuffer slice) { ck(slice, 0, slice.position()); ck(slice, b.remaining(), slice.limit()); ck(slice, b.remaining(), slice.capacity()); if (b.isDirect() != slice.isDirect()) fail("Lost direction", slice); if (b.isReadOnly() != slice.isReadOnly()) fail("Lost read-only", slice); }
@Override public void init(GLAutoDrawable glad) { GL3 gl3 = glad.getGL().getGL3(); try { shaders.add( GLSLHelpers.createShader(gl3, getClass(), GL3.GL_VERTEX_SHADER, "glsl/simple_vs")); shaders.add( GLSLHelpers.createShader(gl3, getClass(), GL3.GL_FRAGMENT_SHADER, "glsl/simple_fs")); program = GLSLHelpers.createProgram(gl3, shaders); gl3.glGenVertexArrays(1, VAO, 0); gl3.glBindVertexArray(VAO[0]); gl3.glGenBuffers(1, VBO, 0); gl3.glBindBuffer(GL3.GL_ARRAY_BUFFER, VBO[0]); FloatBuffer buffer = GLBuffers.newDirectFloatBuffer(TRIANGLE); gl3.glBufferData(GL3.GL_ARRAY_BUFFER, buffer.capacity() * 4, buffer, GL3.GL_STATIC_DRAW); gl3.glEnableVertexAttribArray(0); gl3.glVertexAttribPointer(0, 2, GL3.GL_FLOAT, false, 0, 0); gl3.glBindVertexArray(0); } catch (Throwable t) { t.printStackTrace(); } }
/** * Method for painting any given object. Data must be 7 floats per face – we render one triangle * consisting of 3 vertices with each vertice having an rgba color float value. * * @param data The vertice data containing coordinates and colors to draw. */ private void drawObject(final FloatBuffer data) { // Pass in the position information data.position(mPositionOffset); GLES20.glVertexAttribPointer( mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, mStrideBytes, data); GLES20.glEnableVertexAttribArray(mPositionHandle); // Pass in the color information data.position(mColorOffset); GLES20.glVertexAttribPointer( mColorHandle, mColorDataSize, GLES20.GL_FLOAT, false, mStrideBytes, data); GLES20.glEnableVertexAttribArray(mColorHandle); // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix // (which currently contains model * view). Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); // This multiplies the modelview matrix by the projection matrix, and stores the result in the // MVP matrix // (which now contains model * view * projection). Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0); // The (1+data.capacity() / 8) tells us how many vertices we need to // draw GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, (1 + data.capacity() / 8)); }
public static void main(String args[]) throws Exception { FloatBuffer buffer = FloatBuffer.allocate(10); for (int i = 0; i < buffer.capacity(); ++i) { float f = (float) Math.sin((((float) i) / 10) * (2 * Math.PI)); buffer.put(f); } /** flip()源码: */ // public final Buffer flip() { // limit = position; // position = 0; // mark = -1; // return this; // } /** * 反转缓冲区。首先将限制设置为当前位置,然后将位置设置为 0。 如果已定义了标记,则丢弃该标记。 常与compact方法一起使用。 通常情况下,在准备从缓冲区中读取数据时调用flip方法。 */ buffer.flip(); while (buffer.hasRemaining()) { float f = buffer.get(); System.out.println(f); } }
private int createTubeVbo(int tube, Color color) { float[] c = new float[] {color.getBlue() / 255f, color.getGreen() / 255f, color.getRed() / 255f}; totalNumVerts[tube] = tubes[tube].indeces.length; IntBuffer buf = BufferUtils.createIntBuffer(1); GL15.glGenBuffers(buf); int vbo = buf.get(); FloatBuffer data = BufferUtils.createFloatBuffer(tubes[tube].indeces.length * 9); for (int i = 0; i < tubes[tube].indeces.length; i++) { data.put(c); Vector3D vertex = tubes[tube].vertices[tubes[tube].indeces[i]]; Vector3D normal = tubes[tube].normals[tubes[tube].indeces[i]]; float[] vertexf = new float[] {vertex.x, vertex.y, vertex.z}; float[] normalf = new float[] {normal.x, normal.y, normal.z}; data.put(vertexf); data.put(normalf); } data.rewind(); int bytesPerFloat = Float.SIZE / Byte.SIZE; int numBytes = data.capacity() * bytesPerFloat; GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo); GL15.glBufferData(GL15.GL_ARRAY_BUFFER, data, GL15.GL_STATIC_DRAW); GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0); return vbo; }
private void initialize() { GL11 gl = mGL; // First create an nio buffer, then create a VBO from it. int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE; FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer(); xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0); int[] name = new int[1]; GLId.glGenBuffers(1, name, 0); mBoxCoords = name[0]; gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords); gl.glBufferData( GL11.GL_ARRAY_BUFFER, xyBuffer.capacity() * (Float.SIZE / Byte.SIZE), xyBuffer, GL11.GL_STATIC_DRAW); gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0); gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); // Enable the texture coordinate array for Texture 1 gl.glClientActiveTexture(GL11.GL_TEXTURE1); gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); gl.glClientActiveTexture(GL11.GL_TEXTURE0); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // mMatrixValues and mAlpha will be initialized in setSize() }
private static void bulkPutArray(FloatBuffer b) { int n = b.capacity(); b.clear(); float[] a = new float[n + 7]; for (int i = 0; i < n; i++) a[i + 7] = (float) ic(i); b.put(a, 7, n); b.flip(); }
private void checkSize(final int count) { while (buffer.remaining() < count) { final FloatBuffer newBuffer = BufferUtils.createFloatBuffer(buffer.capacity() << 1); buffer.flip(); newBuffer.put(buffer); buffer = newBuffer; } }
private void expandVerts(int vertCount) { int newVerts = vertexData == null ? 0 : vertexData.capacity() / VERTEX_SIZE; while (newVerts < vertCount) newVerts += EXPAND_VERTS; vertexData = ByteBuffer.allocateDirect(newVerts * VERTEX_STRIDE) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); }
@Override public void extractTemplateFromMesh(Mesh mesh) { template = mesh; templateVerts = MeshUtils.getPositionBuffer(mesh); templateCoords = MeshUtils.getTexCoordBuffer(mesh); templateIndexes = MeshUtils.getIndexBuffer(mesh); templateNormals = MeshUtils.getNormalsBuffer(mesh); templateColors = BufferUtils.createFloatBuffer(templateVerts.capacity() / 3 * 4); }
public static VertexBuffer convertToUByte(VertexBuffer vb) { FloatBuffer fb = (FloatBuffer) vb.getData(); ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity()); convertToUByte(fb, bb); VertexBuffer newVb = new VertexBuffer(vb.getBufferType()); newVb.setupData(vb.getUsage(), vb.getNumComponents(), Format.UnsignedByte, bb); newVb.setNormalized(true); return newVb; }
/** * Nudges an entire object in the given direction through manipulation of its vertices rather than * position of the Spatial itself. * * @param s The Spatial to move. * @param x The amount of x units to move the object. * @param y The amount of y units to move the object. * @param z The amount of z units to move the object. */ public static void adjustObject(Spatial s, float x, float y, float z) { logger.info("Moving " + s.getName() + " " + x + "," + y + "," + z); if (s instanceof TriMesh) { FloatBuffer vb = ((TriMesh) s).getVertexBuffer(); vb.rewind(); float[] floatArray = new float[vb.capacity()]; for (int i = 0; i < ((TriMesh) s).getTriangleCount(); i++) { floatArray[i * 3] = vb.get(i * 3) + x; floatArray[i * 3] = vb.get(i * 3 + 1) + y; floatArray[i * 3] = vb.get(i * 3 + 2) + z; } FloatBuffer newBuffer = FloatBuffer.allocate(vb.capacity()); newBuffer.put(floatArray); ((TriMesh) s).setVertexBuffer(newBuffer); } if (s instanceof QuadMesh) { FloatBuffer vb = ((QuadMesh) s).getVertexBuffer(); vb.rewind(); float[] floatArray = new float[vb.capacity()]; for (int i = 0; i < ((QuadMesh) s).getQuadCount(); i++) { floatArray[i * 4] = vb.get(i * 4) + x; floatArray[i * 4] = vb.get(i * 4 + 1) + y; floatArray[i * 4] = vb.get(i * 4 + 2) + z; } FloatBuffer newBuffer = FloatBuffer.allocate(vb.capacity()); newBuffer.put(floatArray); ((QuadMesh) s).setVertexBuffer(newBuffer); } if (s instanceof Node) { if (((Node) s).getChildren() != null) { for (Spatial child : ((Node) s).getChildren()) { adjustObject(child, x, y, z); } } } }
public static VertexBuffer convertToFixed(VertexBuffer vb) { if (vb.getFormat() == Format.Int) return vb; FloatBuffer fb = (FloatBuffer) vb.getData(); IntBuffer ib = BufferUtils.createIntBuffer(fb.capacity()); convertToFixed(fb, ib); VertexBuffer newVb = new VertexBuffer(vb.getBufferType()); newVb.setupData(vb.getUsage(), vb.getNumComponents(), Format.Int, ib); return newVb; }
private static void bulkPutBuffer(FloatBuffer b) { int n = b.capacity(); b.clear(); FloatBuffer c = FloatBuffer.allocate(n + 7); c.position(7); for (int i = 0; i < n; i++) c.put((float) ic(i)); c.flip(); c.position(7); b.put(c); b.flip(); }
@Override protected int beginPrimitive(int vertexCount, int elemCount) { int vertIdx = vertexOffset / VERTEX_SIZE; int verts = vertIdx + vertexCount, elems = elementOffset + elemCount; int availVerts = vertexData.capacity() / VERTEX_SIZE, availElems = elementData.capacity(); if ((verts > availVerts) || (elems > availElems)) { flush(); if (vertexCount > availVerts) expandVerts(vertexCount); if (elemCount > availElems) expandElems(elemCount); return 0; } return vertIdx; }
public void glPaint() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, 0, _buffer); glNormalPointer(GL_FLOAT, 0, _buffer); glColor3f(1.0f, 1.0f, 1.0f); glDrawArrays(GL_TRIANGLES, 0, _buffer.capacity() / 3); glFlush(); }
public void copy(D3DMesh mesh) { mIndices = CharBuffer.allocate(mesh.mIndices.position()); mVertices = FloatBuffer.allocate(mesh.mVertices.position()); for (int j = 0; j < mIndices.capacity(); j++) mIndices.put(mesh.mIndices.get(j)); for (int j = 0; j < mVertices.capacity(); j++) { mVertices.put(mesh.mVertices.get(j)); } mIndices.position(0); mVertices.position(0); }
public static void convertToFixed(Geometry geom, Format posFmt, Format nmFmt, Format tcFmt) { geom.updateModelBound(); BoundingBox bbox = (BoundingBox) geom.getModelBound(); Mesh mesh = geom.getMesh(); VertexBuffer positions = mesh.getBuffer(Type.Position); VertexBuffer normals = mesh.getBuffer(Type.Normal); VertexBuffer texcoords = mesh.getBuffer(Type.TexCoord); VertexBuffer indices = mesh.getBuffer(Type.Index); // positions FloatBuffer fb = (FloatBuffer) positions.getData(); if (posFmt != Format.Float) { Buffer newBuf = VertexBuffer.createBuffer(posFmt, positions.getNumComponents(), mesh.getVertexCount()); Transform t = convertPositions(fb, bbox, newBuf); t.combineWithParent(geom.getLocalTransform()); geom.setLocalTransform(t); VertexBuffer newPosVb = new VertexBuffer(Type.Position); newPosVb.setupData(positions.getUsage(), positions.getNumComponents(), posFmt, newBuf); mesh.clearBuffer(Type.Position); mesh.setBuffer(newPosVb); } // normals, automatically convert to signed byte fb = (FloatBuffer) normals.getData(); ByteBuffer bb = BufferUtils.createByteBuffer(fb.capacity()); convertNormals(fb, bb); normals = new VertexBuffer(Type.Normal); normals.setupData(Usage.Static, 3, Format.Byte, bb); normals.setNormalized(true); mesh.clearBuffer(Type.Normal); mesh.setBuffer(normals); // texcoords fb = (FloatBuffer) texcoords.getData(); if (tcFmt != Format.Float) { Buffer newBuf = VertexBuffer.createBuffer(tcFmt, texcoords.getNumComponents(), mesh.getVertexCount()); convertTexCoords2D(fb, newBuf); VertexBuffer newTcVb = new VertexBuffer(Type.TexCoord); newTcVb.setupData(texcoords.getUsage(), texcoords.getNumComponents(), tcFmt, newBuf); mesh.clearBuffer(Type.TexCoord); mesh.setBuffer(newTcVb); } }
private static void convertNormals(FloatBuffer input, ByteBuffer output) { if (output.capacity() < input.capacity()) throw new RuntimeException("Output must be at least as large as input!"); input.clear(); output.clear(); Vector3f temp = new Vector3f(); int vertexCount = input.capacity() / 3; for (int i = 0; i < vertexCount; i++) { BufferUtils.populateFromBuffer(temp, input, i); // offset and scale vector into -128 ... 127 temp.multLocal(127).addLocal(0.5f, 0.5f, 0.5f); // quantize byte v1 = (byte) temp.getX(); byte v2 = (byte) temp.getY(); byte v3 = (byte) temp.getZ(); // store output.put(v1).put(v2).put(v3); } }
public void set(final double radius, final double start, final double end) { final FloatBuffer buf = getMeshData().getVertexBuffer(); buf.limit(buf.capacity()); this.getMeshData().updateVertexCount(); buf.rewind(); double arc = end - start; final int n = buf.limit() / 3; for (int i = 0; i < n; i++) { double theta = start + arc / (n - 1) * i; float x = (float) (MathUtils.cos(theta) * radius); float y = (float) (MathUtils.sin(theta) * radius); buf.put(x).put(y).put(0); } getMeshData().updateVertexCount(); }
public void mergeNormals() { FloatBuffer normalAccumulationBuffer = FloatBuffer.allocate(mVertices.capacity()); for (int i = 0; i < mIndices.capacity(); i++) { int indice = mIndices.get(i); int offset_indice = indice * D3DMesh.nbFloatPerVertex; for (int j = 0; j < mIndices.capacity(); j++) { char indice2 = mIndices.get(j); int offset_indice2 = indice2 * D3DMesh.nbFloatPerVertex; float x = mVertices.get(indice * D3DMesh.nbFloatPerVertex); float y = mVertices.get(indice * D3DMesh.nbFloatPerVertex + 1); float z = mVertices.get(indice * D3DMesh.nbFloatPerVertex + 2); float x2 = mVertices.get(indice2 * D3DMesh.nbFloatPerVertex); float y2 = mVertices.get(indice2 * D3DMesh.nbFloatPerVertex + 1); float z2 = mVertices.get(indice2 * D3DMesh.nbFloatPerVertex + 2); if ((x == x2) && (y == y2) && (z == z2)) { normalAccumulationBuffer.put( offset_indice2 + 3, normalAccumulationBuffer.get(offset_indice2 + 3) + mVertices.get(offset_indice + 3)); normalAccumulationBuffer.put( offset_indice2 + 4, normalAccumulationBuffer.get(offset_indice2 + 4) + mVertices.get(offset_indice + 4)); normalAccumulationBuffer.put( offset_indice2 + 5, normalAccumulationBuffer.get(offset_indice2 + 5) + mVertices.get(offset_indice + 5)); } } } D3DVector normal = new D3DVector(); for (int i = 0; i < mIndices.capacity(); i++) { int indice = mIndices.get(i); int offset_indice = indice * D3DMesh.nbFloatPerVertex; normal.set(0, normalAccumulationBuffer.get(offset_indice + 3)); normal.set(1, normalAccumulationBuffer.get(offset_indice + 4)); normal.set(2, normalAccumulationBuffer.get(offset_indice + 5)); normal.normalize(); mVertices.put(offset_indice + 3, normal.get(0)); mVertices.put(offset_indice + 4, normal.get(1)); mVertices.put(offset_indice + 5, normal.get(2)); } }
public void selectOnHardware(final GL11 pGL11) { final int hardwareBufferID = this.mHardwareBufferID; if (hardwareBufferID == -1) { return; } GLHelper.bindBuffer( pGL11, hardwareBufferID); // TODO Does this always need to be binded, or are just for buffers of // the same 'type'(texture/vertex)? if (this.mHardwareBufferNeedsUpdate) { // Debug.d("BufferObject.updating: ID = " + this.mHardwareBufferID); this.mHardwareBufferNeedsUpdate = false; // BufferUtils.copy(mBufferData, mFloatBuffer, mFloatBuffer.capacity(), 0); pGL11.glBufferData( GL11.GL_ARRAY_BUFFER, mFloatBuffer.capacity() * 4, mFloatBuffer, mDrawType); } }
public void init(float[] alldata) { FloatBuffer everythingBuffer = ByteBuffer.allocateDirect(alldata.length * BYTES_PER_FLOAT) .order(ByteOrder.nativeOrder()) .asFloatBuffer(); everythingBuffer.put(alldata).position(0); ByteBuffer dlb = ByteBuffer.allocateDirect( // (# of coordinate values * 2 bytes per short) drawOrder.length * 2); dlb.order(ByteOrder.nativeOrder()); ShortBuffer drawListBuffer = dlb.asShortBuffer(); drawListBuffer.put(drawOrder).position(0); // First, generate as many buffers as we need. // This will give us the OpenGL handles for these buffers. GLES20.glGenBuffers(2, buffers, 0); // Bind to the buffer. Future commands will affect this buffer // specifically. GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[1]); // Transfer data from client memory to the buffer. // We can release the client memory after this call. GLES20.glBufferData( GLES20.GL_ARRAY_BUFFER, everythingBuffer.capacity() * BYTES_PER_FLOAT, everythingBuffer, GLES20.GL_STATIC_DRAW); GLES20.glBufferData( GLES20.GL_ELEMENT_ARRAY_BUFFER, drawListBuffer.capacity() * 2, drawListBuffer, GLES20.GL_STATIC_DRAW); // IMPORTANT: Unbind from the buffer when we're done with it. GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0); }