Android Open Source - misty Texture






From Project

Back to project page misty.

License

The source code is released under:

MIT License

If you think the Android project misty listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.misty.graphics.textures;
/*ww w.j a v  a 2s.c o m*/
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import com.misty.math.Rectangle;

public class Texture
{
  public final String path;
  public final int width;
  public final int height;
  public final int[][] pixelMap;
  public final Rectangle bounds;
  
  private int textureId;
  private final FloatBuffer floatBuffer;
  private final float[] modelMatrix = new float[16];
  private final float[] finalMatrix = new float[16];
  
  private static final int BYTES_PER_FLOAT = 4;
  private static final int VERTICES_LENGTH = 16;
  private static final int POSITION_COMPONENT_COUNT = 2;
  private static final int TEXTURE_COORDINATES_COMPONENT_COUNT = 2;
  private static final int STRIDE = (Texture.POSITION_COMPONENT_COUNT + Texture.TEXTURE_COORDINATES_COMPONENT_COUNT) * Texture.BYTES_PER_FLOAT;
  
  public Texture(String texturePath)
  {
    this.path = texturePath;
    
    Bitmap bitmap = TextureManager.getBitmap(this.path);
    
    this.width = bitmap.getWidth();
    this.height = bitmap.getHeight();
    
    this.pixelMap = new int[this.width][this.height];
    
    for (int i = 0; i < this.width; i++)
    {
      for (int j = 0; j < this.height; j++)
      {
        this.pixelMap[i][j] = bitmap.getPixel(i, j);
      }
    }
    
    this.floatBuffer = getFloatBuffer(bitmap);
    
    this.bounds = getInternalBounds(this.pixelMap, this.width, this.height);
    
    loadTexture(bitmap);
  }
  
  private Rectangle getInternalBounds(int[][] pixelMap, int width, int height)
  {
    int minX = getMinX(pixelMap);
    int maxX = getMaxX(pixelMap);
    int minY = getMinY(pixelMap, height);
    int maxY = getMaxY(pixelMap, height);
    
    return new Rectangle(minX, minY, width - minX - maxX, height - maxY - minY);
  }
  
  private int getMinX(int[][] source)
  {
    int result = 0;
    
    for (int[] array : source)
    {
      if (isEmpty(array))
      {
        result++;
      }
      else
      {
        break;
      }
    }
    
    return result;
  }
  
  private int getMaxX(int[][] source)
  {
    int result = 0;
    
    for (int i = (source.length - 1); i >= 0; i--)
    {
      if (isEmpty(source[i]))
      {
        result++;
      }
      else
      {
        break;
      }
    }
    
    return result;
  }
  
  private int getMinY(int[][] source, int height)
  {
    boolean valid = true;
    int result = -1;
    
    while ((result < height) && (valid))
    {
      result++;
      
      for (int[] array : source)
      {
        if (Color.alpha(array[height - result - 1]) > 0)
        {
          valid = false;
          break;
        }
      }
    }
    
    return result;
  }
  
  private int getMaxY(int[][] source, int height)
  {
    boolean valid = true;
    int result = -1;
    
    while ((result < height) && (valid))
    {
      result++;
      
      for (int[] array : source)
      {
        if (Color.alpha(array[result]) > 0)
        {
          valid = false;
          break;
        }
      }
    }
    
    return result;
  }
  
  private boolean isEmpty(int[] row)
  {
    boolean result = true;
    
    for (int color : row)
    {
      if (Color.alpha(color) > 0)
      {
        result = false;
        break;
      }
    }
    
    return result;
  }
  
  public void render(float[] projectionMatrix, float x, float y, float scaleX, float scaleY, float angle, float orientationHorizontal, float orientationVertical, int uMatrixLocation, int uTextureUnitLocation, int aPositionLocation, int aTextureCoordinatesLocation)
  {
    Matrix.setIdentityM(this.modelMatrix, 0);
    Matrix.translateM(this.modelMatrix, 0, x + (this.width / 2), y + (this.height / 2), 0);
    Matrix.rotateM(this.modelMatrix, 0, angle, 0, 0, 1);
    Matrix.scaleM(this.modelMatrix, 0, scaleX, scaleY, 1);
    
    if (orientationHorizontal == -1)
    {
      Matrix.scaleM(this.modelMatrix, 0, orientationHorizontal, 1, 1);
    }
    if (orientationVertical == -1)
    {
      Matrix.scaleM(this.modelMatrix, 0, 1, orientationVertical, 1);
    }
    
    Matrix.multiplyMM(this.finalMatrix, 0, projectionMatrix, 0, this.modelMatrix, 0);
    
    // setting uniforms
    GLES20.glUniformMatrix4fv(uMatrixLocation, 1, false, this.finalMatrix, 0);
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.textureId);
    GLES20.glUniform1i(uTextureUnitLocation, 0);
    
