Android OpenGL教程-第四课【转】

来源:互联网 发布:华为多个端口加入vlan 编辑:程序博客网 时间:2024/06/05 15:43

第四课 旋转:

在这一课里,我将教会你如何旋转三角形和四边形。左图中的三角形沿Y轴旋转,四边形沿着X轴旋转。

我们增加两个变量来控制这两个对象的旋转。这两个变量加在程序的开始处其他变量的后面。它们是浮点类型的变量,使得我们能够非常精确地旋转对象。浮点数包含小数位置,这意味着我们无需使用1、2、3…的角度。你会发现浮点数是OpenGL编程的基础。新变量中叫做 rtri 的用来旋转三角形, rquad 旋转四边形。

private float rtri, rquad;

在OnDrawFrame里面增加代码如下:

gl.glRotatef(rtri, 0.0f, 1.0f, 0.0f);   

三角形绕Y轴旋转;

gl.glRotatef(rquad, 1.0f, 0.0f, 0.0f);

四边形绕X轴旋转;

(注:原文中并没有详细在哪里加上面两句,学得有点绝望;经过自己尝试后,发现分别加在画三角形和四边形的glDrawArrays函数上面即可)

最后,增加旋转的角度

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

这里写图片描述

注:

一点测试代码

我们说了很久的顺时针,逆时针画图,到底有什么用呢

gl.glEnable(GL10.GL_CULL_FACE);

//设置openggl有剔除效果,就是看不到的面就不画,当然可以增加效率

gl.glFrontFace(GL10.GL_CCW);

//设置逆时针方向为正面

gl.glCullFace(GL10.GL_BACK);

//设置背面被剔除,不画

Cull就是剔除的意思
(注:转自http://www.cnblogs.com/wuqianling/p/6602351.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 = {            0f, 1f, 0f,   // 是上顶点            -1f, -1f, 0f, // 左下顶点            1f, -1f, 0f   // 右下顶点    };    private FloatBuffer mTriangleBuffer;    /**     * 三角形颜色     */    private float[] mColorArray={            1f,0f,0f,1f,     //红            0f,1f,0f,1f,     //绿            0f,0f,1f,1f      //蓝    };    private FloatBuffer mColorBuffer;    /**     * 正方形顶点     */    private float[] mQuadsArray = {            1f, 1f, 0f, // 右上            -1f, 1f, 0f, // 左上            -1f, -1f, 0f, // 左下            1f, -1f, 0f // 右下    }; // 从这里可以看出,我们按照逆时针的方向画图    private FloatBuffer mQuadsBuffer;    /**     * 该方法是画图方法,类似于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);        /**         * 正方形         */        gl.glLoadIdentity();        // 坐标向右移1.5个单位        gl.glTranslatef(1.5f, 0.0f, -6.0f);        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mQuadsBuffer);        //关闭颜色数组 -- 关闭颜色渲染功能.  (原文中没有这句,只有后面那句)        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);        gl.glColor4f(0.5f, 0.5f, 1f, 1f);        gl.glRotatef(rquad, 1.0f, 0.0f, 0.0f);//绕X轴旋转        gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 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);    }}

就是在原来的基础上加了一点点 为了方便以后查看

原创粉丝点击