iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android OpenGl 介绍(一)
  • 394
分享到

Android OpenGl 介绍(一)

android实时音视频 2023-09-01 20:09:11 394人浏览 薄情痞子
摘要

一、OpenGl 介绍 看到这个介绍,相信大家都不会陌生,因为在平时的工作中,或多或少大家都会听说过 openGl 这个东西,而且对它的印象基本都是觉得比较高深难懂。其实这个东西也不是那么难,那么无从下手,首先必须要了解一些基本的背景和搞懂

一、OpenGl 介绍

看到这个介绍,相信大家都不会陌生,因为在平时的工作中,或多或少大家都会听说过 openGl 这个东西,而且对它的印象基本都是觉得比较高深难懂。其实这个东西也不是那么难,那么无从下手,首先必须要了解一些基本的背景和搞懂一些基本概念,然后就可以按需学习了。

首先我们来看看官方对 OpenGl 的描述为:OpenGL( Open Graphics Library 开发图形接口)是一个跨平台的图形 api,用于指定 3D 图形处理硬件中的标准软件接口。

总结的来讲,OpenGl 提供了指定图形处理的硬件接口,我们在处理图形的时候,只要按照它的规则来调用,就可以获得更加高效的图形处理方法。

为了承上启下,必须要再了解以下 OpenGl 的背景,它的前身是 SGI 公司为其图形工作站开发的 IRIS GL。由于 IRIS GL 的兼容性不好,而且不太容易移植。因此在其基础上,SGI 公司开发出了 OpenGl。OpenGl 一般用于PC端的图形工作站,在移动端使用 OpenGl 基本带不动。为此,Khronos 公司就为 OpenGl 提供了一个子集,OpenGl ES(OpenGl for Embedded System)。是不是很自然的知道 OpenGl ES是啥,接着往下看。

二、OpenGl ES 介绍

这里直接上官方解释:OpenGl ES是免费的跨平台的功能完善的 2D/3D 图形库接口的 API,是OpenGL 的一个子集。

移动端使用到的基本上都是 OpenGl ES,当然 Android 开发下还专门提供了android.opengl 包,并且提供了 GlSurfaceView,GLU,GlUtils 等工具类。相信介绍到这里,大家都知道 OpenGl ES 是干什么的,很不巧,这里又是一句承上启下的话,因为这里引出了一堆新的名词,别急,下面一一介绍,大家就可以连起来了。

三、GlSurfaceView 介绍

顾名思义,它是一个SurfaceView,看源码可知,GlSurfaceView 继承 SurfaceView 的同时,增加了 Renderer,作用就是专门为 OpenGl 显示渲染使用的。看看下面的使用方法,十分平易近人:以通过创建的实例使用这个类,并随心所欲的设计属于你的 Renderer。

GLSurfaceView glSurfaceView = new GLSurfaceView(this);glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {    @Override    public void onSurfaceCreated(GL10 gl, EGLConfig config) {    }    @Override    public void onSurfaceChanged(GL10 gl, int width, int height) {    }    @Override    public void onDrawFrame(GL10 gl) {    }});

很巧,这里突然又冒出了个 GlSurfaceView.Renderer。

四、GlSurfaceView.Renderer 介绍

GlSurfaceView.Renderer 定义了用于绘制在图形所需的方法。在使用的时候,必须提供这个接口作为一个单独的类的实现,并通过 GLSurfaceView.setRenderer() 将其连接到 GLSurfaceView 使用实例,如上面的代码所示。通过 @Override,在此接口中设计随心所欲的渲染方法,当然这些方法是需要按照 OpenGl 的规则的。下面介绍以下该接口的方法的作用:

  • onSurfaceCreated():系统会在 GLSurfaceView 调用这个方法,因此这个方法适合用来执行只需要发生一次的操作,比如设置 OpenGL 的环境参数或初始化 OpenGL 图形对象。
  • onDrawFrame():系统调用此方法来重新绘制 GLSurfaceView,因此这个方法主要是用于绘制(和重新绘制)图形对象。
  • onSurfaceChanged():GLSurfaceView 当几何形状发生变化的时候,包括尺寸变化、设备屏幕的旋转。例如,当设备从纵向变为横向。

