大话企业级Android应用开发实战 2D图形

                      42  2D图形 

42.3  绘制几何图形

编写GeoView.java:

public class GeoView extends View {

    private Paint mPaint = null;

    public GeoView(Context context) {

        super(context);

        mPaint = new Paint();

    }

   

    @Override

    protected void onDraw(Canvas canvas) {

        // TODO Auto-generated method stub

        super.onDraw(canvas);

        //设置画布颜色

        canvas.drawColor(Color.WHITE);

        //取消锯齿效果

        mPaint.setAntiAlias(true);

        //设置画笔格式为空心

        mPaint.setStyle(Paint.Style.STROKE);

       

        //创建外面大口

        Rect bigRect = new Rect();

        bigRect.left = 10;

        bigRect.top = 10;

        bigRect.right = 90;

        bigRect.bottom = 100;

       

        mPaint.setColor(Color.RED);

       

        canvas.drawRect(bigRect, mPaint);

        //画左边撇

        canvas.drawLine( 15,40,40,10, mPaint);

        //画右边捺

        canvas.drawLine(60, 10, 85, 40, mPaint);

        //创建里面小口

        Rect smallRect = new Rect();

       

        smallRect.left = 25;

        smallRect.top = 60;

        smallRect.right = 75;

        smallRect.bottom = 95;

       

        canvas.drawRect(smallRect, mPaint);

       

    }

编写GeoFigureActivity.java,通过该类创建并显示一个GeoView控件:

public class GeoFigureActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        GeoView geoView = new GeoView(this);

        setContentView(geoView);

    }

}

编写main.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<com.sharpandroid.geofigure.GeoView

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    />

</LinearLayout>

编写GeoFigureActivity.java:

public class GeoFigureActivity extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

    }

}

42.4  Matrix类介绍——对图片进行变幻

编写MatrixActivity.java:

package com.sharpandroid.matrix;

 

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Matrix;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

 

public class MatrixActivity extends Activity {

 

    private MatrixView matrixView;

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        matrixView = new MatrixView(this);

        setContentView(matrixView);

    }

 

    public boolean onKeyUp(int keyCode, KeyEvent event) {

        super.onKeyUp(keyCode, event);

        return true;

    }

 

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (matrixView == null) {

            return false;

        }

        if (keyCode == KeyEvent.KEYCODE_BACK) {

            this.finish();

            return true;

        }

        //将按键事件传递给matrixView处理

        return matrixView.onKeyDown(keyCode, event);

    }

 

    public class MatrixView extends View implements Runnable {

        // 声明Bitmap对象

        Bitmap bicycle = null;

        int bicycleWidth = 0;

        int bicycleHeight = 0;

 

        float angle = 0.0f;

        float scale = 1.0f;

        // 构建Matrix对象

        Matrix mMatrix = new Matrix();

 

        public MatrixView(Context context) {

            super(context);

 

            //装载资源

            bicycle = ((BitmapDrawable) getResources().getDrawable

(R.drawable.bicycle))

                    .getBitmap();

 

            // 得到图片的宽度和高度

            bicycleWidth = bicycle.getWidth();

            bicycleHeight = bicycle.getHeight();

 

            // 开启线程

            new Thread(this).start();

        }

 

        public void onDraw(Canvas canvas) {

            super.onDraw(canvas);

 

            // 重置mMatrix

            mMatrix.reset();

 

            // 设置旋转

            mMatrix.setRotate(angle);

            // 设置缩放比例

            mMatrix.postScale(scale, scale);

            // 按mMatrix的变形要求构建新的Bitmap

            Bitmap mbicycle2 = Bitmap.createBitmap(bicycle, 0, 0,

bicycleWidth,

                    bicycleHeight, mMatrix, true);

            //绘制变形之后的图片

            drawImage(canvas, mbicycle2, 10, 10);

            mbicycle2 = null;

        }

 

        // 按键按下事件

        public boolean onKeyDown(int keyCode, KeyEvent event) {

            // 左方向键

            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {

                angle = angle - 20;

            }

            // 右方向键

            else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {

                angle = angle + 20;

            }

            // 左方向键

            else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {

                if (scale > 0.5) {

                    scale = scale - 0.2f;

                }

            }

            // 右方向键

            else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {

                if (scale < 2.0) {

                    scale = scale + 0.2f;

                }

            }

            return true;

        }

 

 

        /**

         * 线程处理,不断刷新界面

         */

        public void run() {

            while (!Thread.currentThread().isInterrupted()) {

                try {

                    Thread.sleep(100);

                } catch (InterruptedException e) {

                    Thread.currentThread().interrupt();

                }

                // 使用postInvalidate可以直接在线程中更新界面

                postInvalidate();

            }

        }

 

        /**

         * 绘制一个Bitmap

         *

         * @param canvas

         *            画布

         * @param bitmap

         *            图片

         * @param x

         *            屏幕上的x坐标

         * @param y

         *            屏幕上的y坐标

         */

        public void drawImage(Canvas canvas, Bitmap bitmap, int x, int y) {

            /* 绘制图像 */

            canvas.drawBitmap(bitmap, x, y, null);

        }

    }

}

