openGL画点---openGL学习笔记(二)

本例使用openGL画点方法,画出一条螺旋线,下图为成果图。(图片不是很清晰)

实现步骤:

1.同样是创建GLSurfaceView对象,再创建GLSurfaceView.renderer实现类.设置activity的contentView,以及设置view的render对象.具体代码上篇已有,不再赘述。

2.实现render类的过程,同样重写三个方法。

①onSurfaceCreate()方法:

第一步设置清屏色,第二步启用顶点缓冲数组。

②onSurfaceChanged()方法:

第一步设置视口,再设置平截头体,而要设置平截头体就要先指定矩阵类型为投影矩阵,设置过矩阵类型后,就马上要加载单位矩阵。
( 注:设置平截头体:为了视口所展示的画面不失真,一般设置平截头体的比例与视口比例相同。所以就要先计算视口比例,再应用到平截头体中)

③onDrawFrame()方法:

主要任务是放置眼球位置和画数组。
首先清除颜色缓冲区,再设置绘图颜色.
然后修改矩阵类型为模型视图矩阵(因为openGL是状态机,如果不修改就一直为投影矩阵)
同样,设置完矩阵类型之后,马上归零。(载入单位矩阵)
接下来放置眼球位置
最后一步画数组
而要画数组,就要先把数组的点计算出来。
所以先计算点的坐标。
用for循环出各个点的坐标后,放进list,
再将点坐标转换为缓冲区数据。
因为openGL是C语言实现的,所以要读缓冲区的数据就要先设置顶点指针
再把缓冲区指针位置定位到0位置。
最后,就可以画数组了。

通过以上几步,就完成了一个自定义渲染器,最后将该类new出来,把该类的对象set到GLSurfaceView中,最后设置view就大功告成了,细节在代码中有详细注释。

附代码:

/**
 * 点渲染器,绘制螺旋线。
 */
public class MyPointRenderer implements GLSurfaceView.Renderer{
    private float ratio;//视口比例
    public float xRotate = 0f;//X轴旋转的角度
    public float yRotate = 0f;//Y轴旋转的角度

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        /**
         * 步骤:
         * 第一步设置清屏色,第二步启用顶点缓冲数组。
         */

        //设置清屏色
        gl.glClearColor(0f, 0f, 0f, 1f);
        //启用顶点缓冲数组
        gl.glEnableClientState( GL10.GL_VERTEX_ARRAY );

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        /**步骤:
         * 第一步设置视口,再设置平截头体,而要设置平截头体就要先指定矩阵类型为投影矩阵
         * 设置过矩阵类型后,就马上要加载单位矩阵。
         *
         * 设置平截头体:
         * 为了视口所展示的画面不失真,一般设置平截头体的比例与视口比例相同。
         * 所以就要先计算视口比例,再应用到平截头体中。
         */

        //设置视口
        gl.glViewport(0,0,width,height);
        //计算视口比例
        ratio = (float)width / (float)height;
        //设置矩阵模式
        gl.glMatrixMode(GL10.GL_PROJECTION);
        //加载单位矩阵
        gl.glLoadIdentity();
        //设置平截头体
        gl.glFrustumf(-1f,1f,ratio,-ratio,3f,7f);

    }

    @Override
    public void onDrawFrame(GL10 gl) {

        /**
         * 步骤:
         * 主要任务是放置眼球位置和画矩阵。
         * 首先清除颜色缓冲区,再设置绘图颜色.
         * 然后修改矩阵类型为模型视图矩阵,
         * (因为openGL是状态机,如果不修改就一直为投影矩阵)
         * 同样,设置完矩阵类型之后,马上归零。(载入单位矩阵)
         *
         * 接下来放置眼球位置
         *
         * 最后一步画数组
         * 而要画数组,就要先把数组的点计算出来。
         * 所以先计算点的坐标。
         * for循环出各个点的坐标后,放进list         * 再将点坐标转换为缓冲区数据。
         * 因为openGLC语言实现的,所以要读缓冲区的数据就要先设置顶点指针
         * 再把缓冲区指针位置定位到0位置。
         * 最后,就可以画数组了。
         */

        //清除颜色缓冲区
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        //设置绘图颜色
        gl.glColor4f(1f,0f,0f,1f);
        //设置模型视图矩阵
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        //载入单位矩阵
        gl.glLoadIdentity();
        //放置眼球位置
        GLU.gluLookAt( gl,0f,0f,5f,0f,0f,0f,0f,1f,0f );
        //旋转角度,以便更直观查看
        gl.glRotatef(-90,1,0,0);// x轴旋转 (openGL规定,顺时针旋转为负值)
        gl.glRotatef(yRotate,1,0,0);// y轴旋转

        /**
         * 计算点的坐标
         * @param r 半径
         * @param coordsList 坐标集合
         * @param x,y,z 每个点的坐标
         * @param alpha 角度
         *
         */

        List<Float> coordsList = new ArrayList<Float>(); //list存放各个点
        float r = 0.5f;//半径
        float x = 0f,y = 0f,z = 1.5f;//点的坐标
        float zStep = 0.01f;//z轴的步长
        //for循环出各个点的坐标
        for( float alpha = 0f; alpha < Math.PI * 9;alpha = (float) (alpha+Math.PI / 24)){
            x = (float) (Math.cos(alpha) * r);
            y = (float) (Math.sin(alpha) * r);
            z = z - zStep;
            coordsList.add(x);
            coordsList.add(y);
            coordsList.add(z);
        }

        /**
         * 转换点成为缓冲区
         */

        ByteBuffer ibb = ByteBuffer.allocateDirect(coordsList.size() * 4);//一个浮点数等于四个字节
        ibb.order(ByteOrder.nativeOrder());//设置排列顺序,本地顺序
        FloatBuffer fbb = ibb.asFloatBuffer();//将字节缓冲转换成浮点缓冲
        //用增强for循环把每个坐标put进去
        for( float f : coordsList){
            fbb.put(f);
        }
        ibb.position(0);//把缓冲区指针位置定位到0位置
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ibb);//指定顶点指针

        /**
         * 画数组
         * 因为coordsList中用3个点存一个坐标,
         * 所以点的数量要除以3
         */
        gl.glDrawArrays( GL10.GL_POINTS,0,coordsList.size() / 3 );


    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值