android平台使用Opengl实现点、线、三角形的绘制

图形绘制步骤

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);
}

}

你可能感兴趣的:(android平台使用Opengl实现点、线、三角形的绘制)