예제 #1
0
  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");
    }
  }
예제 #2
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);
  }
예제 #3
0
  /**
   * Stretches the texture according to the nine-patch rules. It will linearly distribute the
   * strechy parts defined in the nine-patch chunk to the target area.
   *
   * <pre>
   *                      source
   *          /--------------^---------------\
   *         u0    u1       u2  u3     u4   u5
   * div ---> |fffff|ssssssss|fff|ssssss|ffff| ---> u
   *          |    div0    div1 div2   div3  |
   *          |     |       /   /      /    /
   *          |     |      /   /     /    /
   *          |     |     /   /    /    /
   *          |fffff|ssss|fff|sss|ffff| ---> x
   *         x0    x1   x2  x3  x4   x5
   *          \----------v------------/
   *                  target
   *
   * f: fixed segment
   * s: stretchy segment
   * </pre>
   *
   * @param div the stretch parts defined in nine-patch chunk
   * @param source the length of the texture
   * @param target the length on the drawing plan
   * @param u output, the positions of these dividers in the texture coordinate
   * @param x output, the corresponding position of these dividers on the drawing plan
   * @return the number of these dividers.
   */
  private int stretch(int x[], float u[], int div[], int source, int target) {
    int textureSize = Util.nextPowerOf2(source);
    float textureBound = (source - 0.5f) / textureSize;

    int stretch = 0;
    for (int i = 0, n = div.length; i < n; i += 2) {
      stretch += div[i + 1] - div[i];
    }

    float remaining = target - source + stretch;

    int lastX = 0;
    int lastU = 0;

    x[0] = 0;
    u[0] = 0;
    for (int i = 0, n = div.length; i < n; i += 2) {
      // fixed segment
      x[i + 1] = lastX + (div[i] - lastU);
      u[i + 1] = Math.min((float) div[i] / textureSize, textureBound);

      // stretchy segment
      float partU = div[i + 1] - div[i];
      int partX = (int) (remaining * partU / stretch + 0.5f);
      remaining -= partX;
      stretch -= partU;

      lastX = x[i + 1] + partX;
      lastU = div[i + 1];
      x[i + 2] = lastX;
      u[i + 2] = Math.min((float) lastU / textureSize, textureBound);
    }
    // the last fixed segment
    x[div.length + 1] = target;
    u[div.length + 1] = textureBound;

    // remove segments with length 0.
    int last = 0;
    for (int i = 1, n = div.length + 2; i < n; ++i) {
      if (x[last] == x[i]) continue;
      x[++last] = x[i];
      u[last] = u[i];
    }
    return last + 1;
  }