2013-07-16 20 views
2

由於性能我搬到了OpenGL的2D從canvas.drawBitmap什麼是在OpenGL Android中爲精靈圖表中的對象添加動畫的技術?

這是精靈表4X1:

enter image description here

現在,使其工作,我曾跟隨類:

public Vulcan(ScreenObjectsView objectsView, int vulkanSpriteID, Context context) {  

    this.b = BitmapFactory.decodeResource(context.getResources(), vulkanSpriteID); 

    // 1x4 
    height = b.getHeight(); 
    width = b.getWidth()/4; 

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    Display display = wm.getDefaultDisplay(); 
    x = display.getWidth()/2-width/2; // deprecated 
    y = display.getHeight()-height; // deprecated 

} 

public void update() { 
    frameFreq++; 

    if(frameFreq > 0){ 
     currentFrame = ++currentFrame % 4; 
     frameFreq = 0; 
    }  
} 


@Override 
public void draw(Canvas canvas) { 
    update(); 

    int srcX = currentFrame * width; 

    Rect src = new Rect(srcX, 0, srcX+width, height); 
    Rect dst = new Rect(x, y, x+width, y+height); 

    canvas.drawBitmap(b, src, dst, null); 
} 

每個週期的時間我採取Rect和從左到右(在循環中):

currentFrame = ++currentFrame % 4; 

到目前爲止好。

我如何在OpenGL中爲上面提到的sprite表單添加動畫?

今天,我知道如何繪製和在OpenGL移動對象(感謝good demo

,但不知道跟精靈玩。

任何想法,鏈接,代碼片段?

[編輯]

THER是無腦膜使用精靈表或4張相似圖片:

enter image description hereenter image description here等。

奇怪的是,仍然沒有得到任何答案或方向。

謝謝

[編輯2]

根據什麼AERT說我實現了下面的代碼和它的作品。

但似乎凌亂

太多的代碼對OpenGL。對於每個紋理(我有4),我需要創建FloatBuffer:

也許有人有更短的路,或者我做錯了什麼。

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import javax.microedition.khronos.opengles.GL10; 

public class DevQuestSpriteBase { 

private static final String LOG_TAG = "Fess";//DevQuestSpriteBase.class.getSimpleName(); 

protected int mFrame = 0; 
protected int mSwitcher = 0; 
private int textureCount = 1; // frame animation 
protected int[] textures = new int[textureCount]; // frame animation 

// texture and verts 
protected FloatBuffer vertexBuffer, 
textureBuffer1, 
textureBuffer2, 
textureBuffer3, 
textureBuffer4; 

ByteBuffer bb1; 

protected float vertices[] = { 
     0f,0f,0.0f, 
     1f,0f,0.0f, 
     0f,1f,0.0f, 
     1f,1f,0.0f 
}; 


/** 1 frame */ 
protected float texture1[] = {   
     0.0f, 1.0f,  
     0.0f, 0.0f,  
     0.25f, 1.0f,  
     0.25f, 0.0f  
}; 
/** 2 frame */ 
protected float texture2[] = {   

     0.25f, 1.0f,   
     0.25f, 0.0f,   
     0.5f, 1.0f,  
     0.5f, 0.0f  
}; 
/** 3 frame */ 
protected float texture3[] = {   
     0.5f, 1.0f,  
     0.5f, 0.0f,  
     0.75f, 1.0f,  
     0.75f, 0.0f  
}; 
/** 4 frame */ 
protected float texture4[] = { 
     0.75f, 1.0f,   
     0.75f, 0.0f,   
     1.0f, 1.0f,  
     1.0f, 0.0f  
}; 


public DevQuestSpriteBase(){ 
    // vertices buffer 
    bb1 = ByteBuffer.allocateDirect(vertices.length * 4); 
    bb1.order(ByteOrder.nativeOrder()); 
    vertexBuffer = bb1.asFloatBuffer(); 
    vertexBuffer.put(vertices); 
    vertexBuffer.position(0); 

    // texture buffer 
    bb1 = ByteBuffer.allocateDirect(texture1.length * 4); 
    bb1.order(ByteOrder.nativeOrder()); 
    textureBuffer1 = bb1.asFloatBuffer(); 
    textureBuffer1.put(texture1); 
    textureBuffer1.position(0); 

    //######################################################### 

    // texture buffer 
    bb1 = ByteBuffer.allocateDirect(texture2.length * 4); 
    bb1.order(ByteOrder.nativeOrder()); 
    textureBuffer2 = bb1.asFloatBuffer(); 
    textureBuffer2.put(texture2); 
    textureBuffer2.position(0); 

    //######################################################### 

    // texture buffer 
    bb1 = ByteBuffer.allocateDirect(texture3.length * 4); 
    bb1.order(ByteOrder.nativeOrder()); 
    textureBuffer3 = bb1.asFloatBuffer(); 
    textureBuffer3.put(texture3); 
    textureBuffer3.position(0); 

    //######################################################### 

    // texture buffer 
    bb1 = ByteBuffer.allocateDirect(texture4.length * 4); 
    bb1.order(ByteOrder.nativeOrder()); 
    textureBuffer4 = bb1.asFloatBuffer(); 
    textureBuffer4.put(texture4); 
    textureBuffer4.position(0); 
} 


private void update() { 

    if(mSwitcher == 5){ 
     mFrame = ++mFrame % 4; 
     mSwitcher = 0; 
     // Log.e(LOG_TAG, "DevQuestSpriteBase :: " + mFrame); 
    } 
    else{ 
     mSwitcher++; 
    } 


} 

public void draw(GL10 gl){ 

    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 


    gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 

    if(mFrame == 0){ 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer1); 
    } 
    else if(mFrame == 1){ 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer2); 
    } 
    else if(mFrame == 2){ 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer3); 
    } 
    else if(mFrame == 3){ 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer4); 
    } 


    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); 

    //Log.e(LOG_TAG, "DevQuestSpriteBase :: draw"); 

    update(); 

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); 
    //gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer1); 
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3); 
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
    gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
} 


