接下来的事情也是要follow一定的模式的,因为GLSurfaceView.Renderer接口规定的三个函数对于开发人员来说不能回避,每次programming 3D的code,都必须要完成它们。

  1. onSurfaceCreated
    主要负责那些在view生命周期中,只需要完成一次的初始化工作,比如

    // preparation
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);                                           将vertex组织成array的形式
    // enable the differentiation of which side may be visible
    gl.glEnable(GL10.GL_CULL_FACE);                                                               采取削面动作,看不见的就不显示
    // which is the front? the one which is drawn counter clockwise
    gl.glFrontFace(GL10.GL_CCW);                                                                   front face(看得见的那面)是逆时针的
    // which one should NOT be drawn
    gl.glCullFace(GL10.GL_BACK);                                                                     back face(背面)不用画出

    这个函数也是初始化要在view中显示3D object的数据的好地方

  2. onSurfaceChanged
    顾名思义,就是当Surface改变时,要做的事情就放在这里了。比如surface的长宽被外部改变了,就要设置相应的viewport
    gl.glViewport(0, 0, w, h);
  3. onDrawFrame
    这是要点所在,每一frame的生成,均有它来完成,这里有个实例

        gl.glClearColor(red, green, blue, alpha);          //定义buffer颜色
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT);        //使用上述定义
        gl.glLoadIdentity();                                    //设置unit变换matrix
        gl.glScalef(0.5f, 0.5f, 0.5f);                         //matrix的xyz坐标均缩小一半
        gl.glColor4f(0.3f, 0.1f, 0.8f, 1.0f);                 //设置render face的颜色
        // set rotation
        gl.glRotatef(_xAngle, 1f, 0f, 0f);                   //绕x轴旋转
        gl.glRotatef(_yAngle, 0f, 1f, 0f);                   //绕y轴旋转
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);         //定义好顶点buffer
        gl.glDrawElements(GL10.GL_TRIANGLES, idxcnt, GL10.GL_UNSIGNED_SHORT, indexBuffer);       //开始画,边的顺序放在indexBuffer,这个indexBuffer同时也代表了face

  4. 需要注意的几点
    openGL使用的坐标系是right handed的,x轴的无穷大在屏幕右方,y轴的无穷大在屏幕上方,z轴的无穷大在屏幕前方
    openGL的一个face是个三角形,让我们看看是如何定义多个面的

    float[] coords={
            -1.0f, 1.0f,  -1.0f,          
            1.0f,  1.0f,  -1.0f,
            1.0f,  1.0f,  1.0f,
            -1.0f, 1.0f,  1.0f,
            -1.0f, -1.0f, -1.0f,
            1.0f,  -1.0f, -1.0f,
            1.0f,  -1.0f, 1.0f,
            -1.0f, -1.0f, 1.0f,
    };

    short[] indices = {
            0,2,1,  0,3,2,   //top
            7,5,6,  7,4,5,   //bottom
            3,6,2,  3,7,6,   //front
            1,4,0,  1,5,4,   //back
            0,7,3,  0,4,7,   //left
            2,5,1,  2,6,5    //right
    };
    coords定义了8个点,而indices定义了12个面,数组中3个数字一组,每个数字是下标,比如0,2,1就定义了一个三角形,即定义了一个面,对于这么三个数字而言如此的排列顺序其实也暗示了顺或逆时针方向,openGL很容易能知道这点,按照第一点的coding,如果这些face是顺时针的话,那么该face就不会被染色。

Advertisements