    // rendering the texture
    setVertexAttribPointer(0, aPositionLocation, Texture.POSITION_COMPONENT_COUNT, Texture.STRIDE);
    setVertexAttribPointer(Texture.POSITION_COMPONENT_COUNT, aTextureCoordinatesLocation, Texture.TEXTURE_COORDINATES_COMPONENT_COUNT, Texture.STRIDE);
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, Texture.VERTICES_LENGTH / (Texture.POSITION_COMPONENT_COUNT + Texture.TEXTURE_COORDINATES_COMPONENT_COUNT));
  }
  
  private void setVertexAttribPointer(int dataOffset, int attributeLocation, int componentCount, int stride)
  {
    this.floatBuffer.position(dataOffset);
    GLES20.glVertexAttribPointer(attributeLocation, componentCount, GLES20.GL_FLOAT, false, stride, this.floatBuffer);
    GLES20.glEnableVertexAttribArray(attributeLocation);
    this.floatBuffer.position(0);
  }
  
  private FloatBuffer getFloatBuffer(Bitmap bitmap)
  {
    float imageWidth = bitmap.getWidth();
    float imageHeight = bitmap.getHeight();
    
    float[] vertices =
      {
          // Order of coordinates: X, Y, S, T
          
          // A----C
          // | /|
          // | / |
          // | / |
          // |/ |
          // B----D
          
          // Note: T is inverted!
          
          -imageWidth / 2, imageHeight / 2, 0f, 0f, //
          -imageWidth / 2, -imageHeight / 2, 0f, 1f, //
          imageWidth / 2, imageHeight / 2, 1f, 0f, //
          imageWidth / 2, -imageHeight / 2, 1f, 1f
      };
    
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * Texture.BYTES_PER_FLOAT);
    byteBuffer.order(ByteOrder.nativeOrder());
    FloatBuffer result = byteBuffer.asFloatBuffer();
    result.put(vertices);
    
    return result;
  }
  
  private void loadTexture(Bitmap bitmap)
  {
    int[] textureObjectIds = new int[1];
    GLES20.glGenTextures(1, textureObjectIds, 0);
    
    if (textureObjectIds[0] != 0)
    {
      if (bitmap != null)
      {
        // Bind to the texture in OpenGL
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureObjectIds[0]);
        
        // Set filtering: a default must be set, or the texture will be black.
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        
        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
        
        // Note: Following code may cause an error to be reported in the
        // ADB log as follows: E/IMGSRV(20095): :0: HardwareMipGen:
        // Failed to generate texture mipmap levels (error=3)
        // No OpenGL error will be encountered (glGetError() will return
        // 0). If this happens, just squash the source image to be
        // square. It will look the same because of texture coordinates,
        // and mipmap generation will work.
        // GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);
        
        // Recycle the bitmap, since its data has been loaded into OpenGL.
        bitmap.recycle();
        
        // Unbind from the texture.
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
        
        this.textureId = textureObjectIds[0];
      }
      else
      {
        GLES20.glDeleteTextures(1, textureObjectIds, 0);
      }
    }
  }
  
  public void reload()
  {
    Bitmap bitmap = TextureManager.getBitmap(this.path);
    loadTexture(bitmap);
  }
}




Java Source Code List

com.misty.audio.AudioManager.java
com.misty.debug.FPS.java
com.misty.debug.TimeCounter.java
com.misty.graphics.Animation.java
com.misty.graphics.Camera.java
com.misty.graphics.CollisionGrid.java
com.misty.graphics.Renderer.java
com.misty.graphics.ScreenResolution.java
com.misty.graphics.textures.TextureManager.java
com.misty.graphics.textures.Texture.java
com.misty.input.TouchEvent.java
com.misty.kernel.Alarm.java
com.misty.kernel.Engine.java
com.misty.kernel.Misty.java
com.misty.kernel.Process.java
com.misty.math.Rectangle.java
com.misty.math.Utils.java
com.misty.math.Vector.java
com.misty.utils.Assets.java