openGLでのスプライトアニメーション


9

openGL ESでのスプライトアニメーションの実装に関する問題に直面しています。私はそれをググってみました、そして私が得ている唯一のものはCanvasを介して実装するチュートリアルです。

私は方法を知っていますが、実装に問題があります。

必要なもの:衝突検出のスプライトアニメーション。

私がしたこと:衝突検出機能は適切に動作しています。

PS:すべてが正常に機能していますが、OPENGLのみでアニメーションを実装したいと考えています。私の場合、キャンバスが機能しません。

------------------------編集-----------------------

これでスプライトシートができました。下にある特定の座標があるとしますが、(u、v)座標はどこから始まるのでしょうか。(0,0)または(0,5)からのu、v座標を考慮し、どのパターンでリストに格納する必要がありますか?---->左から右または---->上から下

スプライトクラスに2D配列が必要ですか?これは、理解を深めるための画像です。

スプライトシート 私はNxNスプライトシートがあると仮定しています。ここで、N = 3,4,5,6、...などです。

class FragileSquare{

FloatBuffer fVertexBuffer, mTextureBuffer;

ByteBuffer mColorBuff;

ByteBuffer mIndexBuff;

int[] textures = new int[1];

public boolean beingHitFromBall = false;

int numberSprites = 49;

int columnInt = 7;      //number of columns as int

float columnFloat = 7.0f; //number of columns as float

float rowFloat = 7.0f;


public FragileSquare() {
    // TODO Auto-generated constructor stub

    float vertices [] = {-1.0f,1.0f,            //byte index 0
                         1.0f, 1.0f,            //byte index 1
                                    //byte index 2
                         -1.0f, -1.0f,
                         1.0f,-1.0f};           //byte index 3


    float textureCoord[] = {
                            0.0f,0.0f,
                            0.142f,0.0f,
                            0.0f,0.142f,
                            0.142f,0.142f           


    };


    byte indices[] = {0, 1, 2,
            1, 2, 3 };

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4*2 * 4); // 4 vertices, 2 co-ordinates(x,y) 4 for converting in float
    byteBuffer.order(ByteOrder.nativeOrder());
    fVertexBuffer = byteBuffer.asFloatBuffer();
    fVertexBuffer.put(vertices);
    fVertexBuffer.position(0);

    ByteBuffer byteBuffer2 = ByteBuffer.allocateDirect(textureCoord.length * 4);
    byteBuffer2.order(ByteOrder.nativeOrder());
    mTextureBuffer =  byteBuffer2.asFloatBuffer();
    mTextureBuffer.put(textureCoord);
    mTextureBuffer.position(0);

}



public void draw(GL10 gl){


    gl.glFrontFace(GL11.GL_CW);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glVertexPointer(1,GL10.GL_FLOAT, 0, fVertexBuffer);
    gl.glEnable(GL10.GL_TEXTURE_2D);
    int idx = (int) ((System.currentTimeMillis()%(200*4))/200);
    gl.glMatrixMode(GL10.GL_TEXTURE); 
    gl.glTranslatef((idx%columnInt)/columnFloat, (idx/columnInt)/rowFloat, 0);
    gl.glMatrixMode(GL10.GL_MODELVIEW); 
    gl.glEnable(GL10.GL_BLEND);
    gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); //4
    gl.glTexCoordPointer(2, GL10.GL_FLOAT,0, mTextureBuffer); //5
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //7
    gl.glFrontFace(GL11.GL_CCW);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    gl.glMatrixMode(GL10.GL_TEXTURE);
    gl.glLoadIdentity();
    gl.glMatrixMode(GL10.GL_MODELVIEW);
}

public void loadFragileTexture(GL10 gl, Context context, int resource)
{
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resource);
    gl.glGenTextures(1, textures, 0);
    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    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);
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
    bitmap.recycle();
}

}


1
スプライトアニメーションと衝突検出は、互いに何の関係もありません。
API-Beast

