1.OpenGL 和OpenGL ES

  OpenGL(Open Graphics Library)是一种用于渲染2D和3D图形的跨平台编程接口。OpenGL提供了一套标准的函数和接口,使开发人员能够在各种操作系统上创建高性能的图形应用程序,这些操作系统包括Windows、Linux、macOS和一些嵌入式系统。OpenGL ES(OpenGL for Embedded Systems)是OpenGL的嵌入式系统版本,专门设计用于移动设备、嵌入式系统和其他资源受限的环境。与标准的OpenGL相比,OpenGL ES经过精简和优化,以适应移动设备和嵌入式系统的硬件和性能要求。

  它的应用场景如下:

  1. 游戏开发:移动游戏通常需要高性能的图形渲染,以呈现复杂的场景、光影效果和3D模型。OpenGL ES是移动游戏开发的主要工具之一,许多流行的移动游戏都使用它来实现图形渲染。
  2. 图形用户界面GUI:移动应用程序的用户界面通常包含复杂的图形元素,如按钮、滑块、图标等。OpenGL ES可用于创建流畅、响应迅速的用户界面,同时提供各种视觉效果。
  3. 地图和导航应用:在需要呈现复杂地图、导航路径和地理信息的应用中,OpenGL ES可以用于实现高性能的地图渲染。
  4. 娱乐和多媒体应用:通过OpenGL ES,开发者可以创建高质量的娱乐和多媒体应用,包括图像和视频编辑应用,艺术创作工具等。

2.第一个OpenGL ES应用程序

  这个应用程序的功能非常简单,它要做的是初始化OpenGL并不停地清空屏幕。初始化OpenGL使用的类是GLSurfaceView,它可以处理OpenGL初始化过程中比较基本的操作,如配置显示设备,在后台线程中渲染,渲染是在显示设备中一个称为surface的特定区域完成的。在使用GLSurfaceView的时候,我们要处理好Activity生命周期事件,在Activity暂停的时候要释放资源,在Activity恢复的时候要重新恢复资源。

  完整的代码如下:

package com.example.opengles30import android.app.ActivityManagerimport android.content.Contextimport android.opengl.GLSurfaceViewimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.widget.Toastclass MainActivity : AppCompatActivity() {private lateinit var glSurfaceView: GLSurfaceView
    var rendererSet=false
    override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)
        glSurfaceView= GLSurfaceView(this)//检查设备是否支持OpenGL ES 3.0
        val activityManager=getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
        val configurationInfo=activityManager?.deviceConfigurationInfo
        val support:Boolean= configurationInfo?.reqGlEsVersion!! >= 0x30000if(support){//配置渲染表面
            glSurfaceView.setEGLContextClientVersion(3)
            glSurfaceView.setRenderer(MyRenderer())
            rendererSet=true
        }else{
            Toast.makeText(this,"这台设备不支持OpenGL ES 3.0",Toast.LENGTH_SHORT).show()return
        }
        setContentView(glSurfaceView)
    }

    override fun onPause() {super.onPause()if(rendererSet){
            glSurfaceView.onPause()
        }
    }

    override fun onResume() {super.onResume()if(rendererSet){
            glSurfaceView.onResume()
        }
    }
}
package com.example.opengles30import android.opengl.GLES30.*import android.opengl.GLSurfaceView.Rendererimport javax.microedition.khronos.egl.EGLConfigimport javax.microedition.khronos.opengles.GL10class MyRenderer:Renderer {
    override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
        glClearColor(0.0F,1.0F,0.0F,0.0F)//设置清除所使用的颜色,参数分别代表红绿蓝和透明度,取值范围是从0到1    }

    override fun onSurfaceChanged(p0: GL10?, width: Int, height: Int) {
        glViewport(0,0,width,height)//是一个用于设置视口的函数,视口定义了在屏幕上渲染图形的区域。这个函数通常用于在渲染过程中指定绘图区域的大小和位置,前两个参数x,y表示视口左下角在屏幕的位置    }

    override fun onDrawFrame(p0: GL10?) {
        glClear(GL_COLOR_BUFFER_BIT)//清除帧缓冲区内容,和glClearColor一起使用    }
}

  Renderer是一个接口,代表渲染器,图像的绘制就是由它控制的,它里面有三个方法需要实现:

  1. onSurfaceCreated:当surface被创建的时候,GLSurfaceView会调用这个方法,这发生在应用程序第一次运行的时候,并且当设备被唤醒或者用户从其他Activity返回的时候也可能被调用,也就是说该方法可能被多次调用
  2. onsurfaceChanged:每次surface尺寸发生变化的时候,这个方法会被GLSurfaceView调用,横竖屏切换的时候尺寸会发生变化
  3. onDrawFrame:当绘制一帧时,这个方法会被GLSurfaceView调用,在这个方法中,我们一定要绘制一些东西,因为这个方法返回时,渲染缓冲区会被交换并显示在屏幕上,如果什么都没有画,会看到屏幕闪烁