前言
绘制全屏红色
/**
* GL测试视图
*/
public class GLView extends GLSurfaceView {
private GLRender mRender;
public GLView(Context context) {
this(context,null);
}
public GLView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init(){
// 设置OpenGL ES 2.0 context
setEGLContextClientVersion(2);
mRender = new GLRender();
// 设置渲染器
setRenderer(mRender);
}
}
/**
* GL渲染类
*/
public class GLRender implements GLSurfaceView.Renderer {
private static final String TAG = "=Test=GLRender";
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.d(TAG,"onSurfaceCreated");
// rbga
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.d(TAG,"onSurfaceChanged width:"+width+" height:"+height);
// GL视口
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
Log.d(TAG,"onDrawFrame");
// 清除颜色缓冲和深度缓存
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
}
}
绘制三角形
三角形:
/**
* 三角形
*/
public class Triangle {
// 顶点缓冲
private FloatBuffer vertexBuffer;
// 顶点着色代码
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;" +
"}";
private final int mProgram;
// 位置句柄
private int mPositionHandle;
private int mColorHandle;// 颜色句柄
static float sCoo[] = { //以逆时针顺序
0.0f, 0.0f, 0.0f, // 顶部
-1.0f, -1.0f, 0.0f, // 左下
1.0f, -1.0f, 0.0f // 右下
};
// 数组中每个顶点的坐标数
static final int COORDS_PER_VERTEX = 3;
private final int vertexStride = COORDS_PER_VERTEX * 4; // 3*4=12
private final int vertexCount = sCoo.length / COORDS_PER_VERTEX;// 顶点个数
// 颜色,rgba
float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
public Triangle() {
// 初始化顶点字节缓冲区; 每个浮点数:坐标个数 * 4字节
ByteBuffer bb = ByteBuffer.allocateDirect(sCoo.length*4);
// 使用本机硬件设备的字节顺序
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();// 从字节缓冲区创建浮点缓冲区
vertexBuffer.put(sCoo);// 将坐标添加到loatBuffer
vertexBuffer.position(0);// 设置缓冲区以读取第一个坐标
int vertexShader = GLRender.loadShader(GLES20.GL_VERTEX_SHADER// 顶点着色
,vertexShaderCode);
int fragmentShader = GLRender.loadShader(GLES20.GL_FRAGMENT_SHADER// 片元着色
,fragmentShaderCode);
mProgram = GLES20.glCreateProgram();// 创建空的OpenGL ES 程序
GLES20.glAttachShader(mProgram,vertexShader);// 加入顶点着色器
GLES20.glAttachShader(mProgram,fragmentShader);// 加入片元着色器
GLES20.glLinkProgram(mProgram);// 创建可执行的OpenGL ES 项目
}
public void draw(){
// 将程序添加到OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// 获取顶点着色器的vPosition成员的句柄
mPositionHandle = GLES20.glGetAttribLocation(mProgram,"vPosition");
// 启用三角形顶点的句柄
GLES20.glEnableVertexAttribArray(mPositionHandle);
// 准备三角形坐标数据
GLES20.glVertexAttribPointer(mPositionHandle// int index,索引
,COORDS_PER_VERTEX,// int size 大小
GLES20.GL_FLOAT,// int type 类型
false,// 是否标准化
vertexStride// 跨度
,vertexBuffer// 缓冲
);
// 获取片元着色器的vColor成员句柄
mColorHandle = GLES20.glGetUniformLocation(mProgram,"vColor");
// 为三角形设置颜色
GLES20.glUniform4fv(mColorHandle,1,color,0);
// 绘制三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,vertexCount);
// 禁用顶点数组:
/**
* 禁用index指定的通用顶点属性数组
* 默认情况下,禁用所有客户端功能,包括所有的通用顶点属性数组
* 如果启用,将访问通用顶点属性数组中的值
* 并在调用顶点数组命令(如:glDrawArrays或glDrawElements)时用于呈现。
*/
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
GL渲染类:
/**
* GL渲染类
*/
public class GLRender implements GLSurfaceView.Renderer {
private static final String TAG = "=Test=GLRender";
Triangle mTriangle;
/**
* 加载作色器
* @param type 顶点着色(GLES20.GL_VERTEX_SHADER); 片元着色(GLES20.GL_FRAGMENT_SHADER)
* @param shaderCode 着色代码
* @return 作色器
*/
public static int loadShader(int type,String shaderCode){
int shader = GLES20.glCreateShader(type);// 创建着色器
GLES20.glShaderSource(shader,shaderCode);// 添加着色器源代码
GLES20.glCompileShader(shader);// 编译
return shader;
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
Log.d(TAG,"onSurfaceCreated");
// rbga
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
mTriangle = new Triangle();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
Log.d(TAG,"onSurfaceChanged width:"+width+" height:"+height);
// GL视口
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
Log.d(TAG,"onDrawFrame");
// 清除颜色缓冲和深度缓存
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
mTriangle.draw();
}
}
OpenGl ES 着色脚本语言
GLSL(OpenGL Shader Language)。没有统一的拓展名。
.vert - 顶点着色器
.tesc - 曲面细分控制着色器
.tese - 曲面细分评估着色器
.geom - 集合着色器
.frag - 片元着色器
.comp - 计算着色器
原生数据类型:
float 浮点型
bool 布尔型
int 整型
|--- 支持8进制(0开头) 16进制(0x开头)
向量:存储及操作 颜色、位置、纹理坐标等
vec2 二维向量-浮点型
vec3 三维向量-浮点型
vec4 四维向量-浮点型
ivec2 二维向量-整型
ivec3 三维向量-整型
ivec4 四维向量-整型
bvec2 二维向量-布尔型
bvec3 三维向量-布尔型
bvec4 四维向量-布尔型
矩阵:根据矩阵的运算进行变换操作
mat2 2x2矩阵-浮点型
mat3 3x3矩阵-浮点型
mat4 4x4矩阵-浮点型
采样器:
sampler2D 二维纹理
sampler3D 三维纹理
samplerCube 立方贴图纹理
结构体:
struct ball{
// 三维向量浮点型
vec3 color;
vec3 position;
}
数组:
vec3 pos[];// 声明不定大小的三维向量浮点数组
vec3 pos[6];// 声明6个三维向量浮点数组
限定符:
attribute 顶点的变量,如:顶点位置、颜色
uniform
varying 用于从顶点着色其传递到片元着色器的变量
const
precision 精度
|---lowp
|---mediump
|---highp
资源文件读取:
/**
* OpenGL ES 辅助工具:资源文件读取
*/
public class GLUtils {
/**
* 从脚本中加载shader内容的方法
*/
public static int loadShaderAssets(Context ctx,int type,String name){
String result = null;
try {
InputStream in = ctx.getAssets().open(name);
int ch =0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((ch-in.read())!=-1){
baos.write(ch);
}
byte[] buff = baos.toByteArray();
baos.close();
in.close();
result = new String(buff,"UTF-8");
result = result.replaceAll("\r\n","\n");
}catch (Exception e){
e.printStackTrace();
}
return load
}
/**
* 加载着色器
* @param type 着色器类型;顶点着色器(GLES20.GL_VERTEX_SHADER); 片元着色器(GLES20.FRAGMENT_SHADER)
* @param shaderCode 着色代码
* @return 着色器
*/
public static int loadShader(int type,String shaderCode){
int shader = GLES20.glCreateShader(type);// 创建着色器
if (shader==0){// 加载失败,直接返回
return 0;
}
GLES20.glShaderSource(shader,shaderCode);// 加载着色器源代码
GLES20.glCompileShader(shader);// 编译
return checkCompile(type,shader);
}
/**
* 检查shader代码是否编译成功
* @param type 着色器类型
* @param shader 着色器
* @return 着色器
*/
private static int checkCompile(int type,int shader){
int[] compiled = new int[1];// 存放编译成功shader数量的数组
// 获取shader编译情况
GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,compiled,0);
if (compiled[0]==0){// 若编译失败则显示错误日志
Log.e("ES20_COMPILE_ERR","Could not compile shader "+type+":"+
GLES20.glGetShaderInfoLog(shader));
shader = 0;
}
return shader;
}
}
片元
tri.frag 声明片元精度;声明片元颜色,gl_FragColor是gl内定名。
precision mediump float;
uniform vec4 vColor;
void main() {
gl_FragColor = vColor;
}
// 颜色,rgba
float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
顶点
tri.vert
定义了一个四维向量给gl_Position
attribute vec4 vPosition;
void main() {
gl_Position = vPosition;
}