package com.example.zhpeng.okhttptest.opengl;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class OpenglesActivity extends AppCompatActivity {
private TrtiangleView mGLView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a GLSurfaceView instance and set it
// as the ContentView for this Activity.
//创建一个GLSurfaceView实例,并将其设置为该Activity的ContentView。
mGLView = new TrtiangleView(this);
setContentView(mGLView);
}
}复制代码
(2) Render文件
package com.example.zhpeng.okhttptest.opengl;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* Created by zhpeng on 2017/10/25.
*创建一个Render类 实现GLSurfaceView.Renderer
*/
public class TriangleRender implements GLSurfaceView.Renderer {
private FloatBuffer vertexBuffer;
private Triangle triangle;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the background frame color
//设置背景帧颜色
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//4个参数分别对应 R,G,B,A
triangle = new Triangle();
}
//横竖屏切换时调用
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0,0,width,height);//设置窗口大小
}
@Override
public void onDrawFrame(GL10 gl) {
//Redraw background color 重新绘制背景颜色
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
triangle.draw();
}
public static int loadShader(int type, String shaderCode) {
// create a vertex shader type (GLES20.GL_VERTEX_SHADER) 创建一个顶点着色类型
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 或者一个片段着色器类型
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it 将源代码添加到着色器并编译它
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}复制代码
package com.example.zhpeng.okhttptest.opengl;
import android.opengl.GLES20;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
/**
* Created by zhpeng on 2017/10/25.
*/
public class Triangle {
// number of coordinates per vertex in this array 这个数组中每个顶点的坐标数
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = { // in counterclockwise order: 以逆时针顺序:
0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right
};
// Set color with red, green, blue and alpha (opacity) values
//设置红色、绿色、蓝色和alpha(不透明度)值的颜色
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };
private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX; //顶点数量
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex 每个顶点4字节
private final String vertexShaderCode =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" + //gl_Position为当前顶点的最终位置
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" + //gl_FragColor为当前片段最终输出的颜色
"}";
private final FloatBuffer vertexBuffer; //顶点坐标数据缓冲
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
public Triangle() {
// initialize vertex byte buffer for shape coordinates 为形状坐标初始化顶点字节缓冲
ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float) 坐标值的数字*一个float的字节数4
triangleCoords.length * 4);
// use the device hardware's native byte order 使用设备硬件的本地字节顺序
bb.order(ByteOrder.nativeOrder());
// create a floating point buffer from the ByteBuffer 从ByteBuffer创建一个浮点缓冲区
vertexBuffer = bb.asFloatBuffer();
// add the coordinates to the FloatBuffer 将坐标添加到浮动缓冲区
vertexBuffer.put(triangleCoords);
// set the buffer to read the first coordinate 设置缓冲区来读取第一个坐标
vertexBuffer.position(0);
int vertexShader = TriangleRender.loadShader(GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = TriangleRender.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
// create empty OpenGL ES Program 创建空的OpenGL ES程序
mProgram = GLES20.glCreateProgram();
// add the vertex shader to program 将顶点着色器添加到程序中
GLES20.glAttachShader(mProgram, vertexShader);
// add the fragment shader to program 将片段着色器添加到程序中
GLES20.glAttachShader(mProgram, fragmentShader);
// creates OpenGL ES program executables 创建OpenGL ES程序可执行文件
GLES20.glLinkProgram(mProgram);
}
public void draw(){
// Add program to OpenGL ES environment 将程序添加到OpenGL ES环境中
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member 对顶点着色器的vPosition number 进行处理
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices 对三角形顶点启用句柄
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data 准备三角坐标数据
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member 获取片段着色器的vColor成员的句柄
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle 绘制三角形的颜色
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// Draw the triangle 画三角形
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
// Disable vertex array 禁用顶点数组
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}复制代码
(3)GLSurfaceView 文件
package com.example.zhpeng.okhttptest.opengl;
import android.content.Context;
import android.opengl.GLSurfaceView;
/**
* Created by zhpeng on 2017/10/25.
*/
public class TrtiangleView extends GLSurfaceView{
private final TriangleRender triangleRender;
public TrtiangleView(Context context) {
super(context);
// Create an OpenGL ES 2.0 context 创建OpenGL ES 2.0的上下文
setEGLContextClientVersion(2);
triangleRender = new TriangleRender();
// Set the Renderer for drawing on the GLSurfaceView 在GLSurfaceView上设置渲染器
setRenderer(triangleRender);
// Render the view only when there is a change in the drawing data 只有当绘图数据发生变化时才呈现视图
setRenderMode(RENDERMODE_WHEN_DIRTY);
}
}复制代码