IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Studio + OpenGL ES 学习记录 -> 正文阅读

[移动开发]Android Studio + OpenGL ES 学习记录

Android Studio + OpenGL ES 学习记录

OpenGL是一种应用程序编程接口,它是一种可以对图形硬件设备特性进行访问的软件库,而OpenGL ES是OpenGL的子集,针对手机、PDA和游戏主机嵌入式设备而设计。OpenGL ES 是从 OpenGL 裁剪定制而来的,去除了 glBegin/glEnd,四边形(GL_QUADS)、多边形(GL_POLYGONS)等复杂图元等许多非绝对必要的特性,剩下最核心有用的部分。

简介

OpenGL是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API),而在嵌入式和移动平台的版本是OpenGL ES。Android最初就支持OpenGL ES的1.0版本,到现在已经支持到最新的3.2版本,下面的支持变化图:
在这里插入图片描述

版本支持声明

可以在AndroidManifet.xml中加入下面这行使用特性的声明,Google Play将会过滤掉不支持指定OpenGL ES版本的用户,拒绝他们安装。

  <!-- 需要OpenGL ES 2.0 -->
  <uses-feature android:glEsVersion="0x00020000" android:required="true" />

也可以在代码中判断gles的版本,version同样传入版本号即可(例如0x20000)

   public static boolean checkOpenGL(Activity activity, int version) {
      ActivityManager am = (ActivityManager) activity.getSystemService(Context.ACTIVITY_SERVICE);
      if (am != null) {
          return am.getDeviceConfigurationInfo().reqGlEsVersion >= version;
      }
      return false;
  }

OpenGL ES的名词解释
图元
官方的解释是图形软件用来描述各种图形的函数,可以理解为图元就是组成图像的基本单元。

顶点数据
在计算机中图元的位置是通过x,y,z,w来存储或颜色数据是通过RGBA的数组格式存储的,然后通过多个点来进行图元装配和光栅化出图形。

片元
元是光栅化过程的产物,光栅化是将一个图元转变为一个二维图象。

光栅化
光栅化是处理区域内的图元并生成片元数据。

OpenGL渲染管线
是显卡芯片内部处理图形信号相互独立的并行处理单元。也就是把数据转化到openGL并且生成最终图像的一个过程。

GLSL是什么
GLSL是一门专门为图形开发设计的编程语言。

可编程管线的编程阶段
在这里插入图片描述

基础

两个基本的类GLSurfaceView和GLSurfaceView.Renderer。
GLSurfaceView:继承自SurfaceView,用来显示渲染的图像。如果想操作你的图像,需要扩展触摸监听事件来处理。
GLSurfaceView.Renderer:GLSurfaceView的内部接口类,主要负责渲染图像。

GLSurfaceView主要方法:
setEGLContextClientVersion:设置OpenGL ES的版本,只能设置主要版本(例如:1,2,3),不能设置次要版本。
setEGLContextFactory:设置OpenGL ES的版本构建器,默认的构建器是根据版本设置的,可以自定义成版本自适应。
setRenderer:设置Renderer,如果不设置,那么界面显示的就是一片空白。
setRenderMode:设置Renderer的模式,有这么两种:1、RENDERMODE_WHEN_DIRTY(仅在创建时或调用requestRender时才会渲染内容);RENDERMODE_CONTINUOUSLY(不停的渲染)。
onPause:暂停渲染,在页面不再显示时可以调用,减少性能开销,例如在Activity的onStop时。
onResume:恢复渲染,类似onPause。 requestRender:请求渲染,通常是RENDERMODE_WHEN_DIRTY模式时使用,必须在setRenderer后才能使用。
queueEvent:插入一个Runnable任务到后台渲染线程上执行,必须在setRenderer后才能使用。 setDebugFlags:设置debug模式,主要有两种:1、DEBUG_CHECK_GL_ERROR(当GL调用glError()方法后如果发生异常会打印。主要用来跟踪OpenGL错误。);2、DEBUG_LOG_GL_CALLS(打印所有GL的verbose级别的日志)
2.GLSurfaceView.Renderer的主要方法:

onSurfaceCreated(GL10 gl, EGLConfig config):当Surface创建或重新创建时,这时可以进行初始化。
onSurfaceChanged(GL10 gl, int width, int height):Surface尺寸改变时,返回当前surface宽高,可以进行下一步操作。
onDrawFrame(GL10 gl):渲染绘制当前一帧时会调用。
OpenGL类:在包android.opengl下,主要有GLES20(OpenGL ES 2.0版本),GLES30,GLES31,GLES32和。

  public class BaseGLView extends GLSurfaceView {
      public BaseGLView(Context context) {
          this(context, null);
      }
 
      public BaseGLView(Context context, AttributeSet attrs) {
          super(context, attrs);
          setDebug();
          init();
      }
 
      protected void setDebug() {
          setDebugFlags(BuildConfig.DEBUG ? DEBUG_LOG_GL_CALLS : DEBUG_CHECK_GL_ERROR);
      }
 
      protected void init() {
          // 设置版本
          setEGLContextClientVersion(2);
          // 设置Renderer
          setRenderer(new BaseRenderer());
          // 设置渲染模式(默认RENDERMODE_CONTINUOUSLY)
          setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
      }
  }

新建一个自定义的Renderer类

 public class BaseRenderer implements GLSurfaceView.Renderer {
      private int bg = Color.BLACK;
 
      public BaseRenderer() {
      }
 
      public BaseRenderer(int bg) {
          this.bg = bg;
      }
 
 
      @Override
      public void onSurfaceCreated(GL10 gl, EGLConfig config) {
          // 设置背景色
          GLES20.glClearColor(Color.red(bg) / 255.0f, Color.green(bg) / 255.0f,
                  Color.blue(bg) / 255.0f, Color.alpha(bg) / 255.0f);
      }
 
      @Override
      public void onSurfaceChanged(GL10 gl, int width, int height) {
          // 设置显示范围
          GLES20.glViewport(0, 0, width, height);
      }
 
      @Override
      public void onDrawFrame(GL10 gl) {
          // 清屏
          GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
      }
  }

安卓手机下的坐标系

在这里插入图片描述
三维坐标系,原点在中间,x 轴向右,y 轴向上,z 轴朝向我们,x y z 取值范围都是 [-1, 1]:

在这里插入图片描述
OpenGL 纹理(texture)坐标系
二维坐标系,原点在左下角,s(x)轴向右,t(y)轴向上,x y 取值范围都是 [0, 1]:
在这里插入图片描述

绘制一个最简单的三角形

主程序:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GLSurfaceView glSurfaceView =
                (android.opengl.GLSurfaceView) findViewById(R.id.mGLSurfaceView);

        glSurfaceView.setEGLContextClientVersion(2);
        glSurfaceView.setRenderer(new MyRenderer());
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    }

    static class MyRenderer implements GLSurfaceView.Renderer {
        private static final String VERTEX_SHADER = "attribute vec4 vPosition;\n"
                + "void main() {\n"
                + "  gl_Position = vPosition;\n"
                + "}";
        private static final String FRAGMENT_SHADER = "precision mediump float;\n"
                + "void main() {\n"
                + "  gl_FragColor = vec4(0.5,0,0,1);\n"
                + "}";
        private static final float[] VERTEX = {   // in counterclockwise order:
                0, 1, 0.0f, // top
                -0.5f, -1, 0.0f, // bottom left
                1f, -1, 0.0f,  // bottom right
        };

        private final FloatBuffer mVertexBuffer;

        private int mProgram;
        private int mPositionHandle;

        MyRenderer() {
            mVertexBuffer = ByteBuffer.allocateDirect(VERTEX.length * 4)
                    .order(ByteOrder.nativeOrder())
                    .asFloatBuffer()
                    .put(VERTEX);
            mVertexBuffer.position(0);
        }

        @Override
        public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        }

        @Override
        public void onSurfaceChanged(GL10 unused, int width, int height) {
            mProgram = GLES20.glCreateProgram();
            int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, VERTEX_SHADER);
            int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, FRAGMENT_SHADER);
            GLES20.glAttachShader(mProgram, vertexShader);
            GLES20.glAttachShader(mProgram, fragmentShader);
            GLES20.glLinkProgram(mProgram);
            
            mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        }

        @Override
        public void onDrawFrame(GL10 unused) {
            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
    
            GLES20.glUseProgram(mProgram);

            GLES20.glEnableVertexAttribArray(mPositionHandle);
            GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false,
                    12, mVertexBuffer);

            GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);

            GLES20.glDisableVertexAttribArray(mPositionHandle);
        }

        static int loadShader(int type, String shaderCode) {
            int shader = GLES20.glCreateShader(type);
            GLES20.glShaderSource(shader, shaderCode);
            GLES20.glCompileShader(shader);
            return shader;
        }
    }
}

运行效果:
在这里插入图片描述

原文链接

fjnu 116052019030 huangyuxuan

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 12:56:35  更:2021-12-13 12:57:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:01:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码