42.5  动画特效之Tween动画

1.通过Java代码实现Tween指令完成动画

编写TweenActivity.java:

package com.sharpandroid.tween;

 

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.view.animation.AlphaAnimation;

import android.view.animation.Animation;

import android.view.animation.AnimationSet;

import android.view.animation.RotateAnimation;

import android.view.animation.ScaleAnimation;

import android.view.animation.TranslateAnimation;

 

public class TweenActivity extends Activity {

 

    private View mBicycleView;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mBicycleView = new BicycleView(this);

        setContentView(mBicycleView);

    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {

        if (mBicycleView == null) {

            return false;

        }

        mBicycleView.onKeyUp(keyCode, event);

        return true;

    }

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (mBicycleView == null) {

            return false;

        }

        if (keyCode == KeyEvent.KEYCODE_BACK) {

            this.finish();

            return true;

        }

        return super.onKeyDown(keyCode, event);

    }

    public class BicycleView extends View {

        // 定义一个Alpha动画

        private Animation mAnimationAlpha = null;

        // 定义一个Scale动画

        private Animation mAnimationScale = null;

        // 定义一个Translate动画

        private Animation mAnimationTranslate = null;

        // 定义一个Rotate动画

        private Animation mAnimationRotate = null;

        // 定义一个AnimationSet对象,该对象可以同时完成几种动画效果

        private AnimationSet as= null;

        // 定义Bitmap对象

        Bitmap mBicycle = null;

 

        public BicycleView(Context context) {

            super(context);

            // 加载图片

            mBicycle = ((BitmapDrawable) getResources().getDrawable(

                    R.drawable.bicycle)).getBitmap();

            // 创建Alpha动画

            mAnimationAlpha = new AlphaAnimation(0.1f, 1.0f);

            // 设置动画持续的时间

            mAnimationAlpha.setDuration(1000*4);

            // 创建Scale动画

            mAnimationScale = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f,

                    Animation.RELATIVE_TO_SELF, 0.7f,

                    Animation.RELATIVE_TO_SELF, 0.7f);

            // 设置动画持续的时间

            mAnimationScale.setDuration(1000*6);

            // 创建Translate动画

            mAnimationTranslate = new TranslateAnimation(5, 200, 4, 150);

            // 设置动画持续的时间

            mAnimationTranslate.setDuration(1000*6);

            // 创建Rotate动画

            mAnimationRotate = new RotateAnimation(0.0f, +360.0f,

                    Animation.RELATIVE_TO_SELF, 0.3f,

                    Animation.RELATIVE_TO_SELF, 0.3f);

            // 设置动画持续的时间

            mAnimationRotate.setDuration(1000*4);

            // 创建一个AnimationSet对象,该对象可以同时完成几种动画效果

            as = new AnimationSet(true);

            as.addAnimation(mAnimationAlpha);

            as.addAnimation(mAnimationRotate);

            as.addAnimation(mAnimationScale);

            as.addAnimation(mAnimationTranslate);

            // 设置动画持续的时间

            as.setDuration(1000*4);

        }

 

        public void onDraw(Canvas canvas) {

            super.onDraw(canvas);

            // 绘制图片

            canvas.drawBitmap(mBicycle, 0, 0, null);

        }

        public boolean onKeyUp(int keyCode, KeyEvent event) {

            switch (keyCode) {

            case KeyEvent.KEYCODE_DPAD_UP:

                // 开始播放动画

                this.startAnimation(mAnimationScale);

                break;

            case KeyEvent.KEYCODE_DPAD_DOWN:

                // 开始播放动画

                this.startAnimation(mAnimationTranslate);

                break;

            case KeyEvent.KEYCODE_DPAD_LEFT:

                // 开始播放动画

                this.startAnimation(mAnimationAlpha);

                break;

            case KeyEvent.KEYCODE_DPAD_RIGHT:

                // 开始播放动画

                this.startAnimation(mAnimationRotate);

                break;

            case KeyEvent.KEYCODE_DPAD_CENTER:

                this.startAnimation(as);

                break;

            }

            return true;

        }

    }

}

