OpenGLES 渲染YUV(NV12)数据 JAVA实现

本文介绍了如何在Android中使用OpenGLES20渲染NV12格式的YUV数据。作者从零基础学习,详细记录了遇到的挑战,包括读取文件到ByteBuffer的问题以及使用ByteBuffer.allocate()和ByteBuffer.allocateDirect()的区别。最终实现了一个能够运行的程序,但只针对NV12格式,其他YUV格式需要调整shader和ByteBuffer的偏移。
摘要由CSDN通过智能技术生成

由于工作需要,这几天在研究OpenGLES的使用,并需要做出一个APK来实现NV12的渲染,由于对Java编程也不懂,所以还去补了点基础的东西,然后参考了很多文章才完成。这里就记录下我的工程和期间遇到的问题。
参考链接:

  • https://blog.csdn.net/yu540135101/article/details/101023208
  • https://blog.csdn.net/WuNLK/article/details/77017813
  • https://blog.csdn.net/ueryueryuery/article/details/17608185
  • https://www.jianshu.com/p/0ecc37cc2f6e
  • https://www.cnblogs.com/firstdream/p/7809404.html
  • https://blog.csdn.net/wang2470198567/article/details/45044283
  • https://blog.csdn.net/biggbang/article/details/20037073

还有一些琐碎的就不贴了,零基础的(我这种)可以先看看链接一的大佬的博客,学习点OpenGLES的基础知识,最好再掌握点yuv数据存储方式,这样才会明白分离yuv分量的字节偏移量。

话不多说,开工

  1. 要使用OpenGLES20,首先需要在AndroidManifest.xml种添加权限说明
<uses-permission 
    android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-feature
    android:glEsVersion="0x00020000" android:required="true" />

不要忘了加文件读取的权限~
2. 再放上Layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.opengl.GLSurfaceView
        android:id="@+id/MyGLView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>```

 4. MainActivity
这里面的内容就很简单了,就指定了布局,然后让MyRender渲染就完事儿了。

```java
public class MainActivity extends AppCompatActivity {
   

    //首先创建一个SurfaceView才能显示
    private GLSurfaceView mGLSurface;
    //创建自定义的Render才能渲染
    private MyRender mGLRender;

    //这里设定的宽高是yuv数据的宽高
    private int pic_width = 1280;
    private int pic_height = 720;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mGLSurface = findViewById(R.id.MyGLView);

        //使用自定义宽高布局
        ViewGroup.LayoutParams lp = mGLSurface.getLayoutParams();
        Point point_width = new Point();
        getWindowManager().getDefaultDisplay().getSize(point_width);
        lp.width = 1280;
        lp.height = 720;
        mGLSurface.setLayoutParams(lp);

        try {
   
            mGLRender = new MyRender(mGLSurface, pic_width, pic_height);
        } catch (FileNotFoundException e) {
   
            e.printStackTrace();
        }
    }
}
  1. 现在来看MyRender是怎么实现的
    MyRender继承与GLSurface.Render,主要重写了三个父类方法onSurfaceCreated(用于一些初始化操作),onSurfaceChanged(更改渲染信息时更新属性)和onDrawFrame(绘制)。
    以下是代码:
public class MyRender  implements GLSurfaceView.Renderer{
   
    private static final String TAG = "OpenGLES20_Test";

    private GLSurfaceView _GLSurfaceView;
    private int _program;
    private int _vertexShader;
    private int _fragmentShader;
    private FloatBuffer _vertexArray = null;
    private FloatBuffer _textureArray = null;
    private int _positionHandle;
    private int _textureHandle;

    private FileInputStream _yuvfilestream = null;
    private ByteBuffer _frameData = null;
    private FileChannel _yuvChinnel = null
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值