2012年2月28日火曜日

Androidでポリライン

シューティングゲームなんかでよく見るグネグネ曲がったホーミングレーザー

これを実際に作ろうとすると、中々に負荷がかかるです。
普通のテクスチャと違って頂点が固定化できないのでAndroidでは無理かなーと思ってたんだけどもとりあえずやってみた。

  1. private static final int VMAX = 128;  
  2.  private static float v[] = new float[VMAX * 4];  
  3.  private static float t[] = new float[VMAX * 4];  
  4.   
  5.  public static void renderPolyLine(Texture tex, Vector<vec2> vlist, RenderParam param) {  
  6.   if (tex.isEnable == falsereturn;  
  7.   
  8.   GL11 gl = Global.gl;  
  9.   
  10.   int vCnt = vlist.size();  
  11.   if (vCnt <= 1return;  
  12.   if (vCnt > VMAX) return;  
  13.   
  14.   final float w = param.sx / 2;  
  15.   tex.bind();  
  16.   gl.glColor4f(param.r, param.g, param.b, param.a);  
  17.   param.setAlpha();  
  18.   
  19.   float uv = 1.0f;  
  20.   Vec2 prevPos, pos, nextPos;  
  21.   float vx, vy, len;  
  22.   
  23.   for (int i = 0; i < vCnt; i++) {  
  24.    prevPos = vlist.get(Math.max(0, i - 1));  
  25.    pos = vlist.get(i);  
  26.    nextPos = vlist.get(Math.min(vCnt - 1, i + 1));  
  27.    //一つ手前と、一つ先のベクトルから、向いている方向を得る  
  28.    vx = prevPos.x - nextPos.x;  
  29.    vy = prevPos.y - nextPos.y;  
  30.    len = (float) Math.sqrt(vx * vx + vy * vy);  
  31.    if(len == 0.0f)len = 1;  
  32.    vx *= w / len;  
  33.    vy *= w / len;  
  34.   
  35.    //指定した横幅に広げる  
  36.    v[i * 4] = pos.x + vy;  
  37.    v[i * 4 + 1] = pos.y - vx;  
  38.    v[i * 4 + 2] = pos.x - vy;  
  39.    v[i * 4 + 3] = pos.y + vx;  
  40.   
  41.    //テクスチャもセットする  
  42.    t[i * 4] = 0;  
  43.    t[i * 4 + 1] = uv;  
  44.    t[i * 4 + 2] = 1;  
  45.    t[i * 4 + 3] = uv;  
  46.   
  47.    uv -= 1.0f / vCnt;  
  48.   }  
  49.   
  50.   gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0);  
  51.   gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, Util.makeFloatBufferArchive(t));  
  52.   gl.glVertexPointer(2, GL11.GL_FLOAT, 0, Util.makeFloatBufferArchive(v));  
  53.   
  54.   gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, 0, vCnt*2);  
  55.   
  56.   Vbo.repair();  
  57.  }  
  58. </vec2>  
ソースはこんな感じ。 どこかで見かけたソースなんだけど、描画しようとしているある点の一つ前と1つ後から進行方向を求めて、直行ベクトル(と、その反対)に幅を広げてあげている頂点をセットする感じ。 3Dだと外積だけど、2Dなおでxとyを入れ替えるだけ。 で、UVをちょっとずつずらす(綺麗に0~1に収まるようにする)。 テストでホーミングレーザーをした図
予想通り激重いけど、馬鹿みたいにばらまかなければ使えるかな。 でも、ホーミングレーザーって馬鹿みたいにばら撒くから綺麗なのに。 だめじゃな。 ちなみに、レーザー画像を
にすればこんな感じでファンシー(?)になるのがステキング。