2.通过XML定义Tween指令完成动画

(1)alpha_animation.xml。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android" >

<alpha

android:fromAlpha="0.1"

android:toAlpha="1.0"

android:duration="4000"

/>

</set>

(2)rotate_animation.xml。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

       

<rotate        

        android:fromDegrees="0"

        android:toDegrees="+360"

        android:pivotX="30%"

        android:pivotY="30%"    

        android:duration="4000" />

</set>

 

(3)scale_animation.xml。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

    <scale         

        android:fromXScale="0.0"

        android:toXScale="1.0"

        android:fromYScale="0.0"

        android:toYScale="1.0"

        android:pivotX="70%"

        android:pivotY="70%"

        android:fillAfter="false"

        android:duration="6000" />

</set>

 

(4)translate_animation.xml。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate

android:fromXDelta="5"

android:toXDelta="200"

android:fromYDelta="4"

android:toYDelta="150"

android:duration="6000"

/>

</set>

 

(5)com.xml。

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

    <alpha

        android:fromAlpha="0.1"

        android:toAlpha="1.0"

        android:duration="4000"/>

    <rotate

        android:fromDegrees="0"

        android:toDegrees="+360"

        android:pivotX="30%"

        android:pivotY="30%"    

        android:duration="4000"/>

 

    <scale

        android:fromXScale="0.0"

        android:toXScale="1.0"

        android:fromYScale="0.0"

        android:toYScale="1.0"

        android:pivotX="70%"

        android:pivotY="70%"

        android:fillAfter="false"

        android:duration="6000" />

    <translate

        android:fromXDelta="5"

        android:toXDelta="200"

        android:fromYDelta="4"

        android:toYDelta="150"

        android:duration="6000"/>

</set>

编写TweenByXmlActivity.java类:

package com.sharpandroid.tweenbyxml;

 

import android.app.Activity;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.view.animation.Animation;

import android.view.animation.AnimationSet;

import android.view.animation.AnimationUtils;

 

public class TweenByXmlActivity extends Activity {

    private View mBicycleView;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mBicycleView = new BicycleView(this);

        setContentView(mBicycleView);

    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {

        if (mBicycleView == null) {

            return false;

        }

        mBicycleView.onKeyUp(keyCode, event);

        return true;

   

    }

   

    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (mBicycleView == null) {

            return false;

        }

        if (keyCode == KeyEvent.KEYCODE_BACK) {

            this.finish();

            return true;

        }

