书上第四章最后开始介绍使用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