讲到这里,相信大家都有个基本概念和使用流程了,这里总结一下:

  • new 一个 GlSurfaceView;
  • 为这个 GlSurfaceView 配置渲染相关的设置;
  • 在 GlSurfaceView.Renderer 中绘制处理显示数据。

说了这么多,来个例子吧,图文并茂。

五、绘制几何图形

1、创建正方型图的类:

public class Square {        private FloatBuffer vertexBuffer;    private ShortBuffer drawListBuffer;    // 数组中每个顶点的坐标数    static final int COORDS_PER_VERTEX = 3;    static float squareCoords[] = {            -0.5f,  0.5f, 0.0f,   // 左上角            -0.5f, -0.5f, 0.0f,   // 左下角             0.5f, -0.5f, 0.0f,   // 右下角             0.5f,  0.5f, 0.0f }; // 右上角    // 绘制顶点的顺序    private short draWorder[] = { 0, 1, 2, 0, 2, 3 };    public Square() {        // 初始化 ByteBuffer,长度为 arr 数组的长度 * 4,因为 float 占4个字节        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(squareCoords.length * 4);        // 数组排列用 nativeOrder                byteBuffer.order(ByteOrder.nativeOrder());        // 从 ByteBuffer 创建一个浮点缓冲区        vertexBuffer = byteBuffer.asFloatBuffer();        // 将坐标添加到 FloatBuffer        vertexBuffer.put(squareCoords);        // 设置缓冲区来读取第一个坐标        vertexBuffer.position(0);        // 初始化 ByteBuffer,长度为 arr 数组的长度 * 2,因为 short 占2个字节        byteBuffer = ByteBuffer.allocateDirect(drawOrder.length * 2);        byteBuffer.order(ByteOrder.nativeOrder());        drawListBuffer = byteBuffer.asshortBuffer();        drawListBuffer.put(drawOrder);        drawListBuffer.position(0);    }}

这里要注意的是 Java 和 OpenGl 的缓冲区数据存储结构存在差异,Java 为 Big-Edian,而 OpenGl 为 Little-Edian。因此在 Android 中使用 OpenGl 的时候,需要进行数据存储格式转换。在代码中,一般会封装成工具类,这里提供几个封装好的轮子。

(1)将 int[] 数组转为 OpenGl 需要的 IntBuffer

private IntBuffer intBufferUtil(int[] intArray){    IntBuffer intBuffer;    // 初始化 ByteBuffer,长度为 intArray 数组的长度 * 4(sizeof(int)这就是4的由来)    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(intArray.length * 4);    // 数组排列用 nativeOrder    byteBuffer.order(ByteOrder.nativeOrder());    intBuffer = byteBuffer.asIntBuffer();    intBuffer.put(intArray);    intBuffer.position(0);    return intBuffer;}

(2)将 float[] 数组转为 OpenGl 需要的 FloatBuffer

private FloatBuffer floatBufferUtil(float[] floatArray){    FloatBuffer floatBuffer;    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(floatArray.length * 4);    byteBuffer.order(ByteOrder.nativeOrder());    floatBuffer = byteBuffer.asFloatBuffer();    floatBuffer.put(floatArray);    floatBuffer.position(0);    return floatArray;}

(3)将 short[] 数组转为 OpenGl 需要的 ShortBuffer

private ShortBuffer shortBufferUtil(short[] shortArray){    ShortBuffer shortBuffer;    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(shortArray.length * 2);    byteBuffer.order(ByteOrder.nativeOrder());    shortBuffer = byteBuffer.asShortBuffer();    shortBuffer.put(shortArray);    shortBuffer.position(0);    return shortBuffer;}

2、将形状渲染到 GlSurfaceView 中,主要可分为下面几步:
(1)首先我们需要在 GlSurfaceView.Renderer 中初始化需要渲染的几何图形

private Triangle mTriangle;private Square mSquare;public void onSurfaceCreated(GL10 unused, EGLConfig config) {    // 设置背景颜色    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    // 初始化 square    mSquare = new Square();}

(2)在绘制图形前至少需要一个顶点着色器来绘制形状和一个片段着色器的颜色。这些着色器要进行编译,然后加入到一个 OpenGL ES 程序。这里有两个比较难理解的概念:

  • 顶点着色器(Vertex Shader),也称为顶点遮蔽器,根据官方解释,顶点着色引擎是一种增加各式特效在3D场影中的处理单元,顶点着色引擎的可程式化特性允许开发者靠加载新的软件指令来调整各式的特效,每一个顶点将被各种的数据变素清楚地定义,至少包括每一顶点的x、y、z坐标,每一点顶点可能包函的数据有颜色、最初的径路、材质、光线特征等。前面的解释十分官方,简单点来说就是,你随心所欲的想法给到它,它来处理顶点(位置,颜色,纹理坐标),是用于渲染图形顶点的 OpenGL ES 图形代码。
  • 片段着色器(Fragment Shader ) ,也称为像素着色器,用于呈现形状的面的颜色或纹理的OpenGL ES代码。
  • 项目(Program),包含要用于绘制一个或多个形状着色器的 OpenGL ES 的对象。

下面给 Square 类定义基本的着色器代码:

public class Square {    private final String vertexShaderCode =            "attribute vec4 vPosition;" +                    "void main() {" +                    "  gl_Position = vPosition;" +                    "}";    private final String fragmentShaderCode =            "precision mediump float;" +                    "unifORM vec4 vColor;" +                    "void main() {" +                    "  gl_FraGColor = vColor;" +                    "}";...}

注意:着色器的代码执行起来代价十分的高,因此多次执行是不行的,一般将执行代码的逻辑写在带图形类的构造方法中。比如上面的 Square:

private final int mProgram;public Square() {    ... ...//这里省略上面的代码    int vertexShader = OneGlRenderer.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);    int fragmentShader = OneGlRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);    // 创建空的OpenGL ES程序    mProgram = GLES20.glCreateProgram();    // 添加顶点着色器到程序中    GLES20.glAttachShader(mProgram, vertexShader);    // 添加片段着色器到程序中    GLES20.glAttachShader(mProgram, fragmentShader);    // 创建OpenGL ES程序可执行文件    GLES20.glLinkProgram(mProgram);}

到这里,所有绘制的基本配置都完成了,然后就可以开始愉快的写绘制图形的方法,在形状类(Square)中创建一个绘制的方法 onDraw(),可以在 onDraw() 方法中编写绘制的逻辑。

public Square() {    ... ...//这里省略上面的代码    public void draw() {        // 将程序添加到OpenGL ES环境        GLES20.glUseProgram(mProgram);        // 获取顶点着色器的位置的句柄        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");        // 启用三角形顶点位置的句柄        GLES20.glEnableVertexAttribArray(mPositionHandle);        //准备三角形坐标数据        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,                GLES20.GL_FLOAT, false,                vertexStride, vertexBuffer);        // 获取片段着色器的颜色的句柄        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");        // 设置绘制三角形的颜色        GLES20.glUniform4fv(mColorHandle, 1, color, 0);        // 绘制三角形        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);        // 禁用顶点数组        GLES20.glDisableVertexAttribArray(mPositionHandle);    }}

完成上面所有步骤,只需要在GlSurfaceView.Renderer的onDrawFrame()方法中调用图形类的绘制方法即可(上面的onDraw()):

@Overridepublic void onDrawFrame(GL10 unused) {    mSquare.draw();}

大功告成!!!

参考链接:

来源地址:https://blog.csdn.net/2301_76382363/article/details/129183495

--结束END--

本文标题: Android OpenGl 介绍(一)

本文链接: https://www.lsjlt.com/news/389617.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android OpenGl 介绍(一)
    一、OpenGl 介绍 看到这个介绍,相信大家都不会陌生,因为在平时的工作中,或多或少大家都会听说过 openGl 这个东西,而且对它的印象基本都是觉得比较高深难懂。其实这个东西也不是那么难,那么无从下手,首先必须要了解一些基本的背景和搞懂...
    99+
    2023-09-01
    android 实时音视频
  • Android学习笔记——Menu介绍(一)
    背景: Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。 随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代...
    99+
    2022-06-06
    android学习 Android
  • Android RIL介绍
    文章目录 一、需求二、相关概念2.1 IMS2.2 Volte2.3 CS域与PS域2.3.1 CS域2.3.2 PS域 2.4 VOIP2.5 URC消息2.6 HIDL 三、环境...
    99+
    2023-09-29
    android 开发语言 java
  • Android dumpsys介绍
    文章目录 一、需求二、环境三、相关概念3.1 dumpsys3.2 Binder3.3 管道 四、dumpsys指令的使用4.1 dumpsys使用4.2 dumpsys指令语法 五、...
    99+
    2023-10-26
    1024程序员节
  • 什么是Android FrameWork,请你介绍一下?
    Framework是什么 Framework的中文意思是“框架”,在软件开发中通常指开发框架,在一个系统中处于内核层之上,为顶层应用提供接口,被设计用来帮助开发者快速开发顶层应用,而不必关心系统内核运...
    99+
    2023-09-24
    android ui 移动开发 Framework java
  • Android单元测试框架Robolectric3.0介绍(一)
      一、关于Robolectric3.0   文章中的所有代码在此:https://github.com/geniusmart/LoveUT,由于Robolectric3...
    99+
    2022-06-06
    android单元测试 测试 Android
  • Android自定义View中Paint、Rect、Canvas介绍(一)
    自定义View对于新手而言貌似是一个很复杂的东西。格式,各函数的意义。对于大神经常忘记各函数及一些参数的具体写法及意义,刚好在做一个风车效果,把过程及遇到的问题都写下来 1、如...
    99+
    2022-06-06
    view canvas rect Android
  • Android Socket 简单介绍
    文章目录 前言一、Socket是什么?百度百科的解释我自己的理解 二、简单示例1.服务端2.客户端3.布局4.实现 参考总结 前言 最近需求需要使用Socket进行通讯,我在工作...
    99+
    2023-09-23
    android
  • Android录屏 MediaRecorder介绍
    Android录屏 MediaRecorder介绍 Android录屏的三种方案 1、adb shell命令screenrecord 2、Med...
    99+
    2022-06-06
    mediarecorder Android
  • android AsyncTask详细介绍
    AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncT...
    99+
    2022-06-06
    asynctask Android
  • Android Bitmap详细介绍
    代码如下: package com.testbitmapscale; import java.io.File; import java.io.FileInputStream;...
    99+
    2022-06-06
    bitmap Android
  • android CursorLoader用法介绍
    工作内容集中到Contact模块,这个应用查询数据的地方很多,其使用了CursorLoader这个工具大大简化了代码复杂度。android自3.0提供了Loader机制,当时g...
    99+
    2022-06-06
    Android
  • Android ViewBinding使用介绍
    目录一、kotlin-android-extensions二、ViewBinding使用1.gradle配置2.在Activity 使用3.在Fragment使用4.在Adapter...
    99+
    2022-11-13
  • Android WorkManager使用介绍
    一、引言   WorkManager 是google提供的异步执行任务的管理框架,是 Android Jetpack 的一部分,会根据手机的API版本和应用程序的状态来选择适当的方式执行任务。   在...
    99+
    2023-09-07
    android
  • 初学Redis(一)--介绍
    1. 什么是NoSql NoSQL(Not Only SQL):不仅仅是SQL NoSQL是一项全新的数据库理念 NoSQL属于非关系型的数据库,没有表的概念,目的只是存储数据。 2. 为什么要使用NoSQL 使用NoSQL数据库为了...
    99+
    2018-09-14
    初学Redis(一)--介绍
  • Android View Binding使用介绍
    前言 Android Studio稳定版发布了3.6版本,带来了一些新变化:首先外观,启动页变了,logo改了,更显现代化;增加Multi Pr...
    99+
    2022-06-06
    view Android
  • android之ContentResolver与ContentProvider介绍
    android中对数据操作包含有: file, sqlite3, Preferences, ContectResolver与ContentProvider前三种数据操作方式都...
    99+
    2022-06-06
    Android
  • android WebView加载html5介绍
    Android设备多分辨率的问题 Android浏览器默认预览模式浏览 会缩小页面 WebView中则会以原始大小显示 Android浏览器和WebView默认为mdpi。hd...
    99+
    2022-06-06
    HTML webview HTML5 Android
  • Android Thread 介绍与实例
    Android中很重要的一个机制就是线程+消息,当然线程并不是android独有的,下面,简单的说说使用线程的时候应该注意的地方 我们采用最简单的方法来建立一个android的...
    99+
    2022-06-06
    Android
  • Android Handler的详细介绍
    Handler的定义  主要接受子线程发送的数据, 并用此数据配合主线程更新UI.  解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线...
    99+
    2022-06-06
    handler Android
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作