Android OpenGL教程-第五课【转】

第五课 3D空间:

我们使用多边形和四边形创建3D物体,在这一课里,我们把三角形变为立体的金子塔形状,把四边形变为立方体。

先看看三角形的顶点变成啥了

private float[] mTriangleArray = {

           0.0f,1.0f,0.0f,

           -1.0f,-1.0f,1.0f,

           1.0f,-1.0f,1.0f,



           0.0f,1.0f,0.0f,

           1.0f,-1.0f,1.0f,

           1.0f,-1.0f,-1.0f,



           0.0f,1.0f,0.0f,

           1.0f,-1.0f,-1.0f,

           -1.0f,-1.0f,-1.0f,



           0.0f,1.0f,0.0f,

           -1.0f,-1.0f,-1.0f,

           -1.0f,-1.0f,1.0f

};

private FloatBuffer mTriangleBuffer;

一个四个面,每个面三个点,地面没画
这里写图片描述
你们仔细看看每个面,都是按逆时针方向画的。当然,如果你没有增加Cull剔除代码(上节课最后提到),至于顺时针,逆时针都无所谓,都画。但是我们还是推荐使用按照方向来写的array。

三角形的颜色数组来了

private float[] mColorArray={

           1.0f,0.0f,0.0f,1.0f,

           0.0f,1.0f,0.0f,1.0f,

           0.0f,0.0f,1.0f,1.0f,



           1.0f,0.0f,0.0f,1.0f,

           0.0f,0.0f,1.0f,1.0f,

           0.0f,1.0f,0.0f,1.0f,



           1.0f,0.0f,0.0f,1.0f,

           0.0f,1.0f,0.0f,1.0f,

           0.0f,0.0f,1.0f,1.0f,



           1.0f,0.0f,0.0f,1.0f,

           0.0f,0.0f,1.0f,1.0f,

           0.0f,1.0f,0.0f,1.0f,    

};

private FloatBuffer mColorBuffer;

注意,同一个点是同一个颜色。

立方体的顶点数组:(原文中没有)

// 四边形的顶点数组
private float[] mQuadsArray = {
            // 前
            1f, 1f, 1f, // 右上
            -1f, 1f, 1f, // 左上
            -1f, -1f, 1f, // 左下
            1f, -1f, 1f,// 右下
            // 右
            1f, 1f, -1f, // 右上
            1f, 1f, 1f, // 左上
            1f, -1f, 1f, // 左下
            1f, -1f, -1f,// 右下
            // 后
            -1f, 1f, -1f, // 右上
            1f, 1f, -1f, // 左上
            1f, -1f, -1f, // 左下
            -1f, -1f, -1f,// 右下
            // 左
            -1f, 1f, 1f, // 右上
            -1f, 1f, -1f, // 左上
            -1f, -1f, -1f, // 左下
            -1f, -1f, 1f, // 右下
            // 顶
            1f, 1f, -1f, // 右上
            -1f, 1f, -1f, // 左上
            -1f, 1f, 1f, // 左下
            1f, 1f, 1f, // 右下
            // 底
            1f, -1f, 1f, // 右上
            -1f, -1f, 1f, // 左上
            -1f, -1f, -1f, // 左下
            1f, -1f, -1f // 右下
}; // 从这里可以看出,我们按照逆时针的方向画图
private FloatBuffer mQuadsBuffer;

立方体的颜色数组来了

private float[] mQuadColorArray={

       0.0f,1.0f,0.0f,1.0f,

       0.0f,1.0f,0.0f,1.0f,

       0.0f,1.0f,0.0f,1.0f,

       0.0f,1.0f,0.0f,1.0f,



       1.0f,0.5f,0.0f,1.0f,

       1.0f,0.5f,0.0f,1.0f,

       1.0f,0.5f,0.0f,1.0f,

       1.0f,0.5f,0.0f,1.0f,



       1.0f,0.0f,0.0f,1.0f,

       1.0f,0.0f,0.0f,1.0f,

       1.0f,0.0f,0.0f,1.0f,

       1.0f,0.0f,0.0f,1.0f,



       1.0f,1.0f,0.0f,1.0f,

       1.0f,1.0f,0.0f,1.0f,

       1.0f,1.0f,0.0f,1.0f,

       1.0f,1.0f,0.0f,1.0f,



       0.0f,0.0f,1.0f,1.0f,

       0.0f,0.0f,1.0f,1.0f,

       0.0f,0.0f,1.0f,1.0f,

       0.0f,0.0f,1.0f,1.0f,



       1.0f,0.0f,1.0f,1.0f,

       1.0f,0.0f,1.0f,1.0f,

       1.0f,0.0f,1.0f,1.0f,

       1.0f,0.0f,1.0f,1.0f,

};

