OpenGL(全写Open Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。
打开AndroidStudio新建名为“TrangleDemo”的项目
默认生成的MainActivity的setContentView不再放入layout的xml布局文件,而是GLSurfaceView
public class MainActivity extends Activity {
private MyGLSurfaceView mGLView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new MyGLSurfaceView(this);
setContentView(mGLView);
}
}
构建一个GLSurfaceView对象
新建MyGLSurfaceView类并继承GLSurfaceView
public class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context) {
super(context);
// 创建一个OpenGL ES 2.0 context,必须放在下一行代码之前,不然会报错
setEGLContextClientVersion(2);
//设置Renderer到GLSurfaceView
setRenderer(new MyRenderer());
//设置render模式为只在绘制数据发生改变时才绘制view
setRenderMode(MyGLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
构建一个渲染器Renderer
新建MyRenderer类并实现GLSurfaceView.Renderer
public class MyRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//设置背景色(red,green,blue,alpha透明度)
GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//设置视口
GLES20.glViewport(0, 0, width, height);
@Override
public void onDrawFrame(GL10 gl) {
//重绘背景色
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
}
启动模拟器,运行效果如图所示
上面的代码只是为我们创建了一块灰色的画布,为我们在上面画三角形做准备
定义形状,准备画三角形
新建Triangle类
public class Triangle {
private FloatBuffer vertexBuffer;//缓冲区
private int mProgram;//着色程序
private int mPositionHandle, mColorHandle;
static final int COORDS_PER_VERTEX = 3;// 数组中每个顶点的坐标数
static float triangleCoords[] = { // 按逆时针方向顺序:
0.0f, 0.622008459f, 0.0f, //top
-0.5f, -0.311004243f, 0.0f, //bottom left
0.5f, -0.311004243f, 0.0f //bottom right
};
// 设置颜色,分别为red, green, blue 和alpha (opacity)
float color[] = {0.63671875f, 0.76953125f, 0.22265625f, 1.0f};
public Triangle(){
// 为存放形状的坐标,初始化顶点字节缓冲
ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
// 设用设备的本点字节序
bb.order(ByteOrder.nativeOrder());
// 从ByteBuffer创建一个浮点缓冲
vertexBuffer = bb.asFloatBuffer();
// 把坐标们加入FloatBuffer中
vertexBuffer.put(triangleCoords);
// 设置buffer,从第一个坐标开始读
vertexBuffer.position(0);
}
}
绘制形状
在MyRenderer类的顶部实例化Triangle类
private Triangle mTriangle;
在MyRenderer类的onSurfaceCreated()方法中初始化形状
mTriangle = new Triangle();
在Triangle 类的顶部声明顶点着色器、片元着色器
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;"+
"}";
若要编译着色器代码,需在Triangle类中创建一个工具类方法
public static int loadShader(int shaderType, String shaderCode){
// 创建一个vertex shader类型(GLES20.GL_VERTEX_SHADER)
// 或fragment shader类型(GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(shaderType);
// 将源码添加到shader并编译之
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
为了绘制你的形状,你必须编译shader代码,添加它们到一个OpenGLES program 对象然后链接这个program。在Triangle类的构造方法中加入如下代码:
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // 创建一个空的OpenGL ES Program
GLES20.glAttachShader(mProgram, vertexShader); // 将vertex shader添加到program
GLES20.glAttachShader(mProgram, fragmentShader);// 将fragment shader添加到program
GLES20.glLinkProgram(mProgram); // 创建可执行的 OpenGL ES program
创建一个draw()方法来绘制形状
public void draw(){
// 将program加入OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// 获取指向vertex shader的成员vPosition的 handle
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// 启用一个指向三角形的顶点数组的handle
GLES20.glEnableVertexAttribArray(mPositionHandle);
// 准备三角形的坐标数据
GLES20.glVertexAttribPointer(
mPositionHandle,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
3 * 4,
vertexBuffer);
// 获取指向fragment shader的成员vColor的handle
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// 设置三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
//画三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3);
// 禁用指向三角形的顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
在Renderer的onDrawFrame()调用draw()方法
@Override
public void onDrawFrame(GL10 gl) {
...
mTriangle.draw();
}
启动模拟器,运行效果如下