1.OpenGL 和OpenGL ES
OpenGL(Open Graphics Library)是一种用于渲染2D和3D图形的跨平台编程接口。OpenGL提供了一套标准的函数和接口,使开发人员能够在各种操作系统上创建高性能的图形应用程序,这些操作系统包括Windows、Linux、macOS和一些嵌入式系统。OpenGL ES(OpenGL for Embedded Systems)是OpenGL的嵌入式系统版本,专门设计用于移动设备、嵌入式系统和其他资源受限的环境。与标准的OpenGL相比,OpenGL ES经过精简和优化,以适应移动设备和嵌入式系统的硬件和性能要求。
它的应用场景如下:
- 游戏开发:移动游戏通常需要高性能的图形渲染,以呈现复杂的场景、光影效果和3D模型。OpenGL ES是移动游戏开发的主要工具之一,许多流行的移动游戏都使用它来实现图形渲染。
- 图形用户界面GUI:移动应用程序的用户界面通常包含复杂的图形元素,如按钮、滑块、图标等。OpenGL ES可用于创建流畅、响应迅速的用户界面,同时提供各种视觉效果。
- 地图和导航应用:在需要呈现复杂地图、导航路径和地理信息的应用中,OpenGL ES可以用于实现高性能的地图渲染。
- 娱乐和多媒体应用:通过OpenGL ES,开发者可以创建高质量的娱乐和多媒体应用,包括图像和视频编辑应用,艺术创作工具等。
2.第一个OpenGL ES应用程序
这个应用程序的功能非常简单,它要做的是初始化OpenGL并不停地清空屏幕。初始化OpenGL使用的类是GLSurfaceView,它可以处理OpenGL初始化过程中比较基本的操作,如配置显示设备,在后台线程中渲染,渲染是在显示设备中一个称为surface的特定区域完成的。在使用GLSurfaceView的时候,我们要处理好Activity生命周期事件,在Activity暂停的时候要释放资源,在Activity恢复的时候要重新恢复资源。
完整的代码如下:
package com.example.opengles20
import android.app.ActivityManager
import android.content.Context
import android.opengl.GLSurfaceView
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Toast
class MainActivity : AppCompatActivity() {
private lateinit var glSurfaceView: GLSurfaceView
var rendererSet=false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
glSurfaceView= GLSurfaceView(this)
//检查设备是否支持OpenGL ES 2.0
val activityManager=getSystemService(Context.ACTIVITY_SERVICE) as? ActivityManager
val configurationInfo=activityManager?.deviceConfigurationInfo
val support:Boolean= configurationInfo?.reqGlEsVersion!! >= 0x20000
if(support){//配置渲染表面
glSurfaceView.setEGLContextClientVersion(2)
glSurfaceView.setRenderer(MyRenderer())
rendererSet=true
}
else{
Toast.makeText(this,"这台设备不支持OpenGL ES 2.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.opengles20
import android.opengl.GLES20.*
import android.opengl.GLSurfaceView.Renderer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10
class MyRenderer:Renderer {
override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
glClearColor(0.0F,1.0F,0.0F,0.0F)//设置清除所使用的颜色,参数分别代表红绿蓝和透明度
}
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是一个接口,代表渲染器,图像的绘制就是由它控制的,它里面有三个方法需要实现:
- onSurfaceCreated:当surface被创建的时候,GLSurfaceView会调用这个方法,这发生在应用程序第一次运行的时候,并且当设备被唤醒或者用户从其他Activity返回的时候也可能被调用,也就是说该方法可能被多次调用
- onsurfaceChanged:每次surface尺寸发生变化的时候,这个方法会被GLSurfaceView调用,横竖屏切换的时候尺寸会发生变化
- onDrawFrame:当绘制一帧时,这个方法会被GLSurfaceView调用,在这个方法中,我们一定要绘制一些东西,因为这个方法返回时,渲染缓冲区会被交换并显示在屏幕上,如果什么都没有画,会看到糟糕的闪烁效果