private FloatBuffer mQuadColorBuffer;

不要晕,后面有了纹理就好了,不过这是基础,一定要掌握。

画图的代码来了

     gl.glTranslatef(-1.5f, 0.0f, -6.0f);  
       gl.glRotatef(rtri, 0.0f, 1.0f, 0.0f);   //绕Y轴旋转  
//     gl.glColor4f(1f, 1f, 1f, 1f);  
       gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
       gl.glEnableClientState(GL10.GL_COLOR_ARRAY);  

       gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);  

       gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);  
       gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 12);     //四棱锥有4个面,每个面3个点  

       gl.glLoadIdentity();  
       gl.glTranslatef(1.5f, 0.0f, -6.0f);  
       gl.glRotatef(rquad, 1.0f, 0.0f, 0.0f);  // gl.glRotatef(rquad, 1.0f, -0.8f, 0.0f); // 斜着旋转

       gl.glColorPointer(4, GL10.GL_FLOAT, 0, mQuadColorBuffer);  
       gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mQuadsBuffer);  

       //依次画6个面  
       for (int i=0; i<6; i++){  
           gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, i*4, 4);           
       }  

       rtri+=0.2f;  
       rquad-=0.15f;  

运行结果:
这里写图片描述

(注:转自:http://www.cnblogs.com/wuqianling/p/6602549.html

我的代码如下:

package xxq.com.opengldemo;

import android.opengl.GLSurfaceView;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;


/**
 * 渲染器类,实现了GLSurfaceView.Renderer接口,实现这个接口,需要实现3个方法:OnSurfaceCreated(),
 * OnSurfaceChanged(),OnDrawFrame()。
 */

public class OpenGLRenderer implements GLSurfaceView.Renderer {
    private float cr, cg, cb;
    private float rtri, rquad;

    // (这是附加的)设置RGB颜色的方法
    public void setColor(float r, float g, float b) {
        cr = r;
        cg = g;
        cb = b;
    }

    /**
     * 三棱锥
     */
    private float[] mTriangleArray = {

            0.0f,1.0f,0.0f,

            -1.0f,-1.0f,1.0f,

            1.0f,-1.0f,1.0f,



            0.0f,1.0f,0.0f,

            1.0f,-1.0f,1.0f,

            1.0f,-1.0f,-1.0f,



            0.0f,1.0f,0.0f,

            1.0f,-1.0f,-1.0f,

            -1.0f,-1.0f,-1.0f,



            0.0f,1.0f,0.0f,

            -1.0f,-1.0f,-1.0f,

            -1.0f,-1.0f,1.0f

    };

    private FloatBuffer mTriangleBuffer;
    /**
     * 三棱锥颜色数组
     */
    private float[] mColorArray={

            1.0f,0.0f,0.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,



            1.0f,0.0f,0.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,



            1.0f,0.0f,0.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,



            1.0f,0.0f,0.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,

    };
    private FloatBuffer mColorBuffer;

    /**
     * 正方体定点数组
     */
    private float[] mQuadsArray = {
            // 前
            1f, 1f, 1f, // 右上
            -1f, 1f, 1f, // 左上
            -1f, -1f, 1f, // 左下
            1f, -1f, 1f,// 右下
            // 右
            1f, 1f, -1f, // 右上
            1f, 1f, 1f, // 左上
            1f, -1f, 1f, // 左下
            1f, -1f, -1f,// 右下
            // 后
            -1f, 1f, -1f, // 右上
            1f, 1f, -1f, // 左上
            1f, -1f, -1f, // 左下
            -1f, -1f, -1f,// 右下
            // 左
            -1f, 1f, 1f, // 右上
            -1f, 1f, -1f, // 左上
            -1f, -1f, -1f, // 左下
            -1f, -1f, 1f, // 右下
            // 顶
            1f, 1f, -1f, // 右上
            -1f, 1f, -1f, // 左上
            -1f, 1f, 1f, // 左下
            1f, 1f, 1f, // 右下
            // 底
            1f, -1f, 1f, // 右上
            -1f, -1f, 1f, // 左上
            -1f, -1f, -1f, // 左下
            1f, -1f, -1f // 右下
    }; // 从这里可以看出,我们按照逆时针的方向画图
    private FloatBuffer mQuadsBuffer;
    /**
     * 正方体颜色数组
     */
    private float[] mQuadColorArray={

            0.0f,1.0f,0.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,

            0.0f,1.0f,0.0f,1.0f,



            1.0f,0.5f,0.0f,1.0f,

            1.0f,0.5f,0.0f,1.0f,

            1.0f,0.5f,0.0f,1.0f,

            1.0f,0.5f,0.0f,1.0f,



            1.0f,0.0f,0.0f,1.0f,

            1.0f,0.0f,0.0f,1.0f,

            1.0f,0.0f,0.0f,1.0f,

            1.0f,0.0f,0.0f,1.0f,



            1.0f,1.0f,0.0f,1.0f,

            1.0f,1.0f,0.0f,1.0f,

            1.0f,1.0f,0.0f,1.0f,

            1.0f,1.0f,0.0f,1.0f,



            0.0f,0.0f,1.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,

            0.0f,0.0f,1.0f,1.0f,



            1.0f,0.0f,1.0f,1.0f,

            1.0f,0.0f,1.0f,1.0f,

            1.0f,0.0f,1.0f,1.0f,

            1.0f,0.0f,1.0f,1.0f,

    };

    private FloatBuffer mQuadColorBuffer;
    /**
     * 该方法是画图方法,类似于View类的OnDraw(),一般所有的画图操作都在这里实现。
     */
    @Override
    public void onDrawFrame(GL10 gl) {
        // 清除屏幕和深度缓存。
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        // 利用数组模型来画模型,要加此句(原文中没有)(没有这句画不出大三角形)
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        //设置颜色数组 -- 开启颜色渲染功能.
        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
        // 三角形的颜色为红色,透明度为不透明
        //使用数组作为颜色
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
        //数组指向一个buffer
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);

        rtri+=0.2f;
        rquad-=0.15f;
        /**
         * 三棱锥
         */
        // 重置当前的模型观察矩阵。
        gl.glLoadIdentity();
        // 沿着X轴左移1.5个单位,Y轴不动(0.0f),最后移入屏幕6.0f个单位
        gl.glTranslatef(-1.5f, 0.0f, -6.0f);
        gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
        // 设置顶点,第一个参数是坐标的维数,这里是3维,第二个参数,表示buffer里面放的是float,第三个参数是0,
        // 是因为我们的坐标在数组中是紧凑的排列的,没有使用offset,最后的参数放的是存放顶点坐标的buffer
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mTriangleBuffer);
        gl.glRotatef(rtri, 0.0f, 1.0f, 0.0f);   //绕Y轴旋转
        // 画数组,第一个参数表示画三角形,第二个参数是first,第三个参数是count,表示在buffer里面的坐标的开始和个数
//        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
        //依次画6个面
        for (int i=0; i<4; i++){
            gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, i*3, 4);
        }
        /**
         * 正方体
         */
        gl.glLoadIdentity();
        // 坐标向右移1.5个单位
        gl.glTranslatef(1.5f, 0.0f, -6.0f);
        gl.glColorPointer(4, GL10.GL_FLOAT, 0, mQuadColorBuffer);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mQuadsBuffer);
        gl.glRotatef(rquad, 1.0f, 0.0f, 0.0f);//绕X轴旋转

