/** * Allocates hardware buffers on the graphics card and fills them with data if a buffer has not * already been previously allocated. Note that this function uses the GL_OES_vertex_buffer_object * extension, which is not guaranteed to be supported on every device. * * @param gl A pointer to the OpenGL ES context. */ public void generateHardwareBuffers(GL10 gl) { if (!mUseHardwareBuffers) { if (gl instanceof GL11) { GL11 gl11 = (GL11) gl; int[] buffer = new int[1]; // Allocate and fill the vertex buffer. gl11.glGenBuffers(1, buffer, 0); mVertBufferIndex = buffer[0]; gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertBufferIndex); final int vertexSize = mVertexBuffer.capacity() * mCoordinateSize; gl11.glBufferData(GL11.GL_ARRAY_BUFFER, vertexSize, mVertexBuffer, GL11.GL_STATIC_DRAW); // Allocate and fill the texture coordinate buffer. gl11.glGenBuffers(1, buffer, 0); mTextureCoordBufferIndex = buffer[0]; gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mTextureCoordBufferIndex); final int texCoordSize = mTexCoordBuffer.capacity() * mCoordinateSize; gl11.glBufferData(GL11.GL_ARRAY_BUFFER, texCoordSize, mTexCoordBuffer, GL11.GL_STATIC_DRAW); // Allocate and fill the color buffer. gl11.glGenBuffers(1, buffer, 0); mColorBufferIndex = buffer[0]; gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mColorBufferIndex); final int colorSize = mColorBuffer.capacity() * mCoordinateSize; gl11.glBufferData(GL11.GL_ARRAY_BUFFER, colorSize, mColorBuffer, GL11.GL_STATIC_DRAW); // Unbind the array buffer. gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0); // Allocate and fill the index buffer. gl11.glGenBuffers(1, buffer, 0); mIndexBufferIndex = buffer[0]; gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBufferIndex); // A char is 2 bytes. final int indexSize = mIndexBuffer.capacity() * 2; gl11.glBufferData( GL11.GL_ELEMENT_ARRAY_BUFFER, indexSize, mIndexBuffer, GL11.GL_STATIC_DRAW); // Unbind the element array buffer. gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0); mUseHardwareBuffers = true; assert mVertBufferIndex != 0; assert mTextureCoordBufferIndex != 0; assert mIndexBufferIndex != 0; assert gl11.glGetError() == 0; } } }
public void copyTexture2D(RawTexture texture, int x, int y, int width, int height) throws GLOutOfMemoryException { Matrix matrix = mTransformation.getMatrix(); matrix.getValues(mMatrixValues); if (isMatrixRotatedOrFlipped(mMatrixValues)) { throw new IllegalArgumentException("cannot support rotated matrix"); } float points[] = mapPoints(matrix, x, y + height, x + width, y); x = (int) points[0]; y = (int) points[1]; width = (int) points[2] - x; height = (int) points[3] - y; GL11 gl = mGL; int newWidth = Util.nextPowerOf2(width); int newHeight = Util.nextPowerOf2(height); int glError = GL11.GL_NO_ERROR; gl.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId()); int[] cropRect = {0, 0, width, height}; gl.glTexParameteriv(GL11.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, cropRect, 0); gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP_TO_EDGE); gl.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR); gl.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR); gl.glCopyTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, x, y, newWidth, newHeight, 0); glError = gl.glGetError(); if (glError == GL11.GL_OUT_OF_MEMORY) { throw new GLOutOfMemoryException(); } if (glError != GL11.GL_NO_ERROR) { throw new RuntimeException("Texture copy fail, glError " + glError); } texture.setSize(width, height); texture.setTextureSize(newWidth, newHeight); }