public int[] getTextures() { 
    return textures; 
} 
} 
+2

「*這是我的精靈表4x1:*」是不是* Doom的*精靈表? –

+0

是的,我把它從毀滅並且加了火,「我的」意味着在我的應用程序。良好的捕捉,:),我不是GUI設計師,並且對於演示/開發它已經足夠了, –

+0

一旦你加載你的紋理(4張圖片在同一個文件中),你可以在繪製之前「裁剪」你的紋理。 – VinceFR

回答

1

沒有進入很多細節,你需要做以下(假設您已經繪製用4個頂點精靈):

  • 定義紋理座標對應的頂點每個動畫幀的精靈,例如

    texCoordsFrame1 = [0.0f, 0.0f, 0.25f, 0.0f, 0.0f, 1.0f, 0.25f, 1.0f]; 
    
  • 上傳spritesheet紋理,例如,

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); 
    
  • 繪製使用紋理座標對應的幀你想在需要時顯示,例如

    ... 
    glBindTexture(GL_TEXTURE_2D, texture[0]); 
    glTexCoordPointer(2, GL_FLOAT, 0, texCoordsFrame1); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
    

或者,也可以上載單獨幀作爲個體紋理,但是這是從性能的角度來看不希望的。

有一些疑難雜症的

  • 使用GLES1,你只能使用冪的兩個紋理。在這種情況下,您必須縮放紋理或將其大小增加到2的冪次,並調整紋理座標。
  • 位圖與GL的y座標方向差異有點令人困惑,你最終可能會得到一個垂直翻轉的精靈。
+0

我也推薦使用[libgdx](http://libgdx.badlogicgames.com/)包,因爲它爲你做了很多這樣的事情(https://code.google.com/p/libgdx /維基/ SpriteAnimation)。 – Aert

+0

謝謝你隊友,所以從你的迴應中我得到了spritesheet 4x1我需要創建'texCoordsFrame1,texCoordsFrame2,..3,.4'。對?我看你只佔用1/4的寬度,問題在於'texture [0])'指的是什麼? –

+0

你不能使用'glTexCoordPointer'它應該是緩衝區。 –