初识openGL---openGL学习笔记(一)

openGL:

openGL是用C语言实现的,而我们作为安卓开发者,严格来讲,我们使用的是es,也就是openGL es,原因无非就像数据库一样,安卓上使用的数据库永远不可能是Mysql之类的,因为终端讲究轻量。

接下来我们来创建第一个openGL项目:

首先我们来了解一下GLSurfaceView这个类,这个类相当于是在屏幕上的一个模板,如下图。

所以,创建一个类继承GLSurfaceView之后,我们就可以new出GLSurfaceView类的对象,调用GLSurfaceView类的对象的setRenderer()方法,就可以对GLSurfaceView进行渲染,而我们的主要工作是,如何进行渲染。

class MyGLSurfaceView extends GLSurfaceView{

    public MyGLSurfaceView(Context context) {
        super(context);
    }

    public MyGLSurfaceView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    }


那么就要自定义一个渲染器:new一个类实现Renderer,需重写三个方法:onSurfaceCreated,onSurfaceChanged和onDrawFrame。

//自定义渲染器
class MyRenderer implements GLSurfaceView.Renderer{
    //表层创建时调用
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        //设置清屏色
        gl.glClearColor(0, 0, 0, 1);
        //启用顶点缓冲区
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    }
    //当表层size改变时调用
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {

        //设置视口,输出画面的区域。
        gl.glViewport(0,0,width,height);
        //宽高比
        float ratio = (float)width/(float)height;
        //矩阵模式,投影矩阵,openGL基于状态机。
        gl.glMatrixMode( GL10.GL_PROJECTION );
        //加载单位矩阵
        gl.glLoadIdentity();
        //设置平截头体
        gl.glFrustumf(-1f,1f,-ratio,ratio,3,7); //-1f,1f为平截头体左右大小比,-ratio,ratio为平截头体底面和顶面,3,7为近平面和原平面距离

    }
    //绘图调用
    @Override
    public void onDrawFrame(GL10 gl) {
        //清除颜色缓冲区。
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

        //模型视图矩阵。
        gl.glMatrixMode( GL10.GL_MODELVIEW );
        //加载单位矩阵。
        gl.glLoadIdentity();
        //0,0,5:放置眼球的坐标。
        //0,0,0:眼球观察的中心点坐标。
        //0,1,0:指定眼球向上的向量。
        GLU.gluLookAt(gl,0,0,5,0,0,0,0,1,0);

        /**
         * 画三角形
         */

        //三角形顶点坐标
        float [] coords = {
                0f,0.5f,0f,
                -0.5f,-0.5f,0f,
                0.5f,-0.5f,0f
        };
        //分配字节缓存空间,存放顶点坐标数据。
        ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);
        //设置顺序(本地顺序)。
        ibb.order(ByteOrder.nativeOrder());
        //放置顶点数组。
        FloatBuffer fbb = ibb.asFloatBuffer();
        fbb.put(coords);
        //定位指针位置,从该位置开始读取顶点数据。
        ibb.position(0);

        //设置绘图颜色:红色。
        gl.glColor4f(1f,0,0,1f);
        //3→三维点,使用三个坐标表示一个点。
        //每个点的数据类型。
        //0→跨度。
        //ibb指定缓冲区。
        gl.glVertexPointer(3,GL10.GL_FLOAT,0,ibb);
        //画数组
        gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);


    }
}
显而易见,onSurfaceCreated和 onSurfaceChanged都是在做初始化工作,关键的是onDrawFrame方法:

需要注意的是,onSurfaceChanged中设置的平截头体,所谓平截头体就是一个类似棱锥的区域,如下图:




最左边的眼睛通过中间墙上的孔,可以看得见与孔相同比例的空间,那么墙上的孔到墙后景物中间的四棱锥,就是一个平截头体。墙上的孔叫近平面,后方景物叫远平面。因为光是直射的,所以,我们只要指定好近平面的比例,以及图中两段红线的比例,那么就能确定远平面,继而确定平截头体。


确定了平截头体之后,就要关注onDrawFrame方法,类似于拍照的过程,我确定了要拍什么之后,还是要确定拍照时候要确定相机的位置,相机的朝向,相机的反正。这个三个属性就对应了程序中的GLU.gluLookAt()方法。详细参数见代码注释。


通过这几步之后,还是不能拍照,因为我们还有一些参数没有设置,比如绘图颜色。上例程序中是画了一个三角形,那么还需指定三角形的三点坐标等等,具体细节代码中注释的很详细,不再赘述。


上例代码运行效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值