        return super.onKeyDown(keyCode, event);

    }

    public class BicycleView extends View {

        // 定义一个Alpha动画

        private Animation mAnimationAlpha = null;

        // 定义一个Scale动画

        private Animation mAnimationScale = null;

        // 定义一个Translate动画

        private Animation mAnimationTranslate = null;

        // 定义一个Rotate动画

        private Animation mAnimationRotate = null;

        // 定义一个AnimationSet对象,该对象可以同时完成几种动画效果

        private AnimationSet as= null;

        // 定义Bitmap对象

        Bitmap mBicycle = null;

 

        public BicycleView(Context context) {

            super(context);

            // 加载图片

            mBicycle = ((BitmapDrawable) getResources().getDrawable(

                    R.drawable.bicycle)).getBitmap();

            // 加载Alpha动画

            mAnimationAlpha =   AnimationUtils.loadAnimation

(TweenByXmlActivity.this,R.anim.alpha_animation);

            // 设置动画持续的时间

            mAnimationAlpha.setDuration(1000*4);

            // 加载Scale动画

            mAnimationScale = AnimationUtils.loadAnimation

(TweenByXmlActivity.this,R.anim.scale_animation);

            // 设置动画持续的时间

            mAnimationScale.setDuration(1000*6);

            // 加载Translate动画

            mAnimationTranslate = AnimationUtils.loadAnimation

(TweenByXmlActivity.this,R.anim.translate_animation);

            // 设置动画持续的时间

            mAnimationTranslate.setDuration(1000*6);

            // 加载Rotate动画

            mAnimationRotate = AnimationUtils.loadAnimation

(TweenByXmlActivity.this,R.anim.rotate_animation);

            // 设置动画持续的时间

            mAnimationRotate.setDuration(1000*4);

            // 加载一个AnimationSet对象,该对象可以同时完成几种动画效果

            as = (AnimationSet) AnimationUtils.loadAnimation

(TweenByXmlActivity.this,R.anim.com);

        }

 

        public void onDraw(Canvas canvas) {

            super.onDraw(canvas);

            // 绘制图片

            canvas.drawBitmap(mBicycle, 0, 0, null);

        }

        public boolean onKeyUp(int keyCode, KeyEvent event) {

            switch (keyCode) {

            case KeyEvent.KEYCODE_DPAD_UP:

                // 开始播放动画

                this.startAnimation(mAnimationScale);

                break;

            case KeyEvent.KEYCODE_DPAD_DOWN:

                // 开始播放动画

                this.startAnimation(mAnimationTranslate);

                break;

            case KeyEvent.KEYCODE_DPAD_LEFT:

                // 开始播放动画

                this.startAnimation(mAnimationAlpha);

                break;

            case KeyEvent.KEYCODE_DPAD_RIGHT:

                // 开始播放动画

                this.startAnimation(mAnimationRotate);

                break;

            case KeyEvent.KEYCODE_DPAD_CENTER:

                this.startAnimation(as);

                break;

            }

            return true;

        }

    }

}

 

42.6  动画特效之Frame动画

1.通过Java代码实现Frame动画

编写FrameActivity.java类:

package com.sharpandroid.frame;

 

import android.app.Activity;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

 

public class FrameActivity extends Activity {

    private FrameView birdView;

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        birdView = new FrameView(this);

        setContentView(birdView);

    }

   

    public boolean onKeyUp(int keyCode, KeyEvent event)

    {

        if ( birdView == null )

        {

            return false;

        }

        birdView.onKeyUp(keyCode,event);

        return true;

    }

    public boolean onKeyDown(int keyCode, KeyEvent event)

    {

        if ( birdView == null )

        {

            return false;

        }

        if ( keyCode ==  KeyEvent.KEYCODE_BACK)

        {

            this.finish();

            return true;

        }

        return super.onKeyDown(keyCode, event);

    }

    public class FrameView extends View

    {

        // 定义AnimationDrawable动画

        private AnimationDrawable frameAnimation = null;

        Context mContext = null;

       

        // 定义一个Drawable对象

        Drawable birdItem = null;

        public FrameView(Context context)

        {

            super(context);

            mContext = context;

            //实例化AnimationDrawable对象

            frameAnimation = new AnimationDrawable();

            //装载资源

            //这里用一个循环了装载所有名字类似的资源

            //如"bird1…5.png"的图片,5张图片鸟的翅膀从上到下

            //之后再从bird4…1.png倒序,翅膀从下往上

            //共循环9次,完成翅膀"上-下-上"的整个循环

            for (int i = 1; i <= 9; i++)

            {  

                int j=0;

                //这样完成从4-1倒序一遍

                if(i <= 5)

                {

                    j = i;

                }else{

                    j = 10 - i;

                }

               

                //根据给定的资源名称返回一个资源标识符,即其在R文件中对应的常量的值

                //第一个参数表示给定的资源的名称

                //第二个参数表示需要获取的资源类型,本例为"drawable"型

                //第三个参数表示应用包的路径

                int id = getResources().getIdentifier("bird" + j,

"drawable", mContext.getPackageName());

                birdItem = getResources().getDrawable(id);

                //为动画添加一帧

                //参数birdItem是该帧的图片内容

                //参数300/j是该帧所显示的毫秒数,由于j是一个先增大后边小的过程

                //因此,每幅图片显示的时间会先减小后增大

                //也即切换图片的速度先增大后减小

                frameAnimation.addFrame(birdItem, 300/j);

            }

           

            // 设置播放模式是否只播放一次,false表示重复播放,而true表示只播放一次

            frameAnimation.setOneShot(false); 

 

            //设置将要显示的动画

            this.setBackgroundDrawable(frameAnimation);

        }

       

        public void onDraw(Canvas canvas)

        {

            super.onDraw(canvas);

        }

       

        public boolean onKeyUp(int keyCode, KeyEvent event)

        {

            switch ( keyCode )

            {

            case KeyEvent.KEYCODE_DPAD_UP:     

                // 开始播放动画

                frameAnimation.start();

                break;

            case KeyEvent.KEYCODE_DPAD_DOWN:

                //停止播放动画

                frameAnimation.stop();

                break;

            }

            return true;

        }

    }

}