どんなアニメーションが欲しいですか?骨格、スプライトシート、何か他のもの?
GameDev-er 2012

@ GameDev-erスプライトシートがあります。
Siddharth-Verma 2012

1
@ミスタービースト私は彼らが互いに何の関係もないことを知っています。衝突後のスプライトアニメーションの実現を目指しています。これまでは、衝突検出を実現できました。しかし、スプライトアニメーションに関する限り、私はそれを行うことができません。PS:私はopenGL ESの初心者です。ここにもコメントがあります。
Siddharth-Verma 2012

@Sidなぜx / yが混同されているのですか?:( Xは水平軸です(本質的にそうではないことはわかっていますが、これは反対すべきではない規則です)
doppelgreener

回答:


6

これは、Androidアプリケーションで使用しているコードスニペットです。

gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glMatrixMode(GL10.GL_TEXTURE);    //edit the texture matrix
gl.glTranslatef(u, v, 0);            //translate the uv space (you can also rotate, scale, ...)
gl.glMatrixMode(GL10.GL_MODELVIEW);  //go back to the modelview matrix
gl.glBindTexture(GL10.GL_TEXTURE_2D, getTexture());
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);           //map the texture on the triangles
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, getTextureBuffer()); //load texture coordinates

ここでの秘訣は、glMatrixModeの後にglTranslatefを使用することです。これにより、UVスペースを変換できます。

(0,0)から(1,1)までのUV座標範囲

4つのフレームを持つ四角いテクスチャがあり、四角形をテクスチャリングしたいとします。以下の座標を使用して、UVスペースでフレームを定義します(選択はあなた次第です)

最初(0、0)(0.5、0.5)

2番目(0.5、0)(1、0.5)

3番目(0、0.5)(0.5、1)

4位(0.5、0.5)(1、1)

glTexCoordPointerを使用して、クワッドの最初のフレームをマップする必要があります。次に、2番目のフレームを表示する場合は、3番目のフレームに対してglTranslatef(0.5、0、0)、glTranslatef(0、0.5、0)を呼び出し、glTranslatef(0.5、0.5、0)を呼び出します。 )4日分。

上記のコードはテストされ、非常にうまく機能しています。この例が十分に明確であることを願っています。


編集:

描画関数の最後に、このコードでテクスチャマトリックスをリセットする必要があります。

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glMatrixMode(GL10.GL_MODELVIEW);

例として、5行と4列を取り上げましょう。スプライトセットには最大20個のスプライトがあるため、int idx =(int)((System.currentTimeMillis()%200 * number_of_sprites)))/ 200);を使用します。

idxは0からnumber_of_sprites-1になり(たとえば、5行、4列、18スプライトしかない場合は20未満にすることができます)、200ミリ秒ごとに値を変更します。スプライトが左から右、上から下にあるとすると、uv空間でフレーム座標を見つけることができます。

int c = 4;      //number of columns as int
float cf = 4.f; //number of columns as float
float rf = 5.f; //number of rows as float
gl.glTranslatef((idx%c)/cf, (idx/c)/rf, 0);

idx%cを実行すると、列インデックスが見つかります。結果は常に0からc-1の間です。

idx%cは整数です。0.0と1.0の間の値にスケーリングする必要があるため、cfで除算します。cfは浮動小数点なので、ここに暗黙的なキャストがあります

idx / cは同じですが、行の場合、idxとcは両方とも整数であるため、結果は引き続き整数であり、それは行インデックスであり、rfで割ると、0.0から1.0の間の値が得られます


ここでは三角形のストリップを使用しています。それで、この場合はうまくいきますか?
Siddharth-Verma 2012

もう1つ、どのようにして座標を保存する必要がありますか?----> 1D配列----> 2D配列?1Dの場合、配列内のすべての座標を考慮する必要がありますか?
Siddharth-Verma 2012

