2011年5月31日火曜日

AndroidでMetasequoiaのmqoを読み込むコード その2 Textureクラス

大分空きましたが続きー

VBOとTextureをワンセットにすることで、DirectXで言うサブセットみたいな処理ができるので、Textureクラスも当然必要です(テクスチャの切り替えを最小限にするため)

  1. package com.dividebyzero.KszGameBase;  
  2.   
  3. import java.util.HashMap;  
  4.   
  5. import javax.microedition.khronos.opengles.GL10;  
  6. import javax.microedition.khronos.opengles.GL11;  
  7.   
  8. import android.content.Context;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.BitmapFactory;  
  11. import android.opengl.GLUtils;  
  12. import android.util.Log;  
  13.   
  14. /** 
  15.  * テクスチャクラス 
  16.  * @author ksz 
  17.  * 
  18.  */  
  19. public class Texture {  
  20.  public int resID, texID, w, h;  
  21.  private static final RenderParam param = new RenderParam();  
  22.   
  23.  /** 
  24.   * @param resID リソースID 
  25.   * @param texID OpenGLでのテクスチャID 
  26.   * @param w 横幅 
  27.   * @param h 縦幅 
  28.   */  
  29.  public Texture(int resID, int texID, int w, int h) {  
  30.   this.resID = resID;  
  31.   this.texID = texID;  
  32.   this.w = w;  
  33.   this.h = h;  
  34.  }  
  35.   
  36.  /** 
  37.   * staticのrenderを呼びやすくしただけ 
  38.   */  
  39.  public void render(float x,float y){  
  40.   render(this,x,y,0,param.init());  
  41.  }  
  42.    
  43.  /** 
  44.   * staticのrenderを呼びやすくしただけ 
  45.   */  
  46.  public void render(float x, float y, RenderParam param) {  
  47.   render(this, x, y, 0, param);  
  48.  }  
  49.   
  50.  /** 
  51.   * staticのrenderを呼びやすくしただけ 
  52.   */  
  53.  public void render(float x, float y, float z, RenderParam param) {  
  54.   render(this, x, y, z, param);  
  55.  }  
  56.   
  57.  /** 
  58.   * staticのポリラインを呼びやすくしただけ 
  59.   */  
  60.  public void renderPolyLine(float sx, float sy, float ex, float ey, RenderParam param) {  
  61.   renderPolyLine(this, sx, sy, ex, ey, param);  
  62.  }  
  63.   
  64.  /** 
  65.   * テクスチャのバインド 
  66.   */  
  67.  public void bind() {  
  68.   setTexture(texID);  
  69.  }  
  70.   
  71.  //////////////////ここから管理ゾーン  
  72.  public static HashMap<Integer, Texture> texMap = new HashMap<:Integer, Texture>();  
  73.   
  74.  /** 
  75.   * リソースIDではなく、文字列からテクスチャインスタンスを作成 
  76.   * @param resName 読み込みたい文字列 "***.png"のようにしても、拡張子部分は捨てられる 
  77.   * @return 作成されたテクスチャインスタンス 
  78.   */  
  79.  public static Texture get(String resName) {  
  80.   Context context = Global.view.getContext();  
  81.   int point = resName.lastIndexOf(".");  
  82.   if (point != -1) {  
  83.    resName = resName.substring(0, point);  
  84.   }  
  85.   Log.v("debug", resName);  
  86.   int id = context.getResources().getIdentifier(resName, "drawable", context.getPackageName());  
  87.   return get(id);  
  88.  }  
  89.   
  90.  /** 
  91.   * リソースIDからテクスチャインスタンスを作成 
  92.   * @param resID 読み込みたいリソース 
  93.   * @return 作成されたテクスチャインスタンス。既に読み込まれている場合はそのインスタンス 
  94.   */  
  95.  public static Texture get(int resID) {  
  96.   if (texMap.containsKey(resID)) {  
  97.    return texMap.get(resID);  
  98.   }  
  99.   
  100.   GL10 gl = Global.gl;  
  101.   //リソースBMPを読み込む  
  102.   BitmapFactory.Options opt = new BitmapFactory.Options();  
  103.   opt.inScaled = false//勝手に拡大縮小するので止める  
  104.   Bitmap bitmap = BitmapFactory.decodeResource(Global.view.getResources(), resID, opt);  
  105.   //グラボのテクスチャとして登録  
  106.   int[] texID = new int[1]; //グラボからテクスチャIDを受け取るための変数  
  107.   gl.glGenTextures(1, texID, 0); //グラボから使ってないテクスチャIDを取得  
  108.   Texture.setTexture(texID[0]);  
  109.   //BMPをテクスチャに割り当てる  
  110.   GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  
  111.   //テクスチャパラメータをセット  
  112.   gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, //拡大の時は  
  113.     GL10.GL_LINEAR); //線形補間  
  114.   gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, //縮小の時は  
  115.     GL10.GL_LINEAR); //線形補間  
  116.   gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, //UVがはみ出したときどうしますか  
  117.     GL10.GL_CLAMP_TO_EDGE); //端っこで止める  
  118.   gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, //UVがはみ出したときどうしますか  
  119.     GL10.GL_CLAMP_TO_EDGE); //端っこで止める  
  120.   
  121.   Texture tex = new Texture(resID, texID[0], bitmap.getWidth(), bitmap.getHeight());  
  122.   bitmap.recycle();  
  123.   texMap.put(resID, tex);  
  124.   return tex;  
  125.  }  
  126.   
  127.  private static Vbo vbo = null;  
  128.  private static int currentTexID = -1;  
  129.   
  130.  /** 
  131.   * テクスチャをOpenGLにセット 
  132.   * 同じテクスチャが連続でセットされないようにしている 
  133.   * @param id セットしたいテクスチャ 
  134.   */  
  135.  public static void setTexture(int id) {  
  136.   if (currentTexID != id) {  
  137.    currentTexID = id;  
  138.    Global.gl.glBindTexture(GL10.GL_TEXTURE_2D, id);  
  139.   }  
  140.  }  
  141.   
  142.  /** 
  143.   * 指定されたテクスチャを描画 z軸が無いVer 
  144.   * @param tex 描画したいテクスチャ 
  145.   * @param x 座標x 
  146.   * @param y 座標y 
  147.   * @param param 描画パラメータ 
  148.   */  
  149.  public static void render(Texture tex, float x, float y, RenderParam param) {  
  150.   render(tex, x, y, 0, param);  
  151.  }  
  152.   
  153.  /** 
  154.   * 指定されたテクスチャを描画 
  155.   * @param tex 描画したいテクスチャ 
  156.   * @param x 座標x 
  157.   * @param y 座標y 
  158.   * @param z 座標z 2Dゲームの場合は0で 
  159.   * @param param 描画パラメータ  
  160.   */  
  161.  public static void render(Texture tex, float x, float y, float z, RenderParam param) {  
  162.   if (vbo == null) {  
  163.    //頂点4つ分用意  
  164.    float v[] = {  
  165.      //頂点  
  166.      000010100110,  
  167.    };  
  168.    float t[] = {  
  169.      //UV  
  170.      00011011,  
  171.    };  
  172.   
  173.    vbo = new Vbo();  
  174.    vbo.makeBuffer(v, t);  
  175.   }  
  176.   vbo.bindVBO();  
  177.   GL11 gl = Global.gl;  
  178.   
  179.   setTexture(tex.texID);  
  180.   gl.glColor4f(param.r, param.g, param.b, param.a);  
  181.   
  182.   if (param.cw + param.ch < 0) {  
  183.    param.cw = (float) tex.w;  
  184.    param.ch = (float) tex.h;  
  185.   }  
  186.   if (param.isCenterOrigin) {  
  187.    if (param.isDestsize) {  
  188.     param.ox = param.dw / 2;  
  189.     param.oy = param.dh / 2;  
  190.    } else {  
  191.     param.ox = param.cw * Math.abs(param.sx) / 2;  
  192.     param.oy = param.ch * Math.abs(param.sy) / 2;  
  193.    }  
  194.   }  
  195.   if (RenderParam.oldAddAlphaMode != param.isAddAlpha) {  
  196.    if (param.isAddAlpha) {  
  197.     gl.glDisable(GL10.GL_DEPTH_TEST);  
  198.     gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);  
  199.    } else {  
  200.     gl.glEnable(GL10.GL_DEPTH_TEST);  
  201.     gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);  
  202.    }  
  203.   }  
  204.   RenderParam.oldAddAlphaMode = param.isAddAlpha;  
  205.   
  206.   gl.glMatrixMode(GL10.GL_TEXTURE);  
  207.   gl.glLoadIdentity();  
  208.   gl.glTranslatef(param.cx + param.cw / tex.w * param.xindex, param.cy + param.ch / tex.h * param.yindex, 0);  
  209.   gl.glScalef(param.cw / tex.w, param.ch / tex.h, 1);  
  210.   
  211.   gl.glMatrixMode(GL10.GL_MODELVIEW);  
  212.   gl.glPushMatrix(); //カメラ行列を退避  
  213.   
  214.   //移動させつつ、原点指定しつつ  
  215.   if (param.isDestsize) {  
  216.    gl.glTranslatef(0.5f * param.dw - param.ox + x, 0.5f * param.dh - param.oy + y, z);  
  217.   } else {  
  218.    gl.glTranslatef(0.5f * param.cw * Math.abs(param.sx) - param.ox + x, 0.5f * param.ch * Math.abs(param.sy)  
  219.      - param.oy + y, z);  
  220.   }  
  221.   gl.glRotatef(param.ax, 001); //回転(なぜかラジアンじゃない)  
  222.   if (param.isDestsize) {  
  223.    gl.glScalef(param.dw, param.dh, 1); //拡大縮小  
  224.   } else {  
  225.    gl.glScalef(param.sx * param.cw, param.sy * param.ch, 1); //拡大縮小  
  226.   }  
  227.   gl.glTranslatef(-0.5f, -0.5f, 0); //中心を原点に回転するための小細工  
  228.   
  229.   gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 04); //横1縦1の頂点描画  
  230.   
  231.   gl.glPopMatrix(); //カメラ行列を戻す  
  232.  }  
  233.   
  234.  /** 
  235.   * ポリライン(テクスチャを線のように描画) 
  236.   * @param tex 描画したいテクスチャ 
  237.   * @param sx 始点x 
  238.   * @param sy 始点y 
  239.   * @param ex 終点x 
  240.   * @param ey 終点y 
  241.   * @param param パラメータ、幅など 
  242.   */  
  243.  void renderPolyLine(Texture tex, float sx, float sy, float ex, float ey, RenderParam param) {  
  244.   Vec3 tang = new Vec3(ex - sx, ey - sy, 0);  
  245.   float angle = (float) Math.atan2(tang.y, tang.x) * Util.TOANGLE;  
  246.   param.setDestSize(Math.abs(tang.getLength()), Math.abs(param.sx)).setAngle(angle);  
  247.   param.setCenterOrigin(true);  
  248.   render(tex, sx + tang.x / 2, sy + tang.y / 2, param);  
  249.  }  
  250.   
  251.  /** 
  252.   * 指定されたリソースを描画  
  253.   * 指定されたリソースがまだ読み込まれていない場合は読み込まれる 
  254.   * @param resID R.drawable.iconなど、リソースのIDを直指定 
  255.   * @param x 描画位置x 
  256.   * @param y 描画位置y 
  257.   * @param param RenderParamのインスタンスによって描画パラメータを操作 
  258.   */  
  259.  public static void render(int resID, int x, int y, RenderParam param) {  
  260.   render(get(resID), x, y, param);  
  261.  }  
  262.   
  263.  /** 
  264.   * 管理されているテクスチャを全て開放 
  265.   */  
  266.  public static void release() {  
  267.   int textureID[] = new int[1];  
  268.   for(Texture tex:texMap.values()){  
  269.    textureID[0] = tex.texID;  
  270.    Global.gl.glDeleteTextures(1, textureID, 0);  
  271.   }  
  272.   texMap.clear();  
  273.   texMap = null;    
  274.  }  
  275.   
  276.  /** 
  277.   * 画面クリア処理 
  278.   * Textureクラスに入れるのが適当がどうかは微妙なところ 
  279.   * 深度を有効化しないと、深度バッファのクリアがうまくいかない場合があるようなので、毎回入れてます。 負荷だけど。 
  280.   */  
  281.  public static void clear() {    
  282.   Global.gl.glEnable(GL10.GL_DEPTH_TEST);  
  283.   Global.gl.glDepthMask(true); // 深度バッファ書き込み有効  
  284.   Global.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);  
  285.  }  
  286.   
  287.  /** 
  288.   * 画面をクリアします 
  289.   * @param r 赤(0.0f~1.0f) 
  290.   * @param g 緑(0.0f~1.0f) 
  291.   * @param b 青(0.0f~1.0f) 
  292.   * @param a アルファ値(0.0f~1.0f) 
  293.   */  
  294.  public static void clear(float r,float g,float b,float a) {  
  295.   Global.gl.glClearColor(r,g,b,a);  
  296.   clear();  
  297.  }  
  298.  /** 
  299.   * 画面をクリアします 
  300.   * @param r 赤(0~255) 
  301.   * @param g 緑(0~255) 
  302.   * @param b 青(0~255) 
  303.   * @param a アルファ値(0~255) 
  304.   */  
  305.  public static void clear(int r,int g,int b,int a) {  
  306.   Global.gl.glClearColor(r/255.0f,g/255.0f,b/255.0f, a / 255.0f);  
  307.   clear();  
  308.  }  
  309. }  

しかし、ソースのほとんどが2D用だっていうのは僕と君だけの秘密だぞ。

0 件のコメント:

コメントを投稿