1.1 自定义MyGLView 继承GLSurfaceView
1.1.1初始化GLSurfaceVeiw
init();
init实现
private viod init(){
//设置渲染器此处自定Renderer
setRenderer(new MyRenderder());
//设置渲染模式
setRenderMode(RENDERMODE_WHEN_DIRT);
//渲模式 有两种 和 被动
//RENDERMODE_WHEN_DIRTY 被动渲染 也是 等待渲用面 染 刷新界requestRender(),
//RENDERMODE_CONTINUOUSLY 主动渲染 onDrawFrame 消耗性能
}
//内部类 实现Renderer 接口 设置渲染器内容
public class MyGlSurfaceView extends GLSurfaceView{
public MyGlSurfaceView(Context context) {
super(context);
// 初始化渲染器
init();
}
private void init() {
//设置 渲染器
setRenderer(new MyRenderer());
//设置渲染模式
setRenderMode(RENDERMODE_CONTINUOUSLY);
//渲染模式有两种
//主动渲染 RENDERMODE_CONTINUOUSLY 由于每隔一段时间自动渲染所以 此模式消耗性能
//被动渲染 RENDERMODE_WHEN_DIRTY 需要的时候渲染 需要刷新 requestRender();
//我们暂使用主动模式
}
//自定义 renderer 实现需求功能 实现三个方法
private class MyRenderer implements Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//关闭抗抖动 对于颜色较少的系统 可以牺牲分辨率 通过抖动来增加颜色数量
gl.glDisable(GL10.GL_DITHER);
//设置 hint 模式 此处为 快速模式
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
//设置背景颜色 此处为黑色 RGBA
gl.glClearColor(0,0,0,0);
//开启深度检测
gl.glEnable(GL10.GL_DEPTH_TEST);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// 此方法中设置视口 因为 opengl是没有窗口的
//该方法参数意义
/**
* 1,2 为 手机屏幕 x y坐标 00 表左上角
* 3,4 表示 视口的宽和高
* 四个参数 则能绘制出一个举行视口
*/
gl.glViewport(0,0,width,height);
//设置投影矩阵
gl.glMatrixMode(GL10.GL_PROJECTION);
//矩阵单位化
gl.glLoadIdentity();
//获取视口的宽高比
float r = (float) width / height;
//然后 设置 是视角大小
//参数意义
/**
*
* 参数1表示 在近平面上 原点到左屏幕的距离
* 参数2 表示在近平面上 原点到又屏幕的距离
* 参数3 4 表示。。。上/下。。。
* r 是 屏幕宽高比例 正常情况r<1 即是 高大于宽
* 把高 设置为1 那么 原点到 左右屏幕距离就是r
* 参数5 近平面距离
* 参数6 是远平面距离 严格意义上可以 任意给值
* 但实际情况 为了屏幕正常显示自己想要的图形应适当给值
*/
gl.glFrustumf(-r,r,-1,1,1,10);
}
@Override
public void onDrawFrame(GL10 gl) {
//此方法是绘制的图形的
//首先清除颜色和深度缓存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//设置模型矩阵
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
//如果 你运行时 看不全自己要绘制的图形 这时候你可以 平移(缩放)一下
/**
* 参数解释
* 1,2 为 x,y轴上的平移量
* 3 为 z轴的平移量 注意 是float
*/
gl.glTranslatef(0, 0, -3.0f);
//绘制图形
//此处把绘制的功能 写成一个类
// DrawPoint point = new DrawPoint();
// point.mDraw(gl);
// DrawLine line = new DrawLine();
// line.mDraw(gl);
DrawTriangle drawTriangle = new DrawTriangle();
drawTriangle.mDraw(gl);
}
}
}
//工具类
public abstract class OpenGLUtils {
public FloatBuffer getFloatbuffer(float[] ver) {
ByteBuffer vbb = ByteBuffer.allocateDirect(ver.length * 4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer buffer = vbb.asFloatBuffer();
buffer.put(ver);
buffer.position(0);
return buffer;
}
public ByteBuffer getByteBuffer(byte[] indices) {
//创建三角形构造索引数据缓冲
ByteBuffer indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
return indexBuffer;
}
public IntBuffer getIntBuffer(int[] ver) {
//创建顶点坐标数据缓存,由于不同平台字节顺序不同,数据单元不是字节的
// 一定要经过ByteBuffer转换,关键是通过ByteOrder设置nativeOrder()
//一个整数四个字节,根据最新分配的内存块来创建一个有向的字节缓冲
ByteBuffer vbb = ByteBuffer.allocateDirect(ver.length * 4);
vbb.order(ByteOrder.nativeOrder());//设置这个字节缓冲的字节顺序为本地平台的字节顺序
IntBuffer intBuffer = vbb.asIntBuffer();//转换为int型缓冲
intBuffer.put(ver);//向缓冲区中放入顶点坐标数据
intBuffer.position(0);//设置缓冲区的起始位置
return intBuffer;
}
}
//画点
public class DrawPoint extends OpenGLUtils {
private IntBuffer verBuffer;
private IntBuffer colorBuffer;
private ByteBuffer indBuffer;
public DrawPoint() {
//初始化 顶点 颜色 和索引
init();
}
private void init() {
//设置 绘制的顶点数
int vCount = 4;
//设置缩放比
int UNIT_SIZE = 10000;
//初始化顶点数据
int ver[] = new int[]{
-2 * UNIT_SIZE, 3 * UNIT_SIZE, 0,//第一个点
UNIT_SIZE, UNIT_SIZE, 0,//第二个
-1 * UNIT_SIZE, -2 * UNIT_SIZE, 0,//第三个
2 * UNIT_SIZE, -3 * UNIT_SIZE, 0 //第四个
};
//创建顶点数据缓冲
verBuffer = getIntBuffer(ver);
//初始化顶点颜色
int one = 65535;//支持65535色彩通道
int color[] = new int[]{//RGBA
one, 0, 0, 0,
one, 0, 0, 0,
one, 0, 0, 0,
one, 0, 0, 0
};
//创建 颜色缓冲
colorBuffer = getIntBuffer(color);
//创建索引
byte indices[] = new byte[]{
0, 3, 2, 1
};
//创建索引缓冲
indBuffer = getByteBuffer(indices);
}
//绘制
public void mDraw(GL10 gl) {
//启用顶点坐标数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//启用顶颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置画笔
//为画笔指定顶点数据
/**
* 参数1坐标个数
* 参数2顶点数据类型
* 参数3 连续顶点坐标数据的间隔
* 参数4顶点数缓冲
*/
gl.glVertexPointer(3, GL10.GL_FIXED, 0, verBuffer);
//为花大笔指定顶点颜色数据
//同上
gl.glColorPointer(4,GL10.GL_FIXED,0,colorBuffer);
gl.glPointSize(10);
/**
* 参数1 绘制模型 点 线段 三角形
* 参数2 索引个数
* 参数3 数据类型
* 参数4 索引数据缓冲
*/
gl.glDrawElements(GL10.GL_POINTS,4,GL10.GL_UNSIGNED_BYTE,indBuffer);
}
}
//划线
public class DrawLine extends OpenGLUtils {
private IntBuffer verBuffer;
private IntBuffer colorBuffer;
private ByteBuffer indBuffer;
public DrawLine() {
//初始化 顶点 颜色 和索引
init();
}
private void init() {
//设置 绘制的顶点数
int vCount = 4;
//设置缩放比
int UNIT_SIZE = 10000;
//初始化顶点数据
int ver[] = new int[]{
-2 * UNIT_SIZE, 3 * UNIT_SIZE, 0,//第一个点
UNIT_SIZE, UNIT_SIZE, 0,//第二个
-1 * UNIT_SIZE, -2 * UNIT_SIZE, 0,//第三个
2 * UNIT_SIZE, -3 * UNIT_SIZE, 0 //第四个
};
//创建顶点数据缓冲
verBuffer = getIntBuffer(ver);
//初始化顶点颜色
int one = 65535;//支持65535色彩通道
int color[] = new int[]{//RGBA
one, 0, 0, 0,
one, 0, 0, 0,
one, 0, 0, 0,
one, 0, 0, 0
};
//创建 颜色缓冲
colorBuffer = getIntBuffer(color);
//创建索引
byte indices[] = new byte[]{
0, 3, 2, 1
};
//创建索引缓冲
indBuffer = getByteBuffer(indices);
}
//绘制
public void mDraw(GL10 gl) {
//启用顶点坐标数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//启用顶颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置画笔
//为画笔指定顶点数据
/**
* 参数1坐标个数
* 参数2顶点数据类型
* 参数3 连续顶点坐标数据的间隔
* 参数4顶点数缓冲
*/
gl.glVertexPointer(3, GL10.GL_FIXED, 0, verBuffer);
//为花大笔指定顶点颜色数据
//同上
gl.glColorPointer(4,GL10.GL_FIXED,0,colorBuffer);
/**
* 参数1 绘制模型 点 线段 三角形
* 参数2 索引个数
* 参数3 数据类型
* 参数4 索引数据缓冲
*/
gl.glDrawElements(GL10.GL_LINE_LOOP,4,GL10.GL_UNSIGNED_BYTE,indBuffer);
}
}
//画三角形
public class DrawTriangle extends OpenGLUtils {
private int vCount;
private FloatBuffer verBuffer;
private FloatBuffer colorBuffer;
public DrawTriangle() {
//初始化 顶点 颜色 和索引
init();
}
private void init() {
//设置多边形的 长度
int length = 45;
//设置顶点个数
vCount = (360 / length + 2);
//顶点坐标容器
float ver[] = new float[vCount * 3];
//第一个坐标点
//计数器
int count = 0;
ver[count++] =0;
ver[count++] =0;
ver[count++] =0;
for (int i = 0; i < 360 + length; i+=length) {
ver[count++] = (float) (Math.cos(Math.toRadians(i)) - Math.sin(Math.toRadians(i)));
ver[count++] = (float) (Math.cos(Math.toRadians(i)) + Math.sin(Math.toRadians(i)));
ver[count++] = 0;
}
verBuffer = getFloatbuffer(ver);
//顶点颜色
int one = 65535;//支持65535色彩通道
//顶点颜色数据(R GB A)
float color[] = new float[]{
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0,
0, one, 0, 0
};
//创建顶点颜色缓冲
colorBuffer = getFloatbuffer(color);
}
//绘制
public void mDraw(GL10 gl) {
//启用顶点坐标数组
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//启用顶颜色数组
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//设置画笔
//为画笔指定顶点数据
/**
* 参数1坐标个数
* 参数2顶点数据类型
* 参数3 连续顶点坐标数据的间隔
* 参数4顶点数缓冲
*/
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verBuffer);
//为花大笔指定顶点颜色数据
//同上
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
/**
* 参数1 绘制模型 点 线段 三角形
*2 数组缓存开始的位置
* 3 顶部观点个数
*/
gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0,vCount);
}
}