在网上找了很多的资料,想利用android上层生成Bitmap,然后把Bitmap的pixel传递给JNI,然后再C++中生成纹理映射,但是结果都失败了。最后自己想得到了一个方法,在android上层直接生成纹理映射,然后把纹理映射的地址传递给JNI,这样就可以利用上层的Bitmap生成纹理映射了。当然这不是最好的方法,但是由于自己现在的能力有限,暂时只能依靠这个方法了,如果有人知道如何正确的利用Bitmap在C++中生成纹理映射,欢迎和我交流。(我利用Bitmap在C++中生成了纹理映射,但是纹理是乱纹,而不是正确的纹理,应该是我生成的Bitmap的pixel数组有问题。)下面是我的做法,可供参考,如果有更好的方法,请告知:我想要在OpenGLES中绘制文字,所以首先我利用Canvas生成想要的Bitmap,然后在android上层生成纹理映射,把纹理映射的绑定地址传递个JNI:public void onSurfaceCreated(GL10 gl10, EGLConfig eglconfig) {
  //从这里开始生成所需Bitmap  String s = "北京";                                                                           Bitmap bitmap;  //构建Bitmap,它的width和height必须是2的n次方
  bitmap = Bitmap.createBitmap(512, 512, Bitmap.Config.ARGB_8888);   Canvas canvas = new Canvas(bitmap); //设置画布背景为透明,这样我们的纹理就只显示文字,而没有颜色背景
  canvas.drawColor(Color.TRANSPARENT);
  Paint p = new Paint();  //设置字体、字体大小和字体颜色
  String familyName = "宋体";
  Typeface font = Typeface.create(familyName, Typeface.BOLD);
  p.setColor(Color.RED);
  p.setTypeface(font);
  p.setTextSize(50);  //在Bitmap上绘制文字
  canvas.drawText(s, 300, 60, p);                       
  s = "阴,23摄氏度";
  canvas.drawText(s, 0, 120, p);
  s = "高温:26,低温: 18 ";
  canvas.drawText(s, 0, 240, p);         //到这里为止,所需Bitmap构建完成  //从这里开始生成纹理映射  gl10.glGenTextures(1, TextureString, 0);  // Create Nearest Filtered Texture and bind it to texture 0
  gl10.glBindTexture(GL10.GL_TEXTURE_2D, TextureString[0]);
  gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
    GL10.GL_NEAREST);
  gl10.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
    GL10.GL_NEAREST);
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  //到这里纹理映射完成  //把我们的纹理映射地址传递给JNI  Native_SolarWind.DrawText(TextureString);  //初始化OpenglES场景设置
  Native_SolarWind.onSurfaceCreated(gl10, eglconfig, 0, 0);
 } 到这里为止,上层绑定纹理映射的工作完成。下面是在JNI中调用上层的纹理:JNI生成的头文件:/*
 * Class:     com_ygc_Native_Method * Method:    DrawText
 * Signature: ([B)V
 */
JNIEXPORT void JNICALL Java_com_ygc_Native_Method_DrawText
  (JNIEnv *, jclass, jintArray);对应的.cpp文件JNIEXPORT void JNICALL Java_com_ygc_Native_Method_DrawText
(JNIEnv *env , jclass cls, jintArray texture)
{
 TextureString = (GLuint *)env->GetIntArrayElements(texture,0);}其中TextureString变量为一个整型指针变量:extern GLuint *TextureString;用来绑定纹理映射。我们把android上层绑定纹理的整型变量的地址传递给TextureString,这样我们在cpp文件中,就可以利用这个地址来使用上层绑定的纹理了,类似于:glBindTexture(GL_TEXTURE_2D, *TextureString); 由于不能把全部代码贴上来,可能有些人看不太明白,对此我表示抱歉。如果有人需要使用这种方法,有不甚理解,可以回复我,我会详细解答你的疑惑。利用这种方法还有一个问题,就是在第一次渲染的时候,上层的纹理不可使用,必须旋转屏幕,重新加载,才可以正常显示,具体原因还在调查。当然最好的方法还是在cpp中绑定纹理,但是我现在还没有实现,希望了解此方法的人能给我一些帮助。我现在想要的是可否直接把bitmap对象传递个JNI,然后在JNI中对bitmap进行处理,得到用于纹理映射的byte数组,或者在java代码中对bitmap进行处理,得到用于纹理映射的byte数组,然后把byte数组传递给JNI,用来生成纹理。
我至今还没有找到解决的办法,而有没有OpenGLES中native private static int native_texImage2D(int target, int level, int internalformat,
            Bitmap bitmap, int type, int border);的源码,还请知道的大侠指点迷津。

解决方案 »

  1.   

    在JNI中可以这样:
    #include <android/bitmap.h>
    ......
    void* pixel_source = NULL;
    AndroidBitmap_lockPixels(env, bitmap, &pixel_source);    // bitmap 是android的Bitmap对象
    ......
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_width, tex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixel_source);还必须在mk文件中加上 -ljnigraphics 这个库的引用,这个就是 AndroidBitmap_lockPixels的库这样可以生成纹理了,但是我在4.0以上系统上可以正常生成纹理,但2.3.7这些系统上,纹理失真了,不知道怎么回事。