/** Mipmap texture */ public static int buildMipmap(GL10 gl, Bitmap srcBitmap, boolean recycle) { Bitmap bitmap = srcBitmap; int level = 0; int height = bitmap.getHeight(); int width = bitmap.getWidth(); int textureID = genTexture(gl); gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID); try { // この一文がないと、Lynxで崩れる ((GL11) gl).glTexParameteri(GL10.GL_TEXTURE_2D, GL11.GL_GENERATE_MIPMAP, GL10.GL_TRUE); } catch (Exception e) { e.printStackTrace(); } gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); gl.glTexParameterf( GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR_MIPMAP_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE); gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE); gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE); while (height >= 1 && width >= 1) { // ---- note ---- // First of all, generate the texture from our bitmap and set it to // the according level // Lynx3Dではlevel 0 以外で呼び出したときにうまくいかないことがある。 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, level, bitmap, 0); if (height == 1 || width == 1) { if (recycle || bitmap != srcBitmap) bitmap.recycle(); break; } level++; height /= 2; width /= 2; Bitmap bitmap2 = Bitmap.createScaledBitmap(bitmap, width, height, true); // Clean up if (recycle || bitmap != srcBitmap) bitmap.recycle(); bitmap = bitmap2; } return textureID; }
private void uploadToGL(GL11 gl) throws GLOutOfMemoryException { Bitmap bitmap = getBitmap(); int glError = GL11.GL_NO_ERROR; if (bitmap != null) { int[] textureId = new int[1]; try { // Define a vertically flipped crop rectangle for // OES_draw_texture. int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] cropRect = {0, height, width, -height}; // Upload the bitmap to a new texture. gl.glGenTextures(1, textureId, 0); gl.glBindTexture(GL11.GL_TEXTURE_2D, textureId[0]); 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); int widthExt = Util.nextPowerOf2(width); int heightExt = Util.nextPowerOf2(height); int format = GLUtils.getInternalFormat(bitmap); int type = GLUtils.getType(bitmap); mTextureWidth = widthExt; mTextureHeight = heightExt; gl.glTexImage2D(GL11.GL_TEXTURE_2D, 0, format, widthExt, heightExt, 0, format, type, null); GLUtils.texSubImage2D(GL11.GL_TEXTURE_2D, 0, 0, 0, bitmap, format, type); } finally { freeBitmap(bitmap); } if (glError == GL11.GL_OUT_OF_MEMORY) { throw new GLOutOfMemoryException(); } if (glError != GL11.GL_NO_ERROR) { mId = 0; mState = STATE_UNLOADED; throw new RuntimeException("Texture upload fail, glError " + glError); } else { // Update texture state. mGL = gl; mId = textureId[0]; mState = BitmapTexture.STATE_LOADED; } } else { mState = STATE_ERROR; throw new RuntimeException("Texture load fail, no bitmap"); } }
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); }
@Override public void glTexParameteri(int target, int pname, int param) { gl.glTexParameteri(target, pname, param); }