使用概述
在Android上运行OpenGL ES程序需要用到GLSurfaceView控件,GLSurfaceView继承自SurfaceView并实现了GLThread,通过OpenGL ES进行绘制。
所有OpenGL相关的操作必须在GLThread线程执行,无法在主线程(UI线程)中执行。Render的onSurfaceCreated、onDrawFrame、onSurfaceChanged方法都是运行在GLThread线程。
OpenGL ES的使用步骤如下:
- 创建GLSurfaceView
- 设置GLES版本
- 设置Render
- 设置GlSurfaceView渲染模式
- 定义Vertex Shader和Fragment Shader
- 编译Shader(着色器)
- 创建Shander
- 加载Shader源码
- 编译Shader
- 查看编译结果
- 链接Program(着色器程序对象)
- 创建Program
- attach顶点着色器
- attach片段着色器
- 链接Program
- 渲染
- 设置窗口尺寸
- 激活着色器程序
- 启用顶点属性
- 设置顶点数据
- 绘制
声明APK需要OpenGL ES版本
//在设备上不存在指定的功能时,则该应用不能够正常运行
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
创建GLSurfaceView
public class OneActivity extends Activity {
private GLSurfaceView glSurfaceView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
glSurfaceView = findViewById(R.id.root_surface);
initGlSurface();
}
private void initGlSurface(){
//设置GLES版本
glSurfaceView.setEGLContextClientVersion(3);
//设置Render
glSurfaceView.setRenderer(new OneRenderer(this));
//设置GlSurfaceView渲染模式,一定要在setRenderer之后调用
//RENDERMODE_WHEN_DIRTY 只有在调用requestRender或者onResume等方法时才渲染
//RENDERMODE_CONTINUOUSLY 表示一直渲染
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
}
定义Shader
在assets下创建glsl文件夹,用于存放glsl(着色器语言)文件,创建one_vertex.glsl文件,保存 Vertex Shader(顶点着色器) 代码
#version 300 es
//顶点着色器的输入
in vec4 vPosition;
//设置 vPosition 的位置属性为 0,设置后不需要查询顶点属性
//layout (location=0) in vec4 vPosition;
void main() {
//gl_Position是内部变量,用来表示输入的顶点坐标
gl_Position = vPosition;
}
创建one_fragment.glsl文件,保存 Fragment Shader(片段着色器)代码:
#version 300 es
precision mediump float;
//片段着色器的输出
out vec4 FragColor;
void main(){
FragColor = vec4(1,0,0,1);
}
Java实现方案
编译Shader、链接Program
public class ShaderUtils {
private static final String TAG = "WHF_"+ShaderUtils.class.getSimpleName();
/**
* 编译着色器
* @param shaderType {@link GLES30#GL_VERTEX_SHADER} {@link GLES30#GL_FRAGMENT_SHADER}
* @param shaderSource glsl源码
*/
private static int compileShader(int shaderType,String shaderSource){
//创建空Shaderÿ