2.通过XML定义Frame完成动画

编写fram.xml文件:

<?xml version="1.0" encoding="utf-8"?>

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"

    android:oneshot="false">

    <item android:drawable="@drawable/bird1" android:duration="300" />

    <item android:drawable="@drawable/bird2" android:duration="150" />

    <item android:drawable="@drawable/bird3" android:duration="100" />

    <item android:drawable="@drawable/bird4" android:duration="75" />

    <item android:drawable="@drawable/bird5" android:duration="60" />

    <item android:drawable="@drawable/bird4" android:duration="75" />

    <item android:drawable="@drawable/bird3" android:duration="100" />

    <item android:drawable="@drawable/bird2" android:duration="150" />

    <item android:drawable="@drawable/bird1" android:duration="300" />

</animation-list>

 

编写FrameByXMLActivity.java:

package com.sharpandroid.framebyxml;

 

import android.app.Activity;

import android.content.Context;

import android.graphics.Canvas;

import android.graphics.drawable.AnimationDrawable;

import android.graphics.drawable.Drawable;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.widget.ImageView;

 

public class FrameByXMLActivity extends Activity {

    private FrameView birdView;

    @Override

    public void onCreate(Bundle savedInstanceState)

    {

        super.onCreate(savedInstanceState);

        birdView = new FrameView(this);

        setContentView(birdView);

    }

   

    public boolean onKeyUp(int keyCode, KeyEvent event)

    {

        if ( birdView == null )

        {

            return false;

        }

        birdView.onKeyUp(keyCode,event);

        return true;

    }

    public boolean onKeyDown(int keyCode, KeyEvent event)

    {

        if ( birdView == null )

        {

            return false;

        }

        if ( keyCode ==  KeyEvent.KEYCODE_BACK)

        {

            this.finish();

            return true;

        }

        return super.onKeyDown(keyCode, event);

    }

    public class FrameView extends View

    {

        // 定义AnimationDrawable逐帧动画

        private AnimationDrawable frameAnimation = null;

        Context mContext = null;

        public FrameView(Context context)

        {

            super(context);

            mContext = context;

            //定义一个ImageView用来存放动画

            ImageView img = new ImageView(mContext);

            //将定义的frame.xml文件传入img作为其背景

            img.setBackgroundResource(R.anim.frame);

            //通过ImageView的getBackground方法获取到Frame动画

            frameAnimation = (AnimationDrawable) img.getBackground();

            //将该动画指定为屏幕的背景

            this.setBackgroundDrawable(frameAnimation);

        }

       

        public void onDraw(Canvas canvas)

        {

            super.onDraw(canvas);

        }

       

        public boolean onKeyUp(int keyCode, KeyEvent event)

        {

            switch ( keyCode )

            {

            case KeyEvent.KEYCODE_DPAD_UP:     

                // 开始播放动画

                frameAnimation.start();

                break;

            case KeyEvent.KEYCODE_DPAD_DOWN:

                //停止播放动画

                frameAnimation.stop();

                break;

            }

            return true;

        }

    }

}

43  OpenGL/OpenGL ES开发 

43.3  Android对OpenGL ES的支持

 

43.3.3  代码详解

在Android中专门提供了GLSurfaceView类,用来显示3D视图,在GLSurfaceView中有一个Renderer接口,GLSurfaceView.Renderer是一个通用的接口。使用setContentView()方法直接载入GLSurfaceView类的实例,而不用载入main.xml,代码如下:

OpenglActivity.java

package com.sharpandroid.opengl;

import android.app.Activity;

import android.content.res.Resources;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.opengl.GLSurfaceView;

import android.os.Bundle;

public class OpenglActivity extends Activity {

    /** Called when the activity is first created. */

    MyRnderer render=new MyRnderer();

        @Override

        public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        GLSurfaceView glView = new GLSurfaceView(this);

        glView.setRenderer(render);

        setContentView(glView);

        }

}

43.3.5  颜色测试

MyRnderer的整体代码如下:

