2011-07-27 40 views
3

我在我的Java層有一個實現Renderer的類。在這個類裏面我有一個我想傳遞給JNI層的位圖。 JNI層將負責使用OpenGL顯示位圖。誰能告訴我如何做到這一點?如何通過C++中的OpenGLES在android中顯示位圖?

更新: 我知道有一個開放的GL方法glTexImage2D其可以被用於顯示一個簡單的2D圖像。任何人都可以告訴我如何使用它?調用這個方法之前和之後我需要做什麼設置?我應該如何將我的位圖傳遞給此方法(從Java到JNI)?

更新2 這是我當前的代碼:

Java類

public class HelloRenderer implements Renderer 
{ 
    Context _context; 
    Bitmap wood; 
    public void SetContext(Context context) 
    { 
     _context = context; 
     wood = BitmapFactory.decodeResource(_context.getResources(), R.drawable.hello); 
    } 

    @Override 
    public void onDrawFrame(GL10 gl) 
    { 
     RenderGLStuff(wood.getWidth(), wood.getHeight(), wood); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) 
    { 
     InitGLStuff(wood.getWidth(), wood.getHeight(), wood); 

    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) 
    { 

    } 

    private static native void InitGLStuff(int width, int height, Bitmap ptr); 
    private static native void RenderGLStuff(int width, int height, Bitmap ptr); 

    static 
    { 
     System.loadLibrary("myglstuff"); 
    } 
} 

JNI方法

JNIEXPORT void JNICALL Java_mine_NativeGL_HelloRenderer_InitGLStuff(JNIEnv * env, jobject obj, int width, int height, void * ptr) 
{ 
    glViewport(0, 0, width, height); 
    glClearColorx((GLfixed)(0.1f * 65536), (GLfixed)(0.2f * 65536), (GLfixed)(0.3f * 65536), 0x10000); 
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

} 

JNIEXPORT void JNICALL Java_mine_NativeGL_HelloRenderer_RenderGLStuff(JNIEnv * env, jobject obj, int width, int height, void * ptr) 
{ 
    GLuint texture; 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &ptr); 
} 

更新3 我已經更新了我的祖國這樣的代碼,現在我可以看到白盒子代替即時通訊年齡但沒有形象的內容。有任何想法嗎?

JNIEXPORT void JNICALL Java_mine_NativeGL_HelloRenderer_RenderGLStuff(JNIEnv * env, jobject obj, int width, int height, void * ptr) 
{ 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    GLfloat vertices[] = { -1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, }; 
    GLfloat normals[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0 }; 
    GLfloat textureCoords[] = { 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0 }; 

    GLuint texture; 
    glGenTextures(1, &texture); 
    glBindTexture(GL_TEXTURE_2D, texture); 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &ptr); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

    glBindTexture(GL_TEXTURE_2D, texture); 
    glVertexPointer(2, GL_FLOAT, 0, vertices); 
    glNormalPointer(GL_FLOAT, 0, normals); 
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrthof(-5.0, 5.0, -7.5, 7.5, -1, 1); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
} 
+0

你爲什麼這樣做的所有,而不是與正規[Android的GL接口]堅持認爲(http://developer.android.com/guide/topics/graphics/opengl.html)? – genpfault

+0

我知道這很奇怪,但這是要求。事實上,這是我無法實現的整個事情的第一步 –

回答

3

您不能直接傳遞一個java位圖類指針,並期望它可以與glTexImage2D一起使用。

glTexImage2D需要在指針中傳遞原始像素數據。 (實際上你的JNI本地C函數聲明看起來不正確,最後一個參數應該是jobject類型,而不是void *。使用「javah」生成正確的JNI函數簽名)

你需要從位圖中獲取數據bitmap.getPixels(..)或bitmap.copyPixelsToBuffer(..)調用,具體取決於您是否想要轉換像素格式。

看到它在Java中怎麼做,看代碼在這裏例如: applying texture to Cube, different texture on each face of cube

字節緩衝區fcbuffer是保存原始像素數據的變量。您應該能夠調用ByteBuffer.array()來獲取實際的數據指針並將其傳遞給JNI。

編輯:要清楚,你的RenderGLStuff應該有類型爲byte []的最後一個參數,並且從JNI/C-端你應該對傳入的jbyteArray類型變量調用GetByteArrayElements/ReleaseByteArrayElements。

EDIT2:要清透,林不知道你的限制是什麼,但也有你的紋理製作問題

  • 你可以做在Android上側(GLUtils紋理生成調用其他的解決方案。texImage2D是採取直接一個位圖)

  • ,你可以使用任何本地圖像庫

  • 如果你必須通過位圖從Java對象倒在本地端文件加載紋理,你必須得到原始數據指針如上所述

對於不同的方法了長時間的討論,看到這個線程http://groups.google.com/group/android-ndk/browse_thread/thread/eaf038cc50d5041e/c5874712be5382cf

EDIT3:我剛纔得知還有另一種方法

相關問題