//        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4); // 画四边形
        for (int i=0; i<6; i++){
            gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, i*4, 4);
        }

        gl.glClearColor(cr, cg, cb, 0.0f);

    }

    /**
     * 在Surface发生改变的时候调用,例如从竖屏切换到横屏的时候
     */
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 设置输出屏幕大小
        gl.glViewport(0, 0, width, height);

        float ratio = (float) width / height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

    }

    /**
     * 在Surface创建的时候调用,一般在这里做一个初始化openggl的操作
     */
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 启用smooth shading(阴影平滑)。阴影平滑通过多边形精细的混合色彩,并对外部光进行平滑。
        gl.glShadeModel(GL10.GL_SMOOTH);

        // 设置清除屏幕时所用的颜色,参数对应(红,绿,蓝,Alpha值)。色彩值的范围从0.0f到1.0f。0.0f代表最黑的情况,1.0f就是最亮的情况。
        gl.glClearColor(0f, 0f, 0f, 0f);

        // 下面三行是关于depth buffer(深度缓存)的。将深度缓存设想为屏幕后面的层。深度缓存不断的对物体进入屏幕内部有多深进行跟踪。
        gl.glClearDepthf(1.0f);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

        // 这里告诉OpenGL我们希望进行最好的透视修正。这会十分轻微的影响性能。但使得透视图看起来好一点。
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

        mTriangleBuffer = BufferUtil.floatToBuffer(mTriangleArray);
        mQuadsBuffer = BufferUtil.floatToBuffer(mQuadsArray);
        mColorBuffer = BufferUtil.floatToBuffer(mColorArray);
        mQuadColorBuffer = BufferUtil.floatToBuffer(mQuadColorArray);

    }

}

猜你喜欢

转载自blog.csdn.net/qq_27686729/article/details/78457817