MyRnderer.java

public class MyRnderer implements Renderer {

    int one=0x10000;

    private IntBuffer pointers =IntBuffer.wrap(new int[]{  //顶点

            one,one,0, //顶点A

            -one,one,0, //顶点B

            one,-one,0, //顶点D

            -one,-one,0});      //顶点C

     private IntBuffer colors = IntBuffer.wrap(new int[]{//颜色

             one,0,0,one,

             0,one,0,one,

             0,0,one,one,

             0,one,one,0

     });

    public void onDrawFrame(GL10 gl) {

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        gl.glLoadIdentity();

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

        gl.glTranslatef(1.5f, 0.0f, -6.0f);

        gl.glColorPointer(4, GL10.GL_FIXED, 0, colors);//定义颜色

        gl.glVertexPointer(3, GL10.GL_FIXED, 0, pointers);

        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);//取消定义颜色

        // 取消顶点设置

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    }

    @Override

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

        float ratio = (float) width / height;

        //设置OpenGL场景的大小

        gl.glViewport(0, 0, width, height);

        //设置投影矩阵

        gl.glMatrixMode(GL10.GL_PROJECTION);

        //重置投影矩阵

        gl.glLoadIdentity();

        // 设置视口的大小

        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

        // 选择模型观察矩阵

        gl.glMatrixMode(GL10.GL_MODELVIEW);

        // 重置模型观察矩阵

        gl.glLoadIdentity();

    }

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

        gl.glShadeModel(GL10.GL_SMOOTH);    //设置阴影模式

        gl.glClearColor(0, 0, 1, 0);        // 蓝色背景

        gl.glClearDepthf(1.0f);             // 设置深度缓存

        gl.glEnable(GL10.GL_DEPTH_TEST);    // 开启深度测试  

        gl.glDepthFunc(GL10.GL_LEQUAL);     // 深度测试的类型

        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

                                            //对透视进行修正

    }

}

43.3.7  正方体测试

在SquareRenderer中加入构建的八个顶点的坐标,代码如下:

int one = 0x10000;

IntBuffer pointers = IntBuffer.wrap(new int[]{

        one,one,-one,

        -one,one,-one,

        one,one,one,

        -one,one,one,

       

        one,-one,one,

        -one,-one,one,

        one,-one,-one,

        -one,-one,-one,

       

        one,one,one,

        -one,one,one,

        one,-one,one,

        -one,-one,one,

       

        one,-one,-one,

        -one,-one,-one,

        one,one,-one,

        -one,one,-one,

       

        -one,one,one,

        -one,one,-one,

        -one,-one,one,

        -one,-one,-one,

       

        one, one, -one,

        one, one, one,

        one, -one, -one,

        one, -one, one,

});

设置3D环境和正方形的一样,但是在绘制正方体的时候有所不同,正方体有六个面组成,要分别绘制出六个正方形,组成之后就是所要的正方体。代码如下:

package com.sharpandroid.opengl;

import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLSurfaceView.Renderer;

public class SquareRenderer implements Renderer {

    float rotateTri, rotateQuad;

    int texture = -1;

    int one = 0x10000;

    IntBuffer pointers = IntBuffer.wrap(new int[]{

            one,one,-one,

            -one,one,-one,

            one,one,one,

            -one,one,one,

           

            one,-one,one,

            -one,-one,one,

            one,-one,-one,

            -one,-one,-one,

           

            one,one,one,

            -one,one,one,

            one,-one,one,

            -one,-one,one,

           

            one,-one,-one,

            -one,-one,-one,

            one,one,-one,

            -one,one,-one,

           

            -one,one,one,

            -one,one,-one,

            -one,-one,one,

            -one,-one,-one,

           

            one, one, -one,

            one, one, one,

            one, -one, -one,

            one, -one, one,

    });

 

    public void onDrawFrame(GL10 gl)

    {

        // 清除屏幕

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // 重置     

gl.glLoadIdentity();

        gl.glTranslatef(0.0f, 0.0f, -5.0f);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        //设置旋转

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

        //设置和绘制正方形

        gl.glVertexPointer(3, GL10.GL_FIXED, 0, pointers);

        for(int i=0; i<6; i++)

        {

        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i*4, 4);

        }

        //绘制正方形结束

        gl.glFinish();

        //取消顶点数组

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        rotateQuad += 0.5f;

