Android使用OpenGL ES显示纹理(使用NDK开发)

本文介绍了在Android中使用OpenGL ES显示2D纹理的流程,包括EGL环境初始化、着色器的准备、编译显卡执行program以及使用OpenGL API进行绘制。在EGL初始化后,通过加载glsl文件,编译着色器,创建并连接program,最后将纹理数据绑定并绘制到屏幕上。实现过程中涉及到libpng库用于PNG文件解码。运行示例需要在SD卡放置PNG图片并获取读写权限。
摘要由CSDN通过智能技术生成

书上第四章最后开始介绍使用OpenGL来显示一个2D纹理,其实做音视频2D基本满足绝大多数要求了,下面简单分析一下源码中的流程。

EGL环境初始化

首先我们需要在Java环境中初始化一个SurfaceView,然后在回调中我们传入surface。这里我将AssetsManager也传入Native,因为着色器的文件我是写在Assets中的,我们再Native层进行读取。Android Studio安装GLSL插件之后,编写glsl文件可以有关键字高亮,以及不用像在C语言中那样写大量的换行符。

SurfaceHolder mSurfaceHolder = surfaceView.getHolder();
mSurfaceHolder.addCallback(previewCallback);
...
private Callback previewCallback = new Callback() {

        public void surfaceCreated(SurfaceHolder holder) {
            pngPreviewController = new PngPreviewController();
            pngPreviewController.init(picPath,getAssets(),0);
            pngPreviewController.setSurface(holder.getSurface());
        }

        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
//          pngPreviewController.resetSize(width, height);
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
        }
    };

接下来先初始化PicPreviewController,以及调用start方法。

void
Java_com_example_yllds_androidopengldemo_PngPreviewController_init(JNIEnv *env, jobject thiz,
                                                                   jstring picPath,
                                                                   jobject assetManager,jint type) {
    controller = new PicPreviewController(env,assetManager,type);
    char* pngFilePath = (char*) env->GetStringUTFChars(picPath, NULL);
    LOGI("filepath %s",pngFilePath);
    controller->start(pngFilePath);
    env->ReleaseStringUTFChars(picPath, pngFilePath);
}

这里做一些初始化,因为demo中我写了一个fbo的测试代码,这里请先将type看做0。接下来就是去assets中读取对应的glsl文件,并存入PicPreviewRender类中。

PicPreviewController::PicPreviewController(JNIEnv *env, jobject assetManager, int type) {
   
    LOGI("VideoDutePlayerController instance created");
    pthread_mutex_init(&mLock, nullptr);
    pthread_cond_init(&mCondition, nullptr);
    screenWidth = 720;
    screenHeight = 720;
    this->type=type;
    char *vertexContent = nullptr;
    char *fragContent = nullptr;
    if (type == 0) {
        readSource(env, "texture/vertex_shader.glsl", "texture/fragment_shader.glsl",
                   assetManager, vertexContent,
                   fragContent);
    } else {
        readSource(env, "fbo/vertex_shader.glsl", "fbo/fragment_shader.glsl", assetManager,
                   vertexContent,
                   fragContent);
    }
    if (!vertexContent || !fragContent) {
        LOGI("read source failed");
        return;
    }
    LOGI("glsl content vertex %s", vertexContent);
    LOGI("glsl content frag %s", fragContent);
    if (ty
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值