2011-02-25 41 views
3

我希望能夠在我的Android應用程序中添加一點本機C代碼。我有一個IntBuffer,我用它作爲OpenGL的glColorPointer方法的參數。這是填充/使用這樣的事情:在Android遊戲中將java.nio.IntBuffer傳遞給C函數

private IntBuffer mColourBuffer; 
int[] colours = new int[10 * 4]; // 10 dots, 4 colour components per dot 


ByteBuffer vbb3 = ByteBuffer.allocateDirect(10 * 4 * 4); 
vbb3.order(ByteOrder.nativeOrder()); 
mColourBuffer = vbb3.asIntBuffer(); 
mColourBuffer.put(colours); 
mColourBuffer.position(0); 

gl.glColorPointer(4, GL10.GL_FIXED, 0, mColourBuffer); 

我想更改這個緩衝區,但它從Java太慢了,所以我想用本地代碼來做到這一點。我一直在尋找一個簡單的例子,但我找不到任何我可以理解的或者可行的東西。我見過很多關於傳遞元素的文檔,但我想要的只是一個指針。傳遞一個指針並在它指向的內存上運行應該非常有效;路過之間的Java和C會殺死可能做出的任何速度提升內存負載通過能夠從C

上的內存操作

到目前爲止,我想出了這一點:

void Java_com_poldie_myTouch2_myclass_mymethod(JNIEnv* env, jobject thiz, jintArray arr, int n) 
{ 
    jint *c_array; 

    c_array = (*env)->GetIntArrayElements(env, arr, NULL); 

    (*env)->ReleaseIntArrayElements(env, arr, c_array, 0); 


return; 


} 

,我可以這樣調用:

public native void mymethod(IntBuffer intbuf, int n); 

mymethod(mColourBuffer , n); 

其中至少運行,並似乎做了電話,但對c_array操作任何企圖(無論是作爲一個復引用指針或數組)導致程序立即退出。

我在正確的軌道上嗎?我可以將指向mColourBuffer後面的內存的指針傳遞給我的C代碼,並在返回到我的Java代碼時對其進行操作?

回答

2

在這裏回答我自己的問題,看起來答案是採用您的頂點數組(您正在使用Java操縱每個框架)並將它們寫入直接緩衝區。

在我上面的例子中,我想以某種方式填充直接緩衝區mColourBuffer每個框架與任何在本地數組'顏色'。原來你想要的東西是這樣的:

JNIfastPutf(mfColourBuffer, colours, nCount); 

其中nCount是要複製的字節數。在(本地,C)函數JNIfastPutf看起來是這樣的:

void Java_com_a_b_c_JNIfastPutf(JNIEnv* env, jobject thiz, jobject jo, jfloatArray jfa, int n) 
{ 
    float* pDst = (float*) (*env)->GetDirectBufferAddress(env, jo); 
    float* pSrc = (float*) (*env)->GetPrimitiveArrayCritical(env, jfa, 0);    
    memcpy(pDst, pSrc, n ); 

    (*env)->ReleasePrimitiveArrayCritical(env, jfa, pSrc, 0); 
} 

我發現下面的鏈接非常有幫助的(我的功能就是其C略加修改C版++爲例):

http://www.badlogicgames.com/wiki/index.php/Direct_Bulk_FloatBuffer.put_is_slow

他們解釋說,如果你使用浮動工具,你確實需要這種方法;使用整數據的速度要快得多,儘管這是我開始的地方,無論如何,他們的本地代碼在「快速」int版本中顯示的速度提高了20%到100%,所以似乎沒什麼原因不要這樣做!

+0

不同版本的Android之間的速度不同。更新版本的Dalvik核心庫具有更好的性能。 – fadden 2011-03-01 20:04:50