        //改变旋转的角度

    }

 

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height)

    {

        // TODO Auto-generated method stub

        float ratio = (float) width / height;

        //设置OpenGL场景的大小

        gl.glViewport(0, 0, width, height);

        //设置投影矩阵

        gl.glMatrixMode(GL10.GL_PROJECTION);

        //重置投影矩阵

        gl.glLoadIdentity();

        // 设置视口的大小

        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

        // 选择模型观察矩阵

        gl.glMatrixMode(GL10.GL_MODELVIEW);

        // 重置模型观察矩阵

        gl.glLoadIdentity();   

    }

 

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config)

    {

        // 启用阴影平滑

        gl.glShadeModel(GL10.GL_SMOOTH);

        // 蓝色背景

        gl.glClearColor(0, 0, 1, 0);

        gl.glClearDepthf(1.0f);                        

        gl.glEnable(GL10.GL_DEPTH_TEST);                       

        gl.glDepthFunc(GL10.GL_LEQUAL);                        

        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

    }

}

43.3.8  纹理映射测试

TestTexture的代码如下:

import java.nio.ByteBuffer;

import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLUtils;

import android.opengl.GLSurfaceView.Renderer;

 

public class TestTexture implements Renderer {

    float x, y, z;

    int texture = -1;

    int one = 0x10000;

    IntBuffer pointers = IntBuffer.wrap(new int[]{

            -one,-one,one,

            one,-one,one,

            one,one,one,

            -one,one,one,

           

            -one,-one,-one,

            -one,one,-one,

            one,one,-one,

            one,-one,-one,

           

            -one,one,-one,

            -one,one,one,

            one,one,one,

            one,one,-one,

           

            -one,-one,-one,

            one,-one,-one,

            one,-one,one,

            -one,-one,one,

           

            one,-one,-one,

            one,one,-one,

            one,one,one,

            one,-one,one,

           

            -one,-one,-one,

            -one,-one,one,

            -one,one,one,

            -one,one,-one,

           

    });

    IntBuffer texCoords = IntBuffer.wrap(new int[]{

        one,0,0,0,0,one,one,one,   

        0,0,0,one,one,one,one,0,

        one,one,one,0,0,0,0,one,

        0,one,one,one,one,0,0,0,

        0,0,0,one,one,one,one,0,

        one,0,0,0,0,one,one,one,

    });

   

    ByteBuffer indices = ByteBuffer.wrap(new byte[]{

            0,1,3,2,

            4,5,7,6,

            8,9,11,10,

            12,13,15,14,

            16,17,19,18,

            20,21,23,22,

    });

    @Override

    public void onDrawFrame(GL10 gl)

    {

        // 清除屏幕和深度缓存

        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

        // 重置当前的模型观察矩阵

        gl.glLoadIdentity();

       

        gl.glTranslatef(0.0f, 0.0f, -5.0f);

       

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

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

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

 

        // 绑定纹理

        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

       

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

       

        //纹理和四边形对应的顶点

        gl.glVertexPointer(3, GL10.GL_FIXED, 0, pointers);

        gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);

 

        //绘制

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_UNSIGNED_

BYTE, indices);

       

        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

       

        x-=0.5f;

        y-=0.5f;

        z-=0.5f;

       

    }

 

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height)

    {

        float ratio = (float) width / height;

        gl.glViewport(0, 0, width, height);

        gl.glMatrixMode(GL10.GL_PROJECTION);

        gl.glLoadIdentity();

        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

        gl.glMatrixMode(GL10.GL_MODELVIEW);

        gl.glLoadIdentity();   

    }

 

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config)

    {

        // 蓝色背景

        gl.glClearColor(0, 0, 1, 0);

        gl.glEnable(GL10.GL_CULL_FACE);

        gl.glShadeModel(GL10.GL_SMOOTH);

        gl.glEnable(GL10.GL_DEPTH_TEST);

        //启用纹理映射

        gl.glClearDepthf(1.0f);

        gl.glDepthFunc(GL10.GL_LEQUAL);

        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

        //允许2D贴图,纹理

        gl.glEnable(GL10.GL_TEXTURE_2D);

       

        IntBuffer intBuffer = IntBuffer.allocate(1);

        // 创建纹理

        gl.glGenTextures(1, intBuffer);

        texture = intBuffer.get();

        // 设置要使用的纹理

        gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

       

        //生成纹理

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.bitmap, 0);

       

        // 线形滤波

        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_

