1

私は OpenGL ES に本当に慣れていない (私は昨日始めました =) と言うところから始めますが、Java や他の言語の経験はいくらかあります。

私はたくさんのチュートリアルを見てきましたが、もちろん Nehe のものもあり、私の仕事は主にそれに基づいています。

テストとして、小さなゼルダのようなゲームを作成するために「タイル ジェネレーター」の作成を開始しました (テクスチャ付きの正方形で男を動かすだけでもいいでしょう :p)。

これまでのところ、動作するタイル ジェネレーターが完成しました。char map[][] 配列を定義して、どのタイルがオンになっているかを格納します。

private char[][] map = {
            {0, 0, 20, 11, 11, 11, 11, 4, 0, 0},
            {0, 20, 16, 12, 12, 12, 12, 7, 4, 0},
            {20, 16, 17, 13, 13, 13, 13, 9, 7, 4},
            {21, 24, 18, 14, 14, 14, 14, 8, 5, 1},
            {21, 22, 25, 15, 15, 15, 15, 6, 2, 1},
            {21, 22, 23, 0, 0, 0, 0, 3, 2, 1},
            {21, 22, 23, 0, 0, 0, 0, 3, 2, 1},
            {26, 0, 0, 0, 0, 0, 0, 3, 2, 1},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}
    };

それは機能していますが、私はそれに満足していません。それらのことを行うためのより良い方法があると確信しています:

1) テクスチャのロード:

そのマップで使用したいタイルを含む見苦しい配列を作成します。

private int[] textures = {
            R.drawable.herbe, //0
            R.drawable.murdroite_haut, //1
            R.drawable.murdroite_milieu, //2
            R.drawable.murdroite_bas, //3
            R.drawable.angledroitehaut_haut, //4
            R.drawable.angledroitehaut_milieu,  //5
    };

(わざと切りました、現在27枚積んでいます)

これらはすべて drawable フォルダーに格納され、それぞれが 16*16 タイルです。

次に、この配列を使用してテクスチャを生成し、後で使用できるように HashMap に保存します。

int[] tmp_tex = new int[textures.length]; 
gl.glGenTextures(textures.length, tmp_tex, 0); 
texturesgen = tmp_tex; //Store the generated names in texturesgen 
for(int i=0; i < textures.length; i++)
{ 
    //Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), textures[i]);
    InputStream is = context.getResources().openRawResource(textures[i]);
    Bitmap bitmap = null;
    try {
        //BitmapFactory is an Android graphics utility for images
        bitmap = BitmapFactory.decodeStream(is);

    } finally {
        //Always clear and close
        try {
            is.close();
            is = null;
        } catch (IOException e) {
        }
    } 
    // Get a new texture name 
    // Load it up 
    this.textureMap.put(new Integer(textures[i]),new Integer(i)); 
    int tex = tmp_tex[i]; 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, tex); 
    //Create Nearest Filtered Texture
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

    bitmap.recycle();
} 

それを処理するためのより良い方法があると確信しています...私はそれを理解できませんでした。誰かがアイデアを持っているなら、私はすべての耳です。

2) タイルの描画

私がしたことは、単一の正方形と単一のテクスチャ マップを作成することでした。

/** The initial vertex definition */
    private float vertices[] = { 
                                -1.0f, -1.0f, 0.0f,     //Bottom Left
                                1.0f, -1.0f, 0.0f,      //Bottom Right
                                -1.0f, 1.0f, 0.0f,      //Top Left
                                1.0f, 1.0f, 0.0f        //Top Right
                                                };

    private float texture[] = {         
            //Mapping coordinates for the vertices
              0.0f, 1.0f,
              1.0f, 1.0f,
              0.0f, 0.0f,
              1.0f, 0.0f

                                };

次に、描画関数でマップをループして、使用するテクスチャを定義します (バッファをポイントして有効にした後)。

for(int y = 0; y < Y; y++){
    for(int x = 0; x < X; x++){
        tile = map[y][x];
        try 
            { 
                //Get the texture from the HashMap
                int textureid = ((Integer) this.textureMap.get(new Integer(textures[tile]))).intValue(); 
                gl.glBindTexture(GL10.GL_TEXTURE_2D, this.texturesgen[textureid]); 
            }    
            catch(Exception e) 
            { 
                return; 
            }

        //Draw the vertices as triangle strip
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);            
        gl.glTranslatef(2.0f, 0.0f, 0.0f); //A square takes 2x so I move +2x before drawing the next tile
    }
    gl.glTranslatef(-(float)(2*X), -2.0f, 0.0f); //Go back to the begining of the map X-wise and move 2y down before drawing the next line
}

これはうまく機能します。1000*1000 以上のマップでは、非常に遅くなると思います (念のため、これは典型的なゼルダの世界地図です: http://vgmaps.com/Atlas/SuperNES/LegendOfZelda- ALinkToThePast-LightWorld.png )。

Vertex Buffer Object と DisplayList について読んだことがありますが、良いチュートリアルが見つかりませんでした.nodobyは、どちらが最適であるか、サポートが優れているかについては問題ないようです(T1とNexus Oneはかなり離れています)。

それだけだと思います。たくさんのコードを書きましたが、役立つと思います。

前もって感謝します !

4

1 に答える 1

1

いくつかのこと:

  1. ハッシュマップを使用する必要はありません。ベクター/リストを使用するだけです。
  2. すべてのタイルを含む 1 つの大きなテクスチャを作成する方が高速で簡単な場合があります。適切なテクスチャ座標を使用して、適切なタイルを選択します。ここでは、テクスチャ フィルタリングについて少し注意する必要があるかもしれません。2D ゲームを行っているように聞こえますが、その場合、タイルに最近傍フィルタリングを使用し、カメラを整数のピクセル位置に固定する必要があります。
  3. GL_TRIANGLE_STRIP よりも GL_QUADS を使用する方が簡単ではないでしょうか。あなたのコードがよくわからない - 「テクスチャ」配列を使用していないようです。
  4. 画面上にないタイルを描画しない限り、マップ サイズに違いはありません。コードは次のようになります。

.

int minX = screenLeft / tileSize;
int minY = screenBottom / tileSize;
int maxX = screenRight / tileSize;
int maxY = screenTop / tilesSize;
for (int x = minX; x <= maxX; ++x)
{
   for (int y = minY; y < maxY; ++y)
   {
      ...
于 2010-03-15T12:02:01.327 に答える