@Sidはい、同じです。正しいUVマッピング座標を使用する必要があります。あなたのコードを投稿するためにさらに助けが必要な場合よりも、私のコードスニペットを適応させるようにしてください
Marco Martinelli

glTexCoordPointerの@Sid UV座標は、1D配列に格納する必要があります
Marco Martinelli

1
私の知らない最初の問題については、ここで問題なく機能しています。2番目の問題については、idxを停止して0にロールバックする必要があるので、簡単な方法はこれです。そのint oldIdx;public FragileSquare()に、drawメソッドで変数を宣言してint idx = oldIdx==(numberSprites-1) ? (numberSprites-1) : (int)((System.currentTimeMillis()%(200*numberSprites))/200); oldIdx = idx; 、次のようにします。OTに行くと思うが、元の質問には答えました。おそらく、この質問を閉じ、必要に応じて新しい質問を開く必要があります。
Marco Martinelli、2012

1

私の提案:アニメーションのすべてのフレームを含むテクスチャを作成します(並べて)。表示したいフレームに応じてテクスチャ座標を変更します。


それの半分は行われました。しかし、この部分をどのように実現すればいいのか……「表示したいフレームに応じて、テクスチャ座標を変更します。」PS:私はopenGL ESの初心者です。
Siddharth-Verma 2012

1

スプライトシートと呼ばれるものを使用する必要があります。

ここに画像の説明を入力してください

スプライトシートは、キャラクターが取ることができるポーズを示すすべての異なる「フレーム」を含む単一の画像です。スプライトシートのどの「フレーム」を表示するかを、時間(爆発アニメーションの場合)またはプレーヤーの入力(左向き、右向き、銃の描画など)に基づいて選択します

このようことを行う最も簡単な方法は、関連するすべてのスプライトを同じサイズ(同じ幅と高さ)にすること(sprite_width*4.0 / sprite_sheet_width)です。そのため、左から4番目のスプライトの(u)座標を取得することはちょうどです。

最適化してスペース効率を高めようとしている場合は、TexturePackerなどのツールを使用して、スプライトを1つのシートにパックできます。TexturePackerは、ロードした各スプライトのxy位置を表すjsonまたはxmlデータも出力します。


すでにスプライトシートを持っています。私は方法を知っています、それは座標をシフトすることによって。しかし、私の主な質問は「これを実現する方法はopenGL ESですか?」です。このための疑似コードまたはJavaコードはありますか?アルゴリズムは私のために働くかもしれません。
Siddharth-Verma 2012

2
Spriteクラスを書く。Spriteクラスパーク内には、テクスチャ内の各「静止」の(u、v)座標を記述する(u、v)ペアのリストがあります。時間を追跡するには、さらに2つの変数が必要です。1つのフロートは「フレームごとの秒数」(各アニメーションフレームに費やす#秒)を格納し、もう1つのフロートは「クロック」と呼ばれ、アニメーションサイクルの「現在の時間」を格納します。描画に行くときは、現在の時刻を更新する必要があります。「フレームあたりの秒数」を超えると、アニメーションの次のフレームに移動し、アニメーションが続行します。
bobobobo 2012

さて、(u、v)ペアを含むリストは2次元配列になりますか?
Siddharth-Verma 2012

編集した質問をご覧ください。
Siddharth-Verma 2012

1

I_COLLIDEはOpenGLで使用できます。

ワールド内の各エンティティをボックスにしてから、ボックスの各軸が他のエンティティと衝突しているかどうかを確認します。

衝突をテストするエンティティが大量にある場合は、オクツリーにチェックインすることができます。単純に世界をセクターに分割し、同じセクター内のオブジェクト間の衝突のみをチェックします。

また、オープンソースの衝突検出および物理エンジンであるBulletダイナミクスエンジンを利用します。


衝突検出はすでに達成されています。私の目的は、スプライトアニメーションを作成することです。
Siddharth-Verma 2012
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.