其他分享
首页 > 其他分享> > 如何通过C中的OpenGLES在android中显示位图?

如何通过C中的OpenGLES在android中显示位图?

作者:互联网

我的Java层中有一个实现Renderer的类.在此类中,我有一个位图,希望传递给JNI层. JNI层将负责使用OpenGL显示位图.谁能告诉我该怎么做?

更新:
我知道有一个开放的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);
}

解决方法:

您不能直接传递Java Bitmap类指针,并且不能期望它与glTexImage2D一起使用.

glTexImage2D期望在指针中传递原始像素数据. (实际上,您的JNI本机C函数声明看起来不正确,最后一个参数应为jobject类型,而不是void *.请使用“ javah”生成正确的JNI函数签名)

您需要使用bitmap.getPixels(..)或bitmap.copyPixelsToBuffer(..)调用从位图中获取数据,具体取决于是否要转换像素格式.

要查看其在Java中的完成方式,请查看以下示例中的代码:
applying texture to Cube, different texture on each face of cube

ByteBuffer fcbuffer是保存原始像素数据的变量.您应该能够调用ByteBuffer.array()以获得实际的数据指针并将其传递给JNI.

编辑:要清楚,您的RenderGLStuff应该具有byte []类型的最后一个参数,并且从JNI / C端,您应该在传递的jbyteArray类型变量上调用GetByteArrayElements / ReleaseByteArrayElements.

EDIT2:非常清楚,我不确定您的约束是什么,但是还有其他解决纹理创建问题的方法

>您可以在Android端进行纹理生成调用(直接获取位图的GLUtils.texImage2D)
>您可以使用任何本机图像库从本机端的文件加载纹理
>如果必须从Java向下传递Bitmap对象,则必须按所述到达原始数据指针

有关不同方法的详细讨论,请参见线程http://groups.google.com/group/android-ndk/browse_thread/thread/eaf038cc50d5041e/c5874712be5382cf.

EDIT3:我刚刚了解到还有另一种方法

>像往下一样传递位图对象,并使用jnigraphics库获取对像素的原始访问,如此处所述What is JNI Graphics or how to use it?

标签:opengl-es,bitmap,c-4,android
来源: https://codeday.me/bug/20191208/2089096.html