ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2019-12-08 05:26:49  阅读:284  来源: 互联网

标签:opengl-es bitmap c-4 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有