FILTER, GL10.GL_LINEAR);

        gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_

FILTER, GL10.GL_LINEAR);

       

    }

 

}

43.3.9  光照测试

TestLight代码如下:

import java.nio.ByteBuffer;

import java.nio.FloatBuffer;

import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;

import javax.microedition.khronos.opengles.GL10;

 

import android.opengl.GLUtils;

import android.opengl.GLSurfaceView.Renderer;

 

    public class TestLight implements Renderer {

        float x, y, z;

        int texture = -1;

        int one = 0x10000;

        //环境光

        FloatBuffer light1 = FloatBuffer.wrap(new float[]{0.5f,0.5f,0.5f,

1.0f});

        //漫射光

        FloatBuffer light2 = FloatBuffer.wrap(new float[]{1.0f,1.0f,1.0f,

1.0f});

        //光源位置

        FloatBuffer lightPosition = FloatBuffer.wrap(new float[]{0.0f,

0.0f,2.0f,1.0f});

       

        IntBuffer pointers = IntBuffer.wrap(new int[]{

                -one,-one,one,

                one,-one,one,

                one,one,one,

                -one,one,one,

               

                -one,-one,-one,

                -one,one,-one,

                one,one,-one,

                one,-one,-one,

               

                -one,one,-one,

                -one,one,one,

                one,one,one,

                one,one,-one,

               

                -one,-one,-one,

                one,-one,-one,

                one,-one,one,

                -one,-one,one,

               

                one,-one,-one,

                one,one,-one,

                one,one,one,

                one,-one,one,

               

                -one,-one,-one,

                -one,-one,one,

                -one,one,one,

                -one,one,-one,

        });

        IntBuffer texCoords = IntBuffer.wrap(new int[]{

            one,0,0,0,0,one,one,one,   

            0,0,0,one,one,one,one,0,

            one,one,one,0,0,0,0,one,

            0,one,one,one,one,0,0,0,

            0,0,0,one,one,one,one,0,

            one,0,0,0,0,one,one,one,

        });

        ByteBuffer indices = ByteBuffer.wrap(new byte[]{

                0,1,3,2,

                4,5,7,6,

                8,9,11,10,

                12,13,15,14,

                16,17,19,18,

                20,21,23,22,

        });

        @Override

        public void onDrawFrame(GL10 gl)

        {

            gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_

BIT);

            gl.glLoadIdentity();

            gl.glTranslatef(0.0f, 0.0f, -5.0f);

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

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

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

            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            gl.glVertexPointer(3, GL10.GL_FIXED, 0, pointers);

            gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);

            gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_

UNSIGNED_BYTE, indices);

           

            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

                x+=0.5f;

                y+=0.5f;

                gl.glEnable(GL10.GL_LIGHT1);        // 启用一号光源

        }

        @Override

        public void onSurfaceChanged(GL10 gl, int width, int height)

        {

            float ratio = (float) width / height;

            gl.glViewport(0, 0, width, height);

            gl.glMatrixMode(GL10.GL_PROJECTION);

            gl.glLoadIdentity();

            gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

            gl.glMatrixMode(GL10.GL_MODELVIEW);

            gl.glLoadIdentity();   

        }

 

        @Override

        public void onSurfaceCreated(GL10 gl, EGLConfig config)

        {

            gl.glClearColor(0, 0, 1, 0);

            gl.glEnable(GL10.GL_CULL_FACE);

            gl.glShadeModel(GL10.GL_SMOOTH);

            gl.glEnable(GL10.GL_DEPTH_TEST);

            gl.glClearDepthf(1.0f);

            gl.glDepthFunc(GL10.GL_LEQUAL);

            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_

NICEST);

            gl.glEnable(GL10.GL_TEXTURE_2D);

            IntBuffer intBuffer = IntBuffer.allocate(1);

            gl.glGenTextures(1, intBuffer);

            texture = intBuffer.get();

            gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.bitmap, 0);

            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_

MIN_FILTER, GL10.GL_LINEAR);

            gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_

MAG_FILTER, GL10.GL_LINEAR);

            //设置环境光

            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, light1);

            //设置漫射光

            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, light2);

            //设置光源的位置

            gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, lightPosition);

            //启用一号光源

            gl.glEnable(GL10.GL_LIGHT1);

        }

    }

 

你可能感兴趣的:(android)