Android界面特效全汇总

(一)Activity 页面切换的效果  

Android 2.0 之后有了 overridePendingTransition() ,其中里面两个参

数,一个是前一个 activity 的退出两一个 activity 的进入,

Java 代码   

1.  @Override       

public  void  onCreate(Bundle  savedInstanceState)  {       

2.      super.onCreate(savedInstanceState);         

3.      

4.      setContentView(R.layout.SplashScreen);       

5.         

6.      new  Handler().postDelayed(new  Runnable()  {       

7.      @Override       

8.      public  void  run()  {       

9.      Intent  mainIntent  =  new  Intent(SplashScreen.this,    

        AndroidNews.class);       

10.    SplashScreen.this.startActivity(mainIntent);       

11.    SplashScreen.this.finish();       

12.       

13.    overridePendingTransition(R.anim.mainfadein,       

14.                      R.anim.splashfadeout);       

15.  }       

16.},  3000);       

}      

  

上面的代码只是闪屏的一部分。

Java 代码   

1.  getWindow().setWindowAnimations  (  int  );      这可没有上个好但是也可以  。

 

实现淡入淡出的效果 

Java 代码   

1.  overridePendingTransition(Android.R.anim.fade_in,android.R.anim.fade_out);        

  

由左向右滑入的效果 

Java 代码   

1.  overridePendingTransition(Android.R.anim.slide_in_left,android.R.anim.slide_out_right);        

  

实现 zoomin 和 zoomout,即类似 iphone 的进入和退出时的效果 

Java 代码   

1.  overridePendingTransition(R.anim.zoomin,  R.anim.zoomout);     

  

新建 zoomin.xml 文件 

Xml 代码   

1.      

2. 

3.  xmlns:Android="http://schemas.android.com/apk/res/android"    

4.  Android:interpolator="@android:anim/decelerate_interpolator">

5.  Android:fromYScale="2.0"  android:toYScale="1.0"    

6.  Android:pivotX="50%p"  android:pivotY="50%p"    

7.  Android:duration="@android:integer/config_mediumAnimTime"  />

    

  

新建 zoomout.xml 文件 

Xml 代码   

1.      

2. 

3.  xmlns:Android="http://schemas.android.com/apk/res/android"    

4.  Android:interpolator="@android:anim/decelerate_interpolator"

5.  Android:zAdjustment="top">    

6. 

7.    Android:fromYScale="1.0"  android:toYScale=".5"    

8.    Android:pivotX="50%p"  android:pivotY="50%p"    

9.    Android:duration="@android:integer/config_mediumAnimTime"  />

    

10.

11.Android:duration="@android:integer/config_mediumAnimTime"/>    

12.     

 

(二)android 菜单动画

先请注意,这里的菜单并不是按机器上的 MENU 出现在那种菜单,而是基于

Android SDK 提供的 android.view.animation.TranslateAnimation(extends

android.view.animation.Animation)类实例后附加到一个 Layout 上使之产生的

有动画出现和隐藏效果的菜单。

               原理:Layout(菜单)从屏幕内(挨着屏

幕边沿,其实并非一定,视需要的初态和末态而定)动态

的移动到屏幕外(在外面可以挨着边沿,也可以离远点,

这个无所谓了),这样就可以达到动态菜单的效果了。但

是由于 Animation 的一些奇怪特性(setFill**() 函数的作用效果,这个在我使

用的某几个 Animation 当中出现了没有想明白的效果),就暂不理会这个东西了,

所以使得我们还需要用上 XML 属性 android:visibility。当 Layout(菜单)显

示的时候,设置 android:visibility="visible",当 Layout(菜单)隐藏的时

候,设置 android:visibility="gone",这里 android:visibility 可以有 3 个

值,"visible"为可见,"invisible"为不可见但占空间,"gone"为不可见且不占

空间(所谓的占不占空间,这个可以自己写个 XML 来试试就明白了)。

               Class TranslateAnimation 的使用:Animation 有两种定义方

法,一种是用 Java code,一种是用 XML,这里只介绍用 code 来定义(因为用

XML 来定义的那种我没用过。。嘿嘿。。)。多的不说,看代码。

这里是 TranslateAnimationMenu.java(我在里面还另加入了 ScaleAnimation

产生的动画,各位朋友可以照着 SDK 以及程序效果来理解):

package com.TranslateAnimation.Menu;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.view.animation.Animation;

import android.view.animation.TranslateAnimation;

import android.widget.Button;

import android.widget.LinearLayout;

public class TranslateAnimationMenu extends Activity {

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

       //TranslateAnimation showAction, hideAction;

       Animation showAction, hideAction;

       LinearLayout menu;

       Button button;

       boolean menuShowed;

       

       @Override

       public void onCreate(Bundle savedInstanceState) 

{

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        menu = (LinearLayout) findViewById(R.id.menu);

        button = (Button) findViewById(R.id.button);

        // 这里是 TranslateAnimation 动画

        showAction = new TranslateAnimation(

Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF,

0.0f,  Animation.RELATIVE_TO_SELF, -1.0f,

Animation.RELATIVE_TO_SELF, 0.0f);

// 这里是 ScaleAnimation 动画 

//showAction = new ScaleAnimation(

//       1.0f, 1.0f, 0.0f, 1.0f, Animation.RELATIVE_TO_SELF, 0.0f,

//       Animation.RELATIVE_TO_SELF, 0.0f);

showAction.setDuration(500);

 

// 这里是 TranslateAnimation 动画                

hideAction = new TranslateAnimation(

   Animation.RELATIVE_TO_SELF, 0.0f, 

Animation.RELATIVE_TO_SELF, 0.0f,

Animation.RELATIVE_TO_SELF, 0.0f,

Animation.RELATIVE_TO_SELF, -1.0f);

// 这里是 ScaleAnimation 动画

//hideAction = new ScaleAnimation(

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

Animation.RELATIVE_TO_SELF, 0.0f, Animation.RELATIVE_TO_SELF,

0.0f);

 hideAction.setDuration(500);

menuShowed = false;

menu.setVisibility(View.GONE);

button.setOnClickListener(new OnClickListener() {

      @Override

      public void onClick(View v) {

      // TODO Auto-generated method stub

         if (menuShowed) {

             menuShowed = false;

             menu.startAnimation(hideAction);

             menu.setVisibility(View.GONE);

        }

        else {

            menuShowed = true;

            menu.startAnimation(showAction);

            menu.setVisibility(View.VISIBLE);

       }

     }

                       

   });

  }

}

这里是 main.xml:

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

android:orientation="vertical" android:layout_width="fill_parent"

android:layout_height="fill_parent">

     android:layout_height="wrap_content"

android:text="@string/hello" />

     android:layout_height="100px" android:layout_width="fill_parent"

     android:layout_alignParentTop="true"

android:background="#ffffff">

    

       android:layout_height="fill_parent" android:text="I am a menu"

       android:gravity="center" />

  

16.            

19.            

22.        

23.    

24.    

  

BrowserInfo 用于提供一个项的信息

  

Java 代码       

1.   public class BrowserInfo {    

2.     

3.       private int appInfoId;    

4.       private int imageId;    

5.       private boolean checked;    

6.     

7.       public BrowserInfo(int appInfoId, int imageId, boolean checked) {    

8.           this.appInfoId = appInfoId;    

9.           this.imageId = imageId;    

10.          this.checked = checked;    

11.      }    

12.    

13.      public boolean isChecked() {    

14.          return checked;    

15.      }    

16.    

17.      public void setChecked(boolean checked) {    

18.          this.checked = checked;    

19.      }    

20.    

21.      public int getAppInfoId() {    

22.          return appInfoId;    

23.      }    

24.    

25.      public void setAppInfoId(int appInfoId) {    

26.          this.appInfoId = appInfoId;    

27.      }    

28.    

29.      public int getImageId() {    

30.          return imageId;    

31.      }    

32.    

33.      public void setImageId(int imageId) {    

34.          this.imageId = imageId;    

35.      }    

36.    

37.  }  

  

GroupInfo  用于显示一个组的信息

  

Java 代码       

1.   import java.util.List;    

2.     

3.   public class GroupInfo {    

4.     

5.       private BrowserInfo group;    

6.       private List child;    

7.     

8.       public GroupInfo(BrowserInfo group, List child) {    

9.     

10.          this.group = group;    

11.          this.child = child;    

12.      }    

13.          

14.      public void add(BrowserInfo info){    

15.          child.add(info);    

16.      }    

17.          

18.      public void remove(BrowserInfo info){    

19.          child.remove(info);    

20.      }    

21.          

22.      public void remove(int index){    

23.          child.remove(index);    

24.      }    

25.          

26.      public int getChildSize(){    

27.          return child.size();    

28.      }    

29.          

30.      public BrowserInfo getChild(int index){    

31.          return child.get(index);    

32.      }    

33.    

34.      public BrowserInfo getBrowserInfo() {    

35.          return group;    

36.      }    

37.    

38.      public void setBrowserInfo(BrowserInfo group) {    

39.          this.group = group;    

40.      }    

41.    

42.      public List getChild() {    

43.          return child;    

44.      }    

45.    

46.      public void setChild(List child) {    

47.          this.child = child;    

48.      }    

49.    

50.  }  

  

  

ClearBrowserActivity 最后就是把要显示的内容显示出来的。

  

  

Java 代码       

1.   public class ClearBrowserActivity extends Activity implements ExpandableListView.OnGr

oupClickListener,ExpandableListView.OnChildClickListener{    

2.     

3.       private List group;    

4.     

5.       private ClearExpandableListAdapter listAdapter = null;    

6.       private ExpandableListView appList;    

7.     

8.       public void onCreate(Bundle savedInstanceState) {    

9.           super.onCreate(savedInstanceState);    

10.          setContentView(R.layout.browserlayout);    

11.          appList = (ExpandableListView) findViewById(R.id.appList);    

12.          init();    

13.          BrowserInfo browsingHistoryParents = newBrowserInfo(    

14.                  R.string.browsinghistory, R.drawable.browser_image,true);    

15.          List browsingHistoryChild = new ArrayList();    

16.          BrowserInfo browser = newBrowserInfo(R.string.browser,    

17.                  R.drawable.browser_image, true);    

18.          browsingHistoryChild.add(browser);    

19.    

20.          BrowserInfo operaClear = newBrowserInfo(R.string.opera_clear,    

21.                  R.drawable.browser_image,true);    

22.          browsingHistoryChild.add(operaClear);    

23.              

24.          BrowserInfo firefoxClear = newBrowserInfo(R.string.firefox_clear,    

25.                  R.drawable.browser_image,true);    

26.          browsingHistoryChild.add(firefoxClear);    

27.              

28.          BrowserInfo ucwebClear = newBrowserInfo(R.string.ucweb_clear,    

29.                  R.drawable.browser_image,false);    

30.          browsingHistoryChild.add(ucwebClear);    

31.              

32.          GroupInfo browserGroup = new GroupInfo(browsingHistoryParents,    

33.                  browsingHistoryChild);    

34.          addGroup(browserGroup);    

35.    

36.          listAdapter = new ClearExpandableListAdapter(this, group);    

37.          appList.setOnChildClickListener(this);    

38.          appList.setOnGroupClickListener(this);    

39.          appList.setAdapter(listAdapter);    

40.      }    

41.    

42.      private void init() {    

43.          group = new ArrayList();    

44.      }    

45.    

46.      private void addGroup(GroupInfo info) {    

47.          group.add(info);    

48.      }    

49.    

50.      private static BrowserInfo newBrowserInfo(int infoId, int imageId,boolean checked) {    

51.          return new BrowserInfo(infoId, imageId,checked);    

52.      }    

53.    

54.      @Override  

55.      public boolean onGroupClick(ExpandableListView parent, View v,    

56.              int groupPosition, long id) {    

57.          return false;    

58.      }    

59.    

60.      @Override  

61.      public boolean onChildClick(ExpandableListView parent, View v,    

62.              int groupPosition, int childPosition, long id) {    

63.          return false;    

64.      }    

65.  }  

android 3d 旋转

文章分类:Java 编程  

   在javaeye里看到了关于3d旋转的文章,可是博主没有透入什么技术细节。

由于一直想做出那种旋转效果,所以就想啊想,终于想出来了(  我是个小菜

鸟)。呵呵,不管怎样,希望对想做还没做出来的朋友一些帮助。

   先上一个效果图:

 

 

  

   这是你想要的吗?如果是就继续往下看吧。

   其实,这个效果是用 animation 配合 camera 做出来的,相信大家在 apidemo

里面看过类似的。

   那么先写一个继承 animation 的类:Rotate3d

  

Rotate3d 代码       

1.   public class Rotate3d extends Animation {    

2.       private float mFromDegree;    

3.       private float mToDegree;    

4.       private float mCenterX;    

5.       private float mCenterY;    

6.       private float mLeft;    

7.       private float mTop;    

8.       private Camera mCamera;    

9.       private static final String TAG = "Rotate3d";    

10.    

11.      public Rotate3d(float fromDegree, float toDegree, float left, float top,    

12.              float centerX, float centerY) {    

13.          this.mFromDegree = fromDegree;    

14.          this.mToDegree = toDegree;    

15.          this.mLeft = left;    

16.          this.mTop = top;    

17.          this.mCenterX = centerX;    

18.          this.mCenterY = centerY;    

19.    

20.      }    

21.    

22.      @Override    

23.      public void initialize(int width, int height, int parentWidth,    

24.              int parentHeight) {    

25.          super.initialize(width, height, parentWidth, parentHeight);    

26.          mCamera = new Camera();    

27.      }    

28.    

29.      @Override    

30.      protected void applyTransformation(float interpolatedTime, Transformation t) {    

31.          final float FromDegree = mFromDegree;    

32.          float degrees = FromDegree + (mToDegree - mFromDegree)    

33.                  * interpolatedTime;    

34.          final float centerX = mCenterX;    

35.          final float centerY = mCenterY;    

36.          final Matrix matrix = t.getMatrix();    

37.    

38.          if (degrees <= -76.0f) {    

39.               degrees = -90.0f;    

40.               mCamera.save();    

41.               mCamera.rotateY(degrees);    

42.               mCamera.getMatrix(matrix);    

43.               mCamera.restore();    

44.          } else if(degrees >=76.0f){    

45.              degrees = 90.0f;    

46.              mCamera.save();    

47.              mCamera.rotateY(degrees);    

48.              mCamera.getMatrix(matrix);    

49.              mCamera.restore();    

50.          }else{    

51.              mCamera.save();    

52.                         //这里很重要哦。    

53.              mCamera.translate(0, 0, centerX);    

54.              mCamera.rotateY(degrees);    

55.              mCamera.translate(0, 0, -centerX);    

56.              mCamera.getMatrix(matrix);    

57.              mCamera.restore();    

58.          }    

59.    

60.          matrix.preTranslate(-centerX, -centerY);    

61.          matrix.postTranslate(centerX, centerY);    

62.      }    

63.  }  

  

  有了这个类一切都会变得简单的,接着只要在 activity 中写两个 Rotate3d

的对象,让两个 view,分别做这两个对象的 animation 就好了。(  原来就这么

简单啊!无语)

  

Activity 代码       

1.   //下面两句很关键哦,呵呵,心照不宣。    

2.           Rotate3d leftAnimation = new Rotate3d(-0, -90, 0, 0, mCenterX, mCenterY);    

3.           Rotate3d rightAnimation = new Rotate3d(-0+90, -90+90, 0.0f, 0.0f, mCenterX, mCent

erY);    

4.     

5.           leftAnimation.setFillAfter(true);    

6.           leftAnimation.setDuration(1000);    

7.           rightAnimation.setFillAfter(true);    

8.           rightAnimation.setDuration(1000);    

9.     

10.          mImageView1.startAnimation(leftAnimation);    

11.          mImageView2.startAnimation(rightAnimation);  

   

  

   

  

还要写一下 mImageView1,mImageView2 的 xml,

  

Xml 代码       

1.     

2.  

3.       android:orientation="vertical"  

4.       android:layout_width="fill_parent"  

5.       android:layout_height="wrap_content"  

6.       >  

7.     

8.      

9.           android:layout_width="fill_parent"  

10.          android:layout_height="fill_parent">  

11.    

12.                    

13.                      android:id="@+id/image1"  

14.                      android:layout_gravity="center_horizontal"  

15.                      android:layout_width="fill_parent"  

16.                      android:layout_height="wrap_content"  

17.                      android:src="@drawable/image1"  

18.                      />  

19.                    

20.                      android:id="@+id/image2"  

21.                      android:background="#ffff0000"  

22.                      android:layout_gravity="center_horizontal"  

23.                      android:layout_width="fill_parent"  

24.                      android:layout_height="wrap_content"  

25.                      android:src="@drawable/image2"  

26.                      />  

27.    

28.        

29.    

  写完收工。如果有不足之处,还请朋友们不吝指教。

  

  

Android File Explorer 展示图片

文章分类:移动开发  

 

 

res/layout/row.xml

  

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

   android:id="@+id/rowtext"

   android:layout_width="fill_parent"

         android:layout_height="25px"

         android:textSize="23sp" />

  

/res/layout/main.xml  

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

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

 android:id="@+id/path"

    android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    />

 android:id="@android:id/list"

 android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

 />

 android:id="@android:id/empty"

 android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    android:text="No Data"

 />

/res/layout/jpgdialog.xml

  

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

              android:id="@+id/layout_root"

              android:orientation="vertical"

              android:layout_width="fill_parent"

              android:layout_height="fill_parent"

              android:paddingLeft="10dip"

              android:paddingRight="10dip"

              >

   

              android:layout_width="wrap_content"

              android:layout_height="wrap_content"

              android:textSize="11sp" />

              />

   

               android:layout_width="150px"

               android:layout_height="150px"

               />

          

12.    

  3.image_show.xml   

       ImageSwitcher 是用来图片显示那块区域的控件   Gallery 是来控制

底下那个图标列表索引用的

Java 代码       

1.       

2.  

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

4.      android:layout_width="fill_parent"  

5.      android:layout_height="fill_parent">    

6.         

7.    

8.        android:layout_height="fill_parent"  

9.       android:layout_width="fill_parent"  

10.      android:layout_alignParentTop="true"  

11.      android:layout_alignParentLeft="true">    

12.          

13.          

14.          

15.    

16.       android:id="@+id/gallery"  

17.       android:background="#55000000"  

18.       android:layout_width="fill_parent"  

19.       android:layout_height="60dp"  

20.       android:layout_alignParentBottom="true"  

21.       android:layout_alignParentLeft="true"      

22.       android:gravity="center_vertical"  

23.       android:spacing="16dp" />    

24.    

25.    

  4.ImageShowActivity 

  R.drawable.sample_thumb_0 为图片的标识

图片放在 res/drawable/目录下   图片名称为 sample_thumb_0.gif

Java 代码       

1.   package com.small.photos;    

2.     

3.   import android.app.Activity;    

4.   import android.content.Context;    

5.   import android.os.Bundle;    

6.   import android.view.View;    

7.   import android.view.ViewGroup;    

8.   import android.view.Window;    

9.   import android.view.animation.AnimationUtils;    

10.  import android.widget.AdapterView;    

11.  import android.widget.BaseAdapter;    

12.  import android.widget.Gallery;    

13.  import android.widget.ImageSwitcher;    

14.  import android.widget.ImageView;    

15.  import android.widget.AdapterView.OnItemSelectedListener;    

16.  import android.widget.RelativeLayout.LayoutParams;    

17.  import android.widget.ViewSwitcher.ViewFactory;    

18.    

19.  public class ImageShowActivity extends Activity implements ViewFactory,    

20.          OnItemSelectedListener {    

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

22.      ImageSwitcher mSwitcher;    

23.      private Integer[] mThumbIds = { R.drawable.sample_thumb_0,    

24.              R.drawable.sample_thumb_1, R.drawable.sample_0, R.drawable.sample_1 };    

25.    

26.      private Integer[] mImageIds = { R.drawable.sample_thumb_0,    

27.              R.drawable.sample_thumb_1, R.drawable.sample_0, R.drawable.sample_1 };    

28.    

29.      @Override  

30.      public void onCreate(Bundle savedInstanceState) {    

31.          super.onCreate(savedInstanceState);    

32.          requestWindowFeature(Window.FEATURE_NO_TITLE);    

33.    

34.          setContentView(R.layout.image_show);    

35.          setTitle("ImageShowActivity");    

36.    

37.          mSwitcher = (ImageSwitcher) findViewById(R.id.ImageSwitcher01);    

38.          // 系统的 anim 中的 fade_in.xml    

39.          mSwitcher.setFactory(this);    

40.          mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,    

41.                  android.R.anim.fade_in));    

42.          mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,    

43.                  android.R.anim.fade_out));    

44.    

45.          Gallery g = (Gallery) findViewById(R.id.gallery);    

46.          // 为缩略图浏览器指定一个适配器    

47.          g.setAdapter(new ImageAdapter(this));    

48.          // 响应 在缩略图列表上选中某个缩略图后的 事件    

49.          g.setOnItemSelectedListener(this);    

50.    

51.      }    

52.    

53.      @SuppressWarnings("unchecked")    

54.      public void onItemSelected(AdapterView parent, View v, int position, long id) {    

55.          mSwitcher.setImageResource(mImageIds[position]);    

56.      }    

57.    

58.      @SuppressWarnings("unchecked")    

59.      public void onNothingSelected(AdapterView parent) {    

60.      }    

61.    

62.      @Override  

63.      public View makeView() {    

64.          ImageView i = new ImageView(this);    

65.          i.setBackgroundColor(0xFF000000);    

66.          i.setScaleType(ImageView.ScaleType.FIT_CENTER);    

67.          i.setLayoutParams(new ImageSwitcher.LayoutParams(    

68.                  LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));    

69.          return i;    

70.      }    

71.    

72.      public class ImageAdapter extends BaseAdapter {    

73.          private Context mContext;    

74.    

75.          public ImageAdapter(Context c) {    

76.              mContext = c;    

77.          }    

78.    

79.          public int getCount() {    

80.              return mThumbIds.length;    

81.          }    

82.    

83.          public Object getItem(int position) {    

84.              return position;    

85.          }    

86.    

87.          public long getItemId(int position) {    

88.              return position;    

89.          }    

90.              

91.          //getView 方法动态生成一个 ImageView,然后利用 setLayoutParams、

setImageResource、    

92.          //setBackgroundResource 分别设定图片大小、图片源文件和图片背景。当图片被

显示到当前    

93.          //屏幕的时候,这个函数就会被自动回调来提供要显示的 ImageView    

94.          public View getView(int position, View convertView, ViewGroup parent) {    

95.              ImageView i = new ImageView(mContext);    

96.    

97.              i.setImageResource(mThumbIds[position]);    

98.              i.setAdjustViewBounds(true);    

99.              i.setLayoutParams(new Gallery.LayoutParams(    

100.                      LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));    

101.              i.setBackgroundResource(R.drawable.picture_frame);    

102.              return i;    

103.          }    

104.    

105.      }    

106.    

107.  }  

    5.AndroidManifest.xml   标识 MainActivity 为一个程序的开始

Java 代码       

1.       

2.  

3.         package="com.small.photos"  

4.         android:versionCode="1"  

5.         android:versionName="1.0">    

6.           

7.          

8.                     android:label="@string/app_name">    

9.                   

10.              

11.    

12.          

13.      

14.      

15.      

16.      

17.    

18.    

19.     

  

  基本上就是这些了,然后启动吧!

opengl es 雾

文章分类:移动开发  

雾效果在某种场合很重要,想象你正在游戏中穿过城市的边缘,显然你并没有渲

染场景中很远距的物体,因为代价很大。当然你不愿意突然出现的场景或物体。

雾可以解决这个问题。

 

雾同样可以使场景更加逼真,例如一个山谷中的场景,往往会云气缭绕。

 

这一章依据第 17 章的代码。

 

程序代码:

 

雾可以指定一个颜色,我们创建一个灰色的颜色。

 

float fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f };

 

雾又三种模式,下面列表给出:

 

模式           描述

GL_EXP         雾的最简单的一种模式. 物体并没有真正的存在雾中,仅仅是

一种阴霾的效果。

GL_EXP2         比第一种模式高级. 比第一种逼真些,但远近距离效果不够真

实。

GL_LINEAR         最逼真的一种模式. 模拟现实中的场景。

 

由上可以看出,GL_LINEAR 是最好的一种效果,但并不意味着你要使用它。显然

越好的效果,性能的损失就越大,根据你的需要选择哪种模式。

 

创建一个数组,保存雾的所有模式,用于即使切换。fogType 指明当前使用的哪

种模式。

 

float fogTypes[] = { GL_EXP, GL_EXP2, GL_LINEAR };

int fogType = 0;

 

设置雾的效果,需要使用 glFogf 或 glFogfv 函数。glFogf 函数有两个参数,第

一个是指定要修改的雾的属性标志,第二个是修改的值。

 

下表描述了雾的各种属性。

标记                                  浮点

值                                   描述

GL_FOG_MODE         GL_EXP, GL_EXP2 or GL_LINEAR         雾的效果模式.

GL_FOG_DENSITY         > 0.0f (default 1.0f)               雾的密度,

值越大密度越高。

GL_FOG_START         Any float (default 0.0f)               指定雾的近

面距离,在此距离内不渲染.

GL_FOG_END         Any float (default 1.0f)                   指定雾的

远面距离,超过此距离不渲染.

 

了解了属性参数,下面设置雾的属性,初始化雾的模式为 GL_EXP.

 

bool init()

{

      .

      .

      glFogf(GL_FOG_MODE, GL_EXP);

 

      //指定雾的颜色,灰色

      glFogfv(GL_FOG_COLOR, fogColor);

 

      //雾的密度

      glFogf(GL_FOG_DENSITY, 0.35f);

      

      //系统如何计算雾气,这里设置不关心

      glHint(GL_FOG_HINT, GL_DONT_CARE);

 

      glFogf(GL_FOG_START, 1.0f);

      glFogf(GL_FOG_END, 5.0f);

 

      glEnable(GL_FOG);

      .

      .

}

 

void display()

{

      .

      .

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

      .

      .

}

 

menu 函数中动态改变雾的模式。

 

      case 3 :

              ++fogType %= 3;

              glFogf(GL_FOG_MODE, fogTypes[fogType]);

              break;

 

至此,雾已经加入到你的场景了,观察效果吧。

 

  

  

Opengl 归纳

文章分类:移动开发  

1.雾  

Java 代码       

1.   // fog  opengles    

2.                      

3.                   gl.glFogfv(GL10.GL_FOG_COLOR, fogColorBfr);    

4.                   gl.glFogf(GL10.GL_FOG_DENSITY, 0.35f);    

5.                   gl.glHint(GL10.GL_FOG_HINT, GL10.GL_DONT_CARE);    

6.                   gl.glFogf(GL10.GL_FOG_START, 2.0f);    

7.                   gl.glFogf(GL10.GL_FOG_END, 6.0f);    

8.                   gl.glEnable(GL10.GL_FOG);  

 

Java 代码       

1.   glClearColor(0.5f,0.5f,0.5f,1.0f);   // 设置背景的颜色为雾气的颜色    

2.   glFogi(GL_FOG_MODE, fogMode[fogfilter]);  // 设置雾气的模式    

3.   glFogfv(GL_FOG_COLOR, fogColor);   // 设置雾的颜色    

4.   glFogf(GL_FOG_DENSITY, 0.35f);   // 设置雾的密度    

5.   glHint(GL_FOG_HINT, GL_DONT_CARE);   // 设置系统如何计算雾气    

6.   glFogf(GL_FOG_START, 1.0f);    // 雾气的开始位置    

7.   glFogf(GL_FOG_END, 5.0f);    // 雾气的结束位置    

8.   glEnable(GL_FOG);     // 使用雾气  

 

 

 

2.混合  Blend  

Java 代码       

1.   gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);    

2.   gl.glEnable(GL10.GL_BLEND);  

 

 

3.纹理  

Java 代码       

1.   // create textures    

2.                  gl.glEnable(GL10.GL_TEXTURE_2D);    

3.                  texturesBuffer = IntBuffer.allocate(3);    

4.                  gl.glGenTextures(3, texturesBuffer);    

5.                      

6.                  // load bitmap    

7.                  Bitmap texture = Utils.getTextureFromBitmapResource(context, R.drawable.glas

s);    

8.                      

9.                  // setup texture 0    

10.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(0));    

11.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_NEAREST);    

12.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL1

0.GL_NEAREST);    

13.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.G

L_CLAMP_TO_EDGE);    

14.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.G

L_CLAMP_TO_EDGE);    

15.                 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);    

16.                     

17.                 // setup texture 1    

18.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(1));    

19.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_LINEAR);    

20.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL1

0.GL_LINEAR);    

21.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.G

L_CLAMP_TO_EDGE);    

22.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.G

L_CLAMP_TO_EDGE);    

23.                 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);    

24.                     

25.                 // setup texture 2    

26.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(2));    

27.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL1

0.GL_LINEAR);    

28.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL1

0.GL_LINEAR_MIPMAP_NEAREST);    

29.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.G

L_CLAMP_TO_EDGE);    

30.                 gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.G

L_CLAMP_TO_EDGE);    

31.                 Utils.generateMipmapsForBoundTexture(texture);    

32.    

33.                 // free bitmap    

34.                 texture.recycle();  

定向光

文章分类:移动开发  

这一节我们使用定向光,涉及漫射光的高级应用和镜面光源。

我们将展示镜面光的显示效果,使用红色的小球和照在小球上的光源。

 

程序代码:

 

第一步依然是定义属性值,这里我们要加上镜面光的属性值定义。

float lightAmbient[] = { 0.2f, 0.0f, 0.0f, 1.0f };

float lightDiffuse[] = { 0.5f, 0.0f, 0.0f, 1.0f };

float lightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

 

同样,定义材质对镜面光的反射值

float matAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };

float matDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };

float matSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

 

因为是定向光,所以我们需要知道光的位置和方向,下面代码就是定义位置和方

向,

 

float lightPosition[] = { 2.0f, 2.0f, 3.0f, 0.0f };

float lightDirection[] = { -2.0f, -2.0f, -3.0f };

 

下面启用第一个光源

void init()

{

      glEnable(GL_LIGHTING);

      glEnable(GL_LIGHT0);

 

设置材质属性

      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);

      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);

      glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular);

 

另一个可以用 glMaterialf 设置的属性是 GL_SHININESS,它的值在 0 到 128 之

间,它表明镜面光的焦距度,值越大镜面光焦距越多。

 

glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0f);

 

下一步设置光属性

      glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);

      glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);

      glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);

 

设置光源的位置和方向,使用 glLightfv 函数,它的第二个参数可以指明设置

的是位置还是方向。

 

      glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);

      glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection);

 

另一个有用的标记是 GL_SPOT_CUTOFF,它指定光锥体的大小,想象一个火把远

离你时所产生的火光锥体,1.2 将产生 2.4 度大的光锥体,如果设置为 180 度,

则发射的光会照到各个角落。

 

glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 1.2f);

 

我们要讨论的下一个标记是 GL_SPOT_EXPONENT,它控制圆锥体内光强分布的指

数因子,值在 0 到 128 之间,值越大,锥体轴线部分的光越强。

 

glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 20.0f);

 

glLightf 函数还有三个标记可以设置,是用来控制衰减方式的,分别是:

GL_CONSTANT_ATTENUATION(1), GL_LINEAR_ATTENUATION(0),

GL_QUADRATIC_ATTENUATION。即常数衰减,线性衰减和二次衰减。括号中的值是

它的默认值。

衰减指的是光的强度逐渐减弱,就像你离火光越来越远一样。设置这些属性会导

致程序大幅减慢。

 

display 函数余下部分不变。

 

      glEnable(GL_DEPTH_TEST);

      glDepthFunc(GL_LEQUAL);

 

      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

      glClearDepthf(1.0f);

 

      glEnable(GL_CULL_FACE);

      glShadeModel(GL_SMOOTH);

}

 

我们简单的使用 glutSolidSphere / ugSolidSpheref 来创建求面体,这个球面

体由水平 24 栈和垂直 24 片组成,这样可以更多的体现光照细节。

 

也许你奇怪我们为什么没有指定球面的法线,令人高兴的是 UG / GLUT|ES 库中

创建的形状物体,法线是自动生成的,均由库自动计算,这大大简化了我们的任

务。

void display()

{

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     glLoadIdentity();

 

     gluLookAtf(

              0.0f, 0.0f, 4.0f,

              0.0f, 0.0f, 0.0f,

              0.0f, 1.0f, 0.0f);

 

     glRotatef(xrot, 1.0f, 0.0f, 0.0f);

     glRotatef(yrot, 0.0f, 1.0f, 0.0f);

 

     ugSolidSpheref(1.0f, 24, 24);

 

     glFlush();

     glutSwapBuffers();

}

 

运行程序,会呈现一个红色的球,注意镜面光源在球的右上方,那么现在你可以

把定向光加入自己的程序了。

 

opengl es 灯光

文章分类:移动开发  

这一章将在你的程序中加入灯光,使场景看起来和真实场景一样。

 

灯光

 

opengl 中灯光分为好几种,都可以加入到你的场景中。

 

Ambiend Light 环境光

环境光没有确切的来源方向,当环境光照射到物体时,光被反射到各个方向。

 

Diffuse Light 漫射光

漫射光不同于环境光,它来自某个方向,但和环境光一样,照射到物体时,会被

反射到各个方向。

 

Specular Light 镜面光

镜面光和漫射光一样是有方向的,但它反射方向是一定的,而不像漫射光一样反

射到各个方向。所以当镜面光照射到物体时,你会看到物体表面被照射的亮点。

 

Emissive Light 发射光

它来自于某一物体,该物体散发出大量的光,但不会被任何物体面反射。

 

为了更好的理解这几种光,我从网络上摘抄了一段定义:

      * 环境光——经过多次反射而来的光称为环境光,无法确定其最初的方向,

但当特定的光源关闭后,它们将消失.

      * 全局环境光——它们并非来自特定的光源,这些光经过了多次散射,已

经无法确定其光源位于何处.

      * 散射光——来自同一方向,照射到物体表面后,将沿各个方向均匀反射,

因此,无论从哪个方向观察,表面的亮度都相同.

      * 镜面反射光——来自特定方向,也被反射到特定方向.镜面反射度与之

相关.

      * 材质发射光——用于模拟发光物体.在 OpenGL 光照模型中,表面的发射

光增加了物体的亮度,它不受光源的影响,另外,发射光不会给整个场景中增加

光线.

 

材质

 

你不光可以设置光的属性,而且还可以指定不同的面对光照作出的反应,这就要

指定材质属性。

这就指定了一个面对光源反射多少。

 

法线

 

法线是一个向量垂直于(90 度)某一特定面,就称这个向量是某个面的法线。

法线可以用于光的计算。如果你想让画出的物体对光源产生影响,那么必须指定

物体每个面的法线。下面将会说明。

 

另一个需要注意的一点是,法线要单位化,我们不会深入数学计算,这不是我们

这章的目的。如果需要会在将来某章中讲解。简明的说,一个向量的长度等于各

个向量分量的平方和的平方根,再把每个向量的分量除以这个值。现在不需要过

多担心这个。

 

程序代码:

 

下面定义两个颜色数组,一个用于环境光,一个用于漫射光,它们是光源的颜色

值。

float lightAmbient[] = { 0.2f, 0.3f, 0.6f, 1.0f };

float lightDiffuse[] = { 0.2f, 0.3f, 0.6f, 1.0f };

 

下面创建一个材质属性数组,分别用于环境光和漫射光。

用材质属性值乘以光源值得出面的反射颜色值,下面的值将会导致面反射的光失

去接收光的百分之四十。每个值表示特定颜色被反射的数量。

float matAmbient[] = { 0.6f, 0.6f, 0.6f, 1.0f };

float matDiffuse[] = { 0.6f, 0.6f, 0.6f, 1.0f };

 

void init()

{

首先先启用光源,这样光才会在场景中起作用。

glEnable(GL_LIGHTING);

 

opengl 最多允许 8 个光源,要使用某个光源,需要使用 glEnable 打开它,光源

的编号是 GL_LIGHTX,X 的值是 0---7。

指定材质属性,可以使用 glMaterialfv 和 glMaterialf ,glMaterialfv 接受向

量数组,而 glMaterialf 只接受一个向量。第一个参数指定那个面被更新,在

opengl es 中只可以使用 GL_FRONT_AND_BACK,其他参数不起作用。之所以存在

这个参数,是因为 opengl 可以设置多个参数。

第二个参数指定光源的类型,GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR,

GL_EMISSION 和 GL_AMBIENT_AND_DIFFUSE. 

最后一个参数指定一个数组或单个值,取决于你使用的哪个函数。

 

下一行设置面的材质属性:

      glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);

      glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);

 

灯光的设置和材质的设置相同,使用 glLightfv 或 glLightf 函数:

      glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);

      glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);

 

init 函数没有发生改变:      

      glEnable(GL_DEPTH_TEST);

      glDepthFunc(GL_LEQUAL);

 

      glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

      glClearDepthf(1.0f);

 

      glVertexPointer(3, GL_FLOAT, 0, box);

      glEnableClientState(GL_VERTEX_ARRAY);

 

      glEnable(GL_CULL_FACE);

      glShadeModel(GL_SMOOTH);

}

 

display 函数的开头部分没有发生改变:

void display()

{

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     glLoadIdentity();

 

     gluLookAtf(

              0.0f, 0.0f, 3.0f,

              0.0f, 0.0f, 0.0f,

              0.0f, 1.0f, 0.0f);

 

     glRotatef(xrot, 1.0f, 0.0f, 0.0f);

     glRotatef(yrot, 0.0f, 1.0f, 0.0f);

 

前面我们讨论了法线,法线是垂直于面的,所以前平面的法线是(0, 0, 1),后

平面的法线是(0, 0, -1),两个法线的长度为 1,所以不用再单位化。

法线由 glNormal3f 函数指定,并在渲染时调用。这个函数由 3 个 float 类型的

数据组成单位化的向量。

     // FRONT AND BACK

     glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

     glNormal3f(0.0f, 0.0f, 1.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

     glNormal3f(0.0f, 0.0f, -1.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);

     

     其他页面设置也同上,

 

     // LEFT AND RIGHT

     glColor4f(0.0f, 1.0f, 0.0f, 1.0f);

     glNormal3f(-1.0f, 0.0f, 0.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);

     glNormal3f(1.0f, 0.0f, 0.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);

 

     // TOP AND BOTTOM

     glColor4f(0.0f, 0.0f, 1.0f, 1.0f);

     glNormal3f(0.0f, 1.0f, 0.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 16, 4);

     glNormal3f(0.0f, -1.0f, 0.0f);

     glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);

 

     glFlush();

     glutSwapBuffers();

}

 

最后菜单增加一项彩色材质,这项选择打开或关闭色彩跟踪。色彩跟踪根据当前

面的色彩反色不同色的光。

 

      case 2 : 

              if (glIsEnabled(GL_COLOR_MATERIAL))

                    glDisable(GL_COLOR_MATERIAL);

              else

                    glEnable(GL_COLOR_MATERIAL);

              break;

 

下面两张图是程序的运行结果,分别是普通灯光和色彩追踪的效果。

     普通灯光               色彩跟踪

 

      

opengl es 色彩混合

文章分类:移动开发  

色彩混合对于效果有很大作用,通过它,可以实现物体透明,例如玻璃、水、窗

户等等。

 

alpha 是混合的基础,前面说过,色彩是由 RGBA 表示的,A 就代表 alpha,我们

可以简单理解为透明度。A 值为 0 代表完全透明,1 代表不透明,指定 A 的值 0

到 1 之间可以调整色彩的透明度。

 

当使用混合时,始终要记住两个不同的颜色,一个是源色彩(用来参加运算),一

个是目标色彩(已经存在于缓冲区)。混合就是进行两个色彩的运算。

 

程序代码:

 

这章使用正交视图

 

glOrthof(0.0f, 3.0f, 0.0f, 3.0f, -1.0f, 1.0f);

 

然后重叠几个矩形放在屏幕上,顶点数组下面给出:

 

GLfloat rectangle[] = {

      -1.0f, -0.25f,

         1.0f, -0.25f,

      -1.0f,    0.25f,

         1.0f,    0.25f

};

 

下面将显示色彩的不同混合方式,下面的变量用来控制混合方式。

 

int currBlend = 4;

 

init 函数首先选择清除缓冲区的颜色,并且不使用深度值。

 

void init()

{

      glClearColor(0.25f, 0.25f, 0.25f, 1.0f);

 

然后启用混合功能,传递 GL_BLEND 参数给 glEnable 函数。

 

glEnable(GL_BLEND);

 

glBlendFunc 函数用于指定颜色如何混合,有两个参数,它们指定颜色运算方式,

有下面几种方式:

 

GL_ZERO

GL_ONE

GL_SRC_COLOR

GL_ONE_MINUS_SRC_COLOR

GL_DST_COLOR

GL_ONE_MINUS_DST_COLOR

GL_SRC_ALPHA

GL_ONE_MINUS_SRC_ALPHA

GL_DST_ALPHA

GL_ONE_MINUS_DST_ALPHA

 

第一个参数也可以指定为 GL_SRC_ALPHA_SATURATE。

 

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

 

下面的数组用于切换不同的混合操作。

 

GLenum blendSrc[] = {

      GL_ONE,

      GL_ONE,

      GL_ONE,

      GL_SRC_ALPHA,

      GL_SRC_ALPHA

};

 

GLenum blendDst[] = {

      GL_ZERO,

      GL_ONE,

      GL_ONE_MINUS_DST_ALPHA,

      GL_ONE,

      GL_ONE_MINUS_SRC_ALPHA

};

 

display 函数放置 4 个矩形在屏幕上

 

void display()

{

      glClear(GL_COLOR_BUFFER_BIT);

      glLoadIdentity();

 

      glVertexPointer(2, GL_FLOAT, 0, rectangle);

 

      glEnableClientState(GL_VERTEX_ARRAY);

 

      glPushMatrix();

              glTranslatef(1.5f, 2.0f, 0.0f);

              glColor4f(1.0f, 0.0f, 0.0f, 0.5f);

              glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

      glPopMatrix();

 

      glPushMatrix();

              glTranslatef(0.7f, 1.5f, 0.0f);

              glRotatef(90.0f, 0.0f ,0.0f, 1.0f);

              glColor4f(0.0f, 1.0f, 0.0f, 0.5f);

              glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

      glPopMatrix();

 

      glPushMatrix();

              glTranslatef(1.7f, 1.5f, 0.0f);

              glRotatef(90.0f, 0.0f ,0.0f, 1.0f);

              glColor4f(0.0f, 0.0f, 1.0f, 0.25f);

              glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

      glPopMatrix();

 

      glPushMatrix();

              glTranslatef(1.5f, 1.0f, 0.0f);

              glColor4f(1.0f, 1.0f, 0.0f, 0.75f);

              glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

      glPopMatrix();

 

      glFlush();

      glutSwapBuffers();

}

 

menu 函数中选择不同的混合处理。

 

      case 2 :

              ++currBlend %= 5;

              glBlendFunc(blendSrc[currBlend], blendDst[currBlend]);

              glutPostRedisplay();

              break;

 

运行程序,你可以使用'b'键改变混合方式。

 

默认混合方式为( GL_ONE, GL_ZERO ),这种方式意味着目标色不起作用,仅仅

用源色覆盖目标色,效果如下:

 

 

 

第二种方式为( GL_ONE, GL_ONE ),

 

 

 

第三种方式为(GL_ONE, GL_ONE_MINUS_DST_ALPHA)

 

 

第四种方式为(GL_SRC_ALPHA, GL_ONE)

 

 

 

(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

 

  

opengl es  灯光  | Opengl-ES  方法  

Android 图片倒影

文章分类:移动开发  

public static Bitmap createReflectedImage(Bitmap originalImage) {

       // The gap we want between the reflection and the original image

       final int reflectionGap = 4;

 

       int width = originalImage.getWidth();

       int height = originalImage.getHeight();

 

       // This will not scale but will flip on the Y axis

       Matrix matrix = new Matrix();

       matrix.preScale(1, -1);

 

      // Create a Bitmap with the flip matrix applied to it.

      // We only want the bottom half of the image

      Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,

                            height / 2, width, height / 2, matrix, false);

 

     // Create a new bitmap with same width but taller to fit reflection

     Bitmap bitmapWithReflection = Bitmap.createBitmap(width,

                            (height + height / 2), Config.ARGB_8888);

 

     // Create a new Canvas with the bitmap that's big enough for

     // the image plus gap plus reflection

     Canvas canvas = new Canvas(bitmapWithReflection);

     // Draw in the original image

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

     // Draw in the gap

     Paint defaultPaint = new Paint();

     canvas.drawRect(0, height, width, height + reflectionGap,      

defaultPaint);

     // Draw in the reflection

     canvas.drawBitmap(reflectionImage, 0, height + reflectionGap,

null);

 

    // Create a shader that is a linear gradient that covers the reflection

    Paint paint = new Paint();

    LinearGradient shader = new LinearGradient(0,

                         originalImage.getHeight(), 0,          

bitmapWithReflection.getHeight()

            + reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);

    // Set the paint to use this shader (linear gradient)

    paint.setShader(shader);

    // Set the Transfer mode to be porter duff and destination in

    paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));

    // Draw a rectangle using the paint with our linear gradient

    canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()

+ reflectionGap, paint);

 

    return bitmapWithReflection;

}

画面

文章分类:移动开发  

Android 系统开机动画包括两部分:

开机显示的 ANDROID 文字;

ANDROID 发光动画。

这篇文章说的开机动画是第一种,下面开始正文!

1. 制作当前屏幕像素的图片(模拟器默认为 320*480)

使用 PS 制作一张 320*480 的图片,保存时选“保存为 Web 所用格式”,然后在

弹开的窗口上,“预设”项选择“PNG-24”,保存为 android_logo.png

注:好像只支持 png-24,其他格式生成的 rle 文件显示不正常,有兴趣大家可

以再验证一下。

2. 将图片转换为 raw 格式

使用linux下的ImageMagick自带的convert命令,进行raw格式转换,命令为:

   convert -depth 8 android_logo.png rgb:android_logo.raw

注:ubuntu 10.04 默认已经安装 ImgageMagick 工具,如果当前系统没有安装,

可以执行下面的命令安装:

   sudo apt-get install imagemagick

3. 将 raw 格式转化为 rle 文件

需要用到android编译后的rgb2565工具,在android/out/host/linux-x86/bin

目录下(android 为当前源码所在目录),转换命令如下:

rgb2565 -rle < android_logo.raw > initlogo.rle

到目前为止,启动需要显示的图像已经做好了,就是 initlogo.rle,注意文件

名必须是这个,如果想改文件名,需要修改 android/system/core/init/init.h

中的宏:

#define INIT_IMAGE_FILE "/initlogo.rle" 

=====================================================================

=======================

下面需要将 initlogo.rle 加入的 android 文件系统中

4. 找到 ramdisk.img 文件

(android/out/target/product/generic/ramdisk.img),将文件名改为

ramdisk.img.gz,然后使用下面的命令解压:

gunzip ramdisk.img.gz

解压后得到 ramdisk.img,可能有人要问,怎么文件名又改回去了?其实不然,

使用 file ramdisk.img 查看一下就知道了:

解压前:ramdisk.img: gzip compressed data, from Unix

解压后:ramdisk.img: ASCII cpio archive (SVR4 with no CRC)

跑题了,还是说正事儿。

5. 使用 cpio 提取文件:

新建一个 temp 目录:

mkdir temp

cd temp

cpio -i -F ../ramdisk.img

6. 导出文件列表:

cpio -i -t -F ../ramdisk.img > list             

注:list 是一个文本文件,里面存储了 ramdisk.img 的文件结构,我们需要在

这个文件中加入 initlogo.rle 这一行,修改后的文件如下:

data

default.prop

dev

init

init.goldfish.rc

init.rc

initlogo.rle 

proc

sbin

sbin/adbd

sys

system

7. 生成 ramdisk.img

cpio -o -H newc -O ramdisk.img < list 

注:根据 list 文件的描述,生成 ramdisk.img 文件

8. 用 ramdisk.img 覆盖 sdk 目录下的

ramdisk.img(android-sdk-windows/platforms/android-2.1/images/ramdisk.

img),最好先备份一下。

9. 启动模拟器,就可以看到我们自己做的的开机界面了。

/////////////////////////

开机图片设置 的下载地址为:http://docs.google.com/leaf?id=0 ...

TIzOGQ5OWQ3&hl=en

init 文件下载地址 http://docs.google.com/leaf?id=0 ...

2RiYjZjNjM2&hl=en

split_bootimg.pl 下载地址:

http://android-dls.com/files/linux/split_bootimg.zip

T 卡文件下载地址:http://docs.google.com/leaf?id=0 ...

GVjYzVhMjg4&hl=en

 

开机图片设置 软件原理:

         根据android 系统开机LOGO和开机动画的存放路径:/initlogo.rle

和 /data/local/bootanimation.zip 在 init.rc 中 建立两个链接:

/initlogo.rle ->/data/data/com.android.e139.gallery/initlogo.rle 和

/data/local/bootanimation.zip

->/data/data/com.android.e139.gallery/bootanimation.zip   

来完成开机 LOGO 和开机动画的动态设定

安装要求:

1.本 apk 文件只能安装在 android 2.1 或 2.0 的操作系统 中

2.必须修改 android 根目录下面的两个文件:init.rc 和 init 功能才能实现

设置开机 LOGO 和开机动画的功能

 

修改 init.rc 和 init 的方法:

1.修改 init.rc 和 init 文件需要修改手机中的 boot.img

导出方法:

cat /dev/mtd/mtd2 > /sdcard/root.img

然后

adb pull /sdcard/root.img ./

这样就把 root.img 拷贝到本地目录下了。

boot.img 的组成结构是

+—————–+

| boot header | 1 page

+—————–+

| kernel | n pages

+—————–+

| ramdisk | m pages

+—————–+

| second stage | o pages

+—————–+

 

那我们要做的就是把这几个部分分别分离出来

我们现在先进行镜像分离。用命令

./split_bootimg.pl boot.img

  

成功执行后,可以得到两个文件,一个是 boot.img-kernel,另一个是

boot.img-ramdisk.gz。我们这里以修改 ramdisk 为例,所以将其解包

mkdir ramdisk

cd ramdisk

gzip -dc ../boot.img-ramdisk.gz | cpio -i

cd ..

2.进入 ramdisk 修改 init.rc 在 init.rc 中增加:

on logo-init

       mkdir /data 0775 system system

# We chown/chmod /data again so because mount is run as root + defaults

       mount yaffs2 mtd@userdata /data nosuid nodev

       chown system system /data

       #for other user can read this dir

       chmod 0775 /data

       symlink /data/data/com.android.e139.gallery/initlogo.rle

/initlogo.rle

on early-boot

# copy file       

       symlink /data/data/com.android.e139.gallery/bootanimation.zip

/data/local/bootanimation.zip

       chmod 0666 /data/local/bootanimation.zip

再将已经下载的 init 文件覆盖到目录下面的 init 文件

3.生成新 img 回到 ramdisk 的上一级目录后执行:

mkbootfs ./ramdisk | gzip > ramdisk-new.gz mkbootimg --cmdline

'no_console_suspend=1 console=null' --kernel boot.img-kernel --ramdisk

ramdisk-new.gz -o boot-new.img

就会重新生成 boot-new.img

3.刷入新 img

生成了新的 img 后,我们如何在系统上应用我们的新 boot.img 呢?首先,把 img

文件放到 sdcard 上去

adb push ./boot_new.img /sdcard

然后执行这两个操作

cat /dev/zero > /dev/mtd/mtd2

flash_image boot /sdcard/mynewimage.img

执行第一个操作时,可能会提示你

write: No space left on device

这个信息没关系,不用管它。两个命令都执行后,最后 adb shell reboot 即可。

如果重启顺利,那么恭喜你,你刷成功了.

 

安装步骤:

1.按上面的步骤修改手机中的 init.rc 和 init 文件

2.把下载的 T 卡文件放到 T 卡中

3.安装 开机图片设置.apk 文件

修改 boot.img 的方法参考:

http://www.kunli.info/2009/09/14/how-to-modify-ramdisk-android/ 和

http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack,_Edit,_and_

Re-Pack_Boot_Images

  

3D 桌面效果动画类

文章分类:移动开发  

Java 代码       

1.   public class CubeAnimation extends Animation implements  

2.           Animation.AnimationListener {    

3.       public static final int FACE_LEFT = 0;    

4.       public static final int FACE_RIGHT = 1;    

5.       private int mInd;    

6.       private float mFromDegrees;    

7.       private float mToDegrees;    

8.       private float mCenterX;    

9.       private float mCenterY;    

10.      private int mHorizonType = 1;    

11.      private float mHorizonValue = 0.5F;    

12.      private Camera mCamera;    

13.      private View mView;    

14.    

15.      public CubeAnimation(int ind) {    

16.          this.mInd = ind;    

17.          this.mFromDegrees = 0.0F;    

18.          this.mToDegrees = 90.0F;    

19.      }    

20.    

21.      public CubeAnimation(Context context, AttributeSet attrs) {    

22.          super(context, attrs);    

23.          TypedArray a = context.obtainStyledAttributes(attrs,    

24.                  R.styleable.CubeAnimation);    

25.    

26.          this.mFromDegrees = 0.0F;    

27.          this.mToDegrees = 90.0F;    

28.    

29.          Description d = Description.parseValue(a.peekValue(0));    

30.          this.mHorizonType = d.type;    

31.          this.mHorizonValue = d.value;    

32.    

33.          this.mInd = a.getInt(1, 0);    

34.    

35.          boolean t = a.getBoolean(2, true);    

36.          if (!(t)) {    

37.              this.mInd = (1 - this.mInd);    

38.              this.mToDegrees = 0.0F;    

39.              this.mFromDegrees = 90.0F;    

40.          }    

41.          a.recycle();    

42.      }    

43.    

44.      public void onAnimationStart(Animation anim) {    

45.          this.mView.setVisibility(View.VISIBLE);    

46.      }    

47.    

48.      public void onAnimationEnd(Animation anim) {    

49.          this.mView.setVisibility((this.mInd == 0) ? 0 : 8);    

50.          this.mInd = (1 - this.mInd);    

51.      }    

52.    

53.      public void onAnimationRepeat(Animation anim) {    

54.      }    

55.    

56.      public static void startCubeAnimation(Context context, int id, View view1,    

57.              View view2) {    

58.          XmlPullParser parser;    

59.          try {    

60.              parser = context.getResources().getAnimation(id);    

61.              AttributeSet attrs = Xml.asAttributeSet(parser);    

62.    

63.              int type = parser.getEventType();    

64.              int depth = parser.getDepth();    

65.              while (true) {    

66.                  while (true) {    

67.                      if ((((type = parser.next()) == 3) && (parser.getDepth() <= depth))    

68.                              || (type == 1))    

69.                          break label172;    

70.                      if (type == 2)    

71.                          break;    

72.                  }    

73.    

74.                  String name = parser.getName();    

75.    

76.                  if (name.equals("cube")) {    

77.                      CubeAnimation anim1 = new CubeAnimation(context, attrs);    

78.                      anim1.mInd = 1;    

79.                      anim1.mView = view1;    

80.                      anim1.setAnimationListener(anim1);    

81.                      CubeAnimation anim2 = new CubeAnimation(context, attrs);    

82.                      anim2.mInd = 0;    

83.                      anim2.mView = view2;    

84.                      anim2.setAnimationListener(anim2);    

85.                      view1.startAnimation(anim1);    

86.                      label172: view2.startAnimation(anim2);    

87.                  }    

88.              }    

89.          } catch (Resources.NotFoundException ex) {    

90.              Log.e("CubeAnimation", "NotFoundException");    

91.          } catch (XmlPullParserException ex) {    

92.              Log.e("CubeAnimation", "XmlPullParserException");    

93.          } catch (IOException ex) {    

94.              Log.e("CubeAnimation", "IOException");    

95.          }    

96.      }    

97.    

98.      public void initialize(int width, int height, int parentWidth,    

99.              int parentHeight) {    

100.          super.initialize(width, height, parentWidth, parentHeight);    

101.          this.mCenterX = resolveSize(1, 0.5F, width, parentWidth);    

102.          this.mCenterY = resolveSize(1, 0.5F, height, parentHeight);    

103.          if (this.mHorizonType == 0) {    

104.              this.mHorizonValue /= height;    

105.          }    

106.    

107.          this.mCamera = new Camera();    

108.      }    

109.    

110.      protected void applyTransformation(float interpolatedTime, Transformation t) {    

111.          float fromDegrees = this.mFromDegrees;    

112.          float degrees = fromDegrees + (this.mToDegrees - fromDegrees)    

113.                  * interpolatedTime;    

114.    

115.          float centerX = this.mCenterX;    

116.          float centerY = this.mCenterY;    

117.          Camera camera = this.mCamera;    

118.    

119.          Matrix matrix = t.getMatrix();    

120.    

121.          camera.save();    

122.    

123.          float b = 0.0F;    

124.          float e = -this.mHorizonValue;    

125.    

126.          if (this.mInd == 0) {    

127.              degrees += 90.0F;    

128.          }    

129.    

130.          camera.rotateY(degrees);    

131.    

132.          camera.getMatrix(matrix);    

133.          camera.restore();    

134.    

135.          if (this.mInd == 0) {    

136.              matrix.preScale(-1.0F, 1.0F, centerX, 0.0F);    

137.          }    

138.    

139.          float tranX = 320.0F * interpolatedTime;    

140.    

141.          float tranY = -centerY * e + b;    

142.          matrix.preTranslate(0.0F, centerY * e);    

143.          matrix.postTranslate(tranX, tranY);    

144.      }    

145.    

146.      protected static class Description {    

147.          public int type;    

148.          public float value;    

149.    

150.          static Description parseValue(TypedValue value) {    

151.              Description d = new Description();    

152.              if (value == null) {    

153.                  d.type = 0;    

154.                  d.value = 0.0F;    

155.              } else {    

156.                  if (value.type == 6) {    

157.                      d.type = (((value.data & 0xF) == 1) ? 2 : 1);    

158.    

159.                      d.value = TypedValue.complexToFloat(value.data);    

160.                      return d;    

161.                  }    

162.                  if (value.type == 4) {    

163.                      d.type = 0;    

164.                      d.value = value.getFloat();    

165.                      return d;    

166.                  }    

167.                  if ((value.type >= 16) && (value.type <= 31)) {    

168.                      d.type = 0;    

169.                      d.value = value.data;    

170.                      return d;    

171.                  }    

172.              }    

173.    

174.              d.type = 0;    

175.              d.value = 0.0F;    

176.    

177.              return d;    

178.          }    

179.      }    

180.  }   

31

菱形 3D 实例

文章分类:移动开发  

下面是具体的实现方法:  

首先需要建两个 array,第一 array 是用来告诉 opengl 这个图形有哪些顶点:  

画一个三维的坐标轴,然后把你要画的点都算出来,然后放在这个 array 里。  

Java 代码       

1.   float l=1.5f;    

2.   float[] vertex={    

3.     

4.   0.0f,l,0.0f,    

5.     

6.   l,0.0f,0.0f,    

7.     

8.   0.0f,0.0f,l,    

9.     

10.  -l,0.0f,0.0f,    

11.    

12.  0.0f,0.0f,-l,    

13.    

14.  0.0f,-l,0.0f    

15.    

16.  };  

 

第二个 array 是告诉 opengl  你要怎样组织这些点:  

这里我要画三角形,所以每三个点是一组。  

Java 代码       

1.   byte[] edge=    

2.   {    

3.   0,1,2,    

4.   1,2,5,    

5.     

6.   0,2,3,    

7.   5,2,3,    

8.     

9.   0,3,4,    

10.  5,3,4,    

11.    

12.  0,4,1,    

13.  5,4,1  

14.    

15.  };  

 

 

这里的数字,是第一个 array 的 index。  

下面你要建立两个 Buffer 它们是用来存放这两个 array 的。  

Java 代码       

1.   ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length*4);    

2.   bb.order(ByteOrder.nativeOrder());    

3.   fbv=bb.asFloatBuffer();    

4.   fbv.put(vertex);    

5.   fbv.position(0);    

6.     

7.   ffe=ByteBuffer.allocateDirect(edge.length);    

8.   ffe.put(edge);    

9.   ffe.position(0);  

 

这样一个三维的菱形就画好了。  

 

下面你要写一个方法能让它自己把自己画出来!  

Java 代码       

1.   public void draw(GL10 gl)    

2.   {    

3.   gl.glFrontFace(GL10.GL_CW);    

4.   gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fbv);    

5.   gl.glDrawElements(GL10.GL_TRIANGLES, 24, GL10.GL_UNSIGNED_BYTE, ffe);    

6.     

7.   }  

 

 

先说第一个 glFrontFace,物体都有一个正面一个反面,这里告诉 opengl 显示这个物体按顺

时针方向(CW=> clockwise)  

 

gl.glVertexPointer(3,  GL10.GL_FLOAT,  0,  fbv);这个方法是把本程序所用的点都传递个 opengl。

opengl 需要知道什么哪?首先是  这个点是几维的(opengl  支持 2,3,4  维),这里是 3 所

以是三维的,第二个参数告诉 opengl,这个点是用什么样类型的变量来储存的,这里是 float

类型。第三个是步长(stride),这个我还没弄明白,不过我看的例子都为 0.  最后把你建立

好的三维坐标点都传给 opengl  

 

gl.glDrawElements。  这个方法是告诉 opengl 如果要画这个图形,应该怎么画。第一个参数,

告诉 opengl  用画三角形(这样 opengl 就以三个点为一组),然后告诉 opengl 你要用到多少

个点(注意这个点是在第二个 array 里的点数)。  第三个是告诉 opengl 这些点(其实是三维

坐标点的 reference)的类型。这里是 unsigned byte。最后把你排列点的 array  放进去!  

 

第二个大的步骤是创建一个让这个三维坐标运行的环境(Renderer)。  

这是一个 interface 类  

首先,在 onDrawFrame 里,我们告诉本程序这个三维图形的行为:  

在做任何事情之前,我们要清空所有以前内存里的东西,这个内存包括:Color  和 Depth  

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

然后告诉 opengl 你要用那个 MatrixMode  这个就比较难解释了。  

如果写程序  只要记住  GL_MODELVIEW  是管理图形的  缩放,移动,和转动就行了.(如果那

个朋友想理解的更深一点,可以联系我,我可以把我的笔记发过去或者参考

http://glasnost.itcarlow.ie/~powerk/GeneralGraphicsNotes/projection/projection_viewing.html  )。  

 

 

gl.glTranslatef(0, 0, -3.0f);  

这个方法告诉 opengl 把图形沿 z 轴迁移 3 个 unit。这三个值分别是 x,y,z 轴。  

gl.glRotatef(angle,0, 1, 0);  

这个方法告诉我们以 y 为轴。  转 angle 个度数。注意这里的 1 和 0 是告诉沿着那个轴转,

别的值应该没有意义。  

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  

还记得上边说的 opengl 分 client  side 和 service  side 吗。  这个是告诉 opengl 如果 client  side

调用 draw 什么的时候,这个 vertex array 是可用的。opengl 有很多这样的可选项,所以需要

告诉 opengl,因为我们已经设置了 vertex  array(我们的第一个 array),所以告诉 opengl  它

是可用的(如果不告诉,opengl 会忽略)!  

 

trian.draw(gl);  

这个方法是把图形画出来。  

 

angle++;  

为了达到动态的效果,我们让每一个 frame  的 angle,比上一个多一度。  

当显示空间大小发生变化的时候,我们应该告诉 opengl 一下信息:  

Java 代码       

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

2.   {    

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

4.   gl.glMatrixMode(GL10.GL_PROJECTION);    

5.   gl.glLoadIdentity();    

6.   float ratio = (float)width/height;    

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

8.     

9.   }  

 

 

首先是 opengl 可用的空间  :  

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

想象一下用这四个点画出来的四边形,就是 opengl 所能用的空间。  

 

gl.glMatrixMode(GL10.GL_PROJECTION);  

这个 matrix 是如何把三维坐标转换为二维坐标并把它放在显示器上。  

gl.glLoadIdentity  

是告诉 opengl 初始化这个 matrix。  

 

gl.glFrustumf  

要把三维的东西用二维显示出来,需要知道几个东西,第一是这个显示平面有多大,你可以

看多近和多远。这里的头四个参数,建立了一个四边形,告诉 opengl 把图形显示在这个范

围了。后两个参数告诉 opengl 这里显示平面里可以显示三维空间里最近和最远的位置。  

 

当这个三维图形建立的是时候,我们可以告诉 opengl 一些基本参数。这里把能省略的都省

略了(其实什么都没有也可以运行!)  

Java 代码       

1.   public void onSurfaceCreated(GL10 gl, EGLConfig arg1)     

2.   {    

3.   gl.glEnable(GL10.GL_DEPTH_TEST);    

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

5.   }  

 

gl.glEnable(GL10.GL_DEPTH_TEST);  告诉 opengl 要检查 depth,为什么哪。在三维空间里一个

物体A 在另一个物体B 后面,那么这个A 被B 挡住里,所以你是看不见的。我们要告诉opengl,

我们不想看见被挡住的东西。这个 GL_DEPTH_TEST  就是这个功能。  

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

设置这个背景颜色为黑色,应为我们没有给我们的三维图形设置颜色(为了简单),它的初

始化颜色是白色。  

 

以下是源代码:  

Java 代码       

1.   package Beta.ThreeD;    

2.     

3.   import java.nio.ByteBuffer;    

4.   import java.nio.ByteOrder;    

5.   import java.nio.FloatBuffer;    

6.     

7.   import javax.microedition.khronos.opengles.GL10;    

8.     

9.   public class TriangleShape     

10.  {    

11.    

12.  private final float l=1.5f;    

13.    

14.  private FloatBuffer fbv;    

15.    

16.  private ByteBuffer ffe;    

17.    

18.  public TriangleShape()    

19.    

20.  {    

21.    

22.  float[] vertex={    

23.    

24.  0.0f,l,0.0f,    

25.    

26.  l,0.0f,0.0f,    

27.    

28.  0.0f,0.0f,l,    

29.    

30.  -l,0.0f,0.0f,    

31.    

32.  0.0f,0.0f,-l,    

33.    

34.  0.0f,-l,0.0f    

35.    

36.  };    

37.    

38.    

39.  byte[] edge=    

40.    

41.  {    

42.    

43.  0,1,2,    

44.    

45.  1,2,5,    

46.    

47.    

48.    

49.  0,2,3,    

50.    

51.  5,2,3,    

52.    

53.    

54.    

55.  0,3,4,    

56.    

57.  5,3,4,    

58.    

59.    

60.    

61.  0,4,1,    

62.    

63.  5,4,1  

64.    

65.  };    

66.    

67.  ByteBuffer bb = ByteBuffer.allocateDirect(vertex.length*4);    

68.    

69.  bb.order(ByteOrder.nativeOrder());    

70.    

71.  fbv=bb.asFloatBuffer();    

72.    

73.  fbv.put(vertex);    

74.    

75.  fbv.position(0);    

76.    

77.    

78.    

79.    

80.  ffe=ByteBuffer.allocateDirect(edge.length);    

81.    

82.  ffe.put(edge);    

83.    

84.  ffe.position(0);    

85.    

86.  }    

87.    

88.  public void draw(GL10 gl)    

89.    

90.  {    

91.    

92.  gl.glFrontFace(GL10.GL_CW);    

93.    

94.  gl.glVertexPointer(3, GL10.GL_FLOAT, 0, fbv);    

95.    

96.  gl.glDrawElements(GL10.GL_TRIANGLES, 24, GL10.GL_UNSIGNED_BYTE, ffe);    

97.    

98.  }    

99.  }    

100.    

101.    

102.  package Beta.ThreeD;    

103.    

104.  import javax.microedition.khronos.egl.EGLConfig;    

105.  import javax.microedition.khronos.opengles.GL10;    

106.    

107.  import android.opengl.GLSurfaceView.Renderer;    

108.    

109.  public class MySimpleRendered implements Renderer    

110.  {    

111.    

112.  private int angle=50;    

113.    

114.  private TriangleShape trian;    

115.    

116.  public MySimpleRendered()    

117.    

118.  {    

119.    

120.  trian = new TriangleShape();    

121.    

122.  }    

123.    

124.  @Override  

125.    

126.  public void onDrawFrame(GL10 gl)     

127.    

128.  {    

129.    

130.  // TODO Auto-generated method stub    

131.    

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

133.    

134.  gl.glMatrixMode(GL10.GL_MODELVIEW);    

135.    

136.  gl.glLoadIdentity();    

137.    

138.  gl.glTranslatef(0, 0, -3.0f);    

139.    

140.  gl.glRotatef(angle,0, 1, 0);    

141.    

142.  gl.glRotatef(angle, 1, 0, 0);    

143.    

144.  gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    

145.    

146.  trian.draw(gl);    

147.    

148.  angle++;    

149.    

150.  }    

151.    

152.    

153.  @Override  

154.    

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

156.    

157.  {    

158.    

159.  // TODO Auto-generated method stub    

160.    

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

162.    

163.  gl.glMatrixMode(GL10.GL_PROJECTION);    

164.    

165.  gl.glLoadIdentity();    

166.    

167.  float ratio = (float)width/height;    

168.    

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

170.    

171.    

172.    

173.  }    

174.    

175.    

176.  @Override  

177.    

178.  public void onSurfaceCreated(GL10 gl, EGLConfig arg1)     

179.    

180.  {    

181.    

182.  gl.glEnable(GL10.GL_DEPTH_TEST);    

183.    

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

185.    

186.  }    

187.    

188.  }    

189.  package Beta.ThreeD;    

190.    

191.  import android.app.Activity;    

192.  import android.os.Bundle;    

193.  import android.opengl.GLSurfaceView;    

194.  public class Triangle extends Activity {    

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

196.    

197.  private GLSurfaceView my_view;    

198.      @Override  

199.      public void onCreate(Bundle savedInstanceState) {    

200.          super.onCreate(savedInstanceState);    

201.          setContentView(R.layout.main);    

202.          my_view = new GLSurfaceView(this);    

203.          my_view.setRenderer(new MySimpleRendered());    

204.          this.setContentView(my_view);    

205.      }    

206.      public void onResume()    

207.      {    

208.          

209.  super.onResume();    

210.          

211.  my_view.onResume();    

212.      }    

213.      public void onPause()    

214.      {    

215.          

216.  super.onPause();    

217.          

218.  my_view.onPause();    

219.      }    

220.  }  

镜像倒影特效 Gallery

文章分类:移动开发  

效果展示

 

本文档将介绍在 android 上如何实现一个倒影效果的 Gallery。

  

为了达到上图所示的效果,

首先,是需要有一个自定义的 gallery,实现了对 Gallery 的继承,通过重写

getChildStaticTransformation 方法来控制,每个子 view 有不同的缩放比例,

形成阶梯状的展示。这个 gallery 是在坤庭的代码基础上实现的,我这里就不再

重复介绍。 

接下来,gallery 中的每个 view,都是一个自定义的 MirrorView,由它来实现

了画原图及画倒影。新的算法解决了性能问题,下面就重点说一下这部分内容:

镜像特效最近还蛮流行的,尤其在 HTC 的 Sense 介面上,常常都可以见到。大

家可以看到,加了个镜像特效后,那感觉就很立体,感觉上好像是这些图片摆立

在一个玻璃桌面上。

在 Android 上要帮图片加上镜像特效,会不会很麻烦?一点也不麻烦,只要几

行代码,就可以搞定。

因此,在开始看答案之前,我会建议你要先有 Photoshop 的使用经验。想想,

如果用 Photoshop 要帮图片加上镜像特效,要如何做?我想一般不外乎是先复

制个图片,并将其垂直翻转,接着再对这翻转的图片,加个由灰到黑的渐层 mask

即可。

好了,让我们来看一下答案。底下就是帮图片加上镜像特效的程式范例。

  

Java 代码       

1.   public  class  MirrorView extends  View {    

2.     

3.   Paint m_paint;    

4.     

5.   int m_nShadowH;    

6.     

7.   Drawable m_dw;    

8.     

9.   Bitmap m_bitmap;    

10.    

11.  Matrix mMatrix;    

12.    

13.  int shadowHeight;    

14.    

15.  public MirrorView(Context context, Bitmap bitmap) {    

16.    

17.  super (context);    

18.    

19.  m_bitmap = bitmap;    

20.    

21.  _Init();    

22.    

23.  }    

24.    

25.  private void _Init() {    

26.    

27.  //m_dw = new BitmapDrawable(BitmapFactory.decodeResource(getResources(),  R.draw

able.icon));    

28.    

29.  m_dw = new BitmapDrawable(m_bitmap);    

30.    

31.  m_dw.setBounds(0,0,m_dw.getIntrinsicWidth(),m_dw.getIntrinsicHeight());    

32.    

33.  m_nShadowH = m_dw.getIntrinsicHeight()/1;    

34.    

35.  m_paint = new Paint(Paint.ANTI_ALIAS_FLAG );    

36.    

37.  LinearGradient lg = new LinearGradient(0, 0, 0, m_nShadowH, 0xB0FFFFFF, 0×00000000,

Shader.TileMode.CLAMP );    

38.    

39.  m_paint.setShader(lg);    

40.    

41.  m_paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY ));    

42.    

43.  mMatrix = new Matrix();    

44.    

45.  }    

46.    

47.  @Override  

48.    

49.  public void onDraw(Canvas canvas) {    

50.    

51.  super .onDraw(canvas);    

52.    

53.  int nX = 0;    

54.    

55.  int nY = 0;    

56.    

57.  _DrawNormalImg(canvas, nX, nY);    

58.    

59.  _DrawMirror(canvas, nX, nY);    

60.    

61.  }    

62.    

63.  private void _DrawNormalImg(Canvas canvas, int nX, int nY) {    

64.    

65.  canvas.save(Canvas.MATRIX_SAVE_FLAG );    

66.    

67.  canvas.translate(nX, nY);    

68.    

69.  m_dw.draw(canvas);    

70.    

71.  canvas.restore();    

72.    

73.  }    

74.    

75.  private void _DrawMirror(Canvas canvas, int nX, int nY) {    

76.    

77.  int nW = m_dw.getIntrinsicWidth();    

78.    

79.  int nH = m_dw.getIntrinsicHeight();    

80.    

81.  shadowHeight=nH/2;    

82.    

83.  float [] src={0, nH, nW, nH, nW,nH – m_nShadowH, 0, nH – m_nShadowH};    

84.    

85.  float [] dst={ 0, nH, nW, nH,nW, shadowHeight, 0, shadowHeight };    

86.    

87.  canvas.save();    

88.    

89.  mMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);    

90.    

91.  canvas.concat(mMatrix);    

92.    

93.  //draw mirror image    

94.    

95.  canvas.save(Canvas.MATRIX_SAVE_FLAG );    

96.    

97.  canvas.scale(1.0f, -1.0f);    

98.    

99.  canvas.translate(nX, -(nY + nH * 2));    

100.    

101.  canvas.clipRect(0, nH, nW, nH – m_nShadowH);    

102.    

103.  m_dw.draw(canvas);    

104.    

105.  canvas.restore();    

106.    

107.  //draw mask    

108.    

109.  canvas.save();    

110.    

111.  canvas.translate(nX, nY + nH);    

112.    

113.  canvas.drawRect(0, 0, nW, m_nShadowH, m_paint);    

114.    

115.  canvas.restore();    

116.    

117.  canvas.restore();    

118.    

119.  }    

120.    

121.  }  

   

_DrawMirror() 方法是关键。用 Photoshop 要如何做出镜像特效?第一步是先

画出垂直翻转的图片。

Android 绘图座标体系预设的原点在左上角,X 轴往右是越来越大的正值,而 Y

轴往下,则是越来越大的正值。要画出垂直翻转的图片,其实也就是要垂直翻转

整个绘图座标体系。在 Android 中,要如何做?答案就是 canvas.scale(1.0f,

-1.0f)。很简单吧,没想到给 scale() 函式一个负值,就可以翻转相对应的轴。

在 Photoshop 中,做镜像特效的第二步是要对这翻转的图片,加个由灰到黑的

渐层 mask。

在 Android 中,要画渐层色,那就一定得用 LinearGradient 这个类别。至于要

对背景图加上个 mask,就请参考一下 Paint 的 setXfermode() 函式。  _Init()

这个函式,就是负责生成一个由灰到黑渐层 mask 的 m_paint 物件。

这个控件我测试过,200 张图片加入 adapter,在大数据量情况下性能也没有问

题。

Gallery3D 各个界面可见范围计算方法

文章分类:移动开发  

computeVisibleRange 算法分析:  

第 1 步,计算出 left,right,bottom,top  

第 2 步,计算出 numSlots,并除于 2 赋值给 index  

第 3 步,由 index 得 position,判断 position 是否在第 1 步计算出的范围内,是的话,就把第 2

步计算得出的中间的 index  赋值给  firstVisibleSlotIndex,lastVisibleSlotIndex,否则,根据滑

动窗口算法改变 index 直到求组所需 index  

第 4 步,在 while 循环中,用第 3 步得到的 firstVisibleSlotIndex 求出 position,进行和第 2 步相

反的判断,即  position 若不在可视范围内,则将相应的 index 给 firstVisibleSlotIndex,否则减

firstVisibleSlotIndex,直到找到最小的可视范围内的 index 作为 firstVisibleSlotIndex。  

第 5 步,在 while 循环中,用第 3 步得到的 lastVisibleSlotIndex 求出 position,进行和第 2 步相

反的判断,即  position 若不在可视范围内,则将相应的 index 给 lastVisibleSlotIndex,否则增

lastVisibleSlotIndex,直到找到可视范围内的最大的 index 作为 lastVisibleSlotIndex。  

第 6 步,进行 firstVisibleSlotIndex,lastVisibleSlotIndex 的越界判断。  outBufferedVisibleRange

对应的是可见的。outBufferedVisibleRange 对应的是 0~文件夹的最大数。  

computeVisibleItems 算法分析:  

第 1 步  由 slot 计算出 position,set,当前 set 不为空且 slot 在有效范围,创建 bestItems,计算

sortedIntersection  

第 2 步  计算这个 slotindex 中的图片数目,取这个文件中的前 12 张图片加到 bestItems.  

第 3 步   取 bestItems 里的图片对应的 displayList 中的 displayItem,并赋值给 displayItems 数

组,同时保存  position,及 j,j 是 bestItems 数组中一项,范围是 0~12。  

第四步   对于每一个文件夹,要在 displayItems 里有对应的 12 项,当文件夹内图片不足 12

时,余下的用 null 填充。  

当绘制缩略图界面时,有些不同  

在第 1 步中,slotindex 不再表示文件夹,这时表示具体某一张图片了,所以由 slot 得到的

set   里始终只有 1   项,且会调   ArrayUtils.computeSortedIntersection(visibleItems,   items,

MAX_ITEMS_PER_SLOT,  bestItems,  sTempHash);给 bestItems 赋值,这样第 2 步就在 bestItems

加项动作不执行。

Gallery3D 中画图时调用 glTranslate 函数参数赋值过程

文章分类:移动开发  

GridDrawManager::drawDisplayItem(RenderView view, GL11 gl, DisplayItem displayItem, Texture

texture, int pass,Texture previousTexture, float mixRatio)  函数有下面几句:  

        

Java 代码       

1.   Vector3f animatedPosition = displayItem.mAnimatedPosition;    

2.           float translateXf = animatedPosition.x * camera.mOneByScale;    

3.           float translateYf = animatedPosition.y * camera.mOneByScale;    

4.           float translateZf = -animatedPosition.z;  

 

调用过程:  

->computeVisibleItems(),displayItems[baseIndex    +    j]    =    displayItem;Vector3f    position    =

pool.create();           GridCameraManager.getSlotPositionForSlotIndex(i,           camera,           layout,

deltaAnchorPosition,  position);//give  position

value   displayList.setPositionAndStackIndex(displayItem,  position,  j,  true);//raletive  position  to

item  

 

->GridLayer,    mDrawManager    =    new    GridDrawManager(context,    mCamera,    mDrawables,

sDisplayList, sDisplayItems, sDisplaySlots);  

->GridDrawManager(), mDisplayItems = displayItems;  

->drawFocusItems ,DisplayItem[] displayItems = mDisplayItems;  

->animatedPosition = displayItem.mAnimatedPosition;  

->drawDisplayItem, amAnimatedPosition  

->DisplayItem::commit()   amAnimatedPosition.set(mTargetPosition);  

->      DisplayItem::set(Vector3f      position,      int      stackIndex,      boolean      performTransition)

mTargetPosition.z =  

 

Java 代码       

1.   public void getPositionForSlotIndex(int slotIndex, int itemWidth, int itemHeight, Vector3f

 outPosition) {    

2.           outPosition.x = (slotIndex / mNumRows) * (itemWidth + mSpacingX);    

3.           outPosition.y = (slotIndex % mNumRows) * (itemHeight + mSpacingY);    

4.           int maxY = (mNumRows - 1) * (itemHeight + mSpacingY);    

5.           outPosition.y -= (maxY >> 1);    

6.           outPosition.z = 0;    

7.           Log.d("outPosition","slotIndex="+slotIndex+",mNumRows="+mNumRows+",outPosit

ion=("+outPosition.x+","+outPosition.y+","+outPosition.z+")");    

8.       }  

 

 

在 gallery3d 中矩阵是从上到下、从左到右排列的,在主界面时最多有 3 行,mNumRows=3,

在缩略图界面最多 4 行 mNumRows=4,在查看界面只有一行 mNumRows=1  

上面函数是计算所绘制项位置的,slotIndex / mNumRows 得到的是当前处于多少列,slotIndex %

mNumRows 得到的是处于多少行。  int maxY = (mNumRows - 1) * (itemHeight + mSpacingY);  

         outPosition.y -= (maxY >> 1);是为了在 y 方向对称,想成屏幕中间是分界线,以上的项 y

为负,线以下的 y 为正。  

deltaAnchorPosition 的赋值过程:  

Java 代码       

1.   int currentlyVisibleSlotIndex = getAnchorSlotIndex(ANCHOR_CENTER);->anchorItem = dis

playItem.mItemRef;-> newSlotIndex = i;->if (currentAnchorSlotIndex != Shared.INVALID &

& newAnchorSlotIndex != Shared.INVALID) {    

2.                   layout.getPositionForSlotIndex(newAnchorSlotIndex, itemWidth, itemHeight, de

ltaAnchorPosition);    

3.                   oldLayout.getPositionForSlotIndex(currentAnchorSlotIndex, itemWidth, itemHei

ght, currentSlotPosition);    

4.                   currentSlotPosition.subtract(sDeltaAnchorPosition);    

5.                   deltaAnchorPosition.subtract(currentSlotPosition);    

6.                   deltaAnchorPosition.y = 0;    

7.                   deltaAnchorPosition.z = 0;    

8.               }  

 

 

MediaFeed::run()  

onFeedChanged(, onLayout(newSlotIndex, currentlyVisibleSlotIndex, null);  

onLayout,   sDeltaAnchorPositionUncommited.set(deltaAnchorPosition);  

computeVisibleRange(),sDeltaAnchorPosition.set(sDeltaAnchorPositionUncommited);  

deltaAnchorPosition.set(sDeltaAnchorPosition);  

deltaAnchorPosition  

Gallery3D 笔记

文章分类:移动开发  

布局及特效   gallery3d 的精华

一、布局

gallery3d 的界面生成和普通的应用程序不一样。普通程序一般一个界面就是一

个activity,布局用xml或代码都可以实现,界面切换是activity的切换方式;

而 gallery3d 没有用 android 的 UI 系统,而是用 opengl 画出来的,即界面是在

同一个 activity 的,如主界面,缩略图界面,单张图片查看界面,标记界面等

都属于同一个 activity。那么这界面布局不同的界面是如何组合到一起的呢?

分析代码,可以把它看成一个状态机:     

1、标记模式     public static final int MODE_SELECT = 1;(HudLayer)

包含了主界面标记模式,缩略界面矩阵游览时标记模式、缩略图界面分类游览时

标记模式 3 个界面

2、普通模式   public static final int MODE_NORMAL = 0;(HudLayer)

包含了

     

Java 代码       

1.   public static final int STATE_MEDIA_SETS = 0;主界面    

2.       public static final int STATE_GRID_VIEW = 1;缩略图矩阵浏览    

3.       public static final int STATE_FULL_SCREEN = 2;查看界面    

4.       public static final int STATE_TIMELINE = 3;缩略图界面分类浏览  

 

有了以上状态分类后,在渲染的时候就能根据些界面的组成来定哪些控件譔隐藏,

哪些要显示了。

下面是基本控件:

Java 代码       

1.   com.cooliris.media.GridLayer    

2.   com.cooliris.media.BackgroundLayer    

3.   com.cooliris.media.HudLayer    

4.   com.cooliris.media.ImageButton    

5.   com.cooliris.media.TimeBar    

6.   com.cooliris.media.MenuBar    

7.   com.cooliris.media.PopupMenu    

8.   com.cooliris.media.PathBarLayer  

 

在渲染时,每一帧所有界面上的元素都画了,由于根据上面的状态只把特定窗口

的特定元素显示出来,其它窗口中的隐藏,所以不会乱。

Layer 是上面控件的基类,上面控件的类也就有了下面两个方法来隐藏不譔显示

的界面元素。

   

Java 代码       

1.   public boolean isHidden() {    

2.           return mHidden;    

3.       }    

4.     

5.       public void setHidden(boolean hidden) {    

6.           if (mHidden != hidden) {    

7.               mHidden = hidden;    

8.               onHiddenChanged();    

9.           }    

10.      }  

 

下面是根据上面分类来画不同元素所用的标识:

    

Java 代码       

1.   public static final int PASS_THUMBNAIL_CONTENT = 0;    

2.      public static final int PASS_FOCUS_CONTENT = 1;    

3.      public static final int PASS_FRAME = 2;    

4.      public static final int PASS_PLACEHOLDER = 3;    

5.      public static final int PASS_FRAME_PLACEHOLDER = 4;    

6.      public static final int PASS_TEXT_LABEL = 5;    

7.      public static final int PASS_SELECTION_LABEL = 6;    

8.      public static final int PASS_VIDEO_LABEL = 7;    

9.      public static final int PASS_LOCATION_LABEL = 8;    

10.     public static final int PASS_MEDIASET_SOURCE_LABEL = 9;  

 

Java 代码       

1.   drawDisplayItem(view, gl, displayItem, texture, PASS_THUMBNAIL_CONTENT, placeholde

r,displayItem.mAnimatedPlaceholderFade); 画缩略图的,注掉此句,前两屏只显示框,

第三屏 OK    

2.   drawDisplayItem(view, gl, displayItem, texture, PASS_FOCUS_CONTENT, null, 0.0f);画单

张图片的,注掉,第三屏黑屏    

3.   drawDisplayItem(view, gl, itemDrawn, textureToUse, PASS_FRAME, previousTexture, ratio

);画边框的,注掉,前两屏明显没有边框,巨齿明显    

4.   drawDisplayItem(view, gl, displayItem, textureString, PASS_TEXT_LABEL, null, 0);画文本

标签的    

5.   drawDisplayItem(view, gl, displayItem, textureToUse, PASS_SELECTION_LABEL, null, 0);画

选中标记的    

6.   drawDisplayItem(view, gl, displayItem, videoTexture, PASS_VIDEO_LABEL, null, 0);画视频

标记的    

7.   drawDisplayItem(view, gl, displayItem, locationTexture, PASS_LOCATION_LABEL, null, 0);

画位置标记的    

8.   drawDisplayItem(view, gl, displayItem, locationTexture, PASS_MEDIASET_SOURCE_LABEL

,transparentTexture, 0.85f);画源来源图标的(相机或一般文件夹)  

 

 

二、特效

举如何显示一张图片为例,在图片完全显示出来经过这样一个过程,附近的图片

渐小渐出,当前图片渐大渐入,当前图片逐渐变大直到全屏。实现这个特效,要

进行很多帧的渲染。就是说并不是只调一次 onDrawFrame 函数就可以了,要调用

多次。可以把这个特效的实现想成一个状态变化的过程,在每一个状态,纹理的

显示大小和位置都不同,这也符合动画的基本原理。放大、缩小我们只要改变顶

点数据就可以做到,gallery3d 也是这样做的,下面是主要代码:

我们知道调用 onDrawFrame 来渲染,最后调到下面的 drawFocusItems 函数,

Java 代码       

1.   GridQuad quad = GridDrawables.sFullscreenGrid[vboIndex];    

2.   float u = texture.getNormalizedWidth();    

3.   float v = texture.getNormalizedHeight();    

4.   float imageWidth = texture.getWidth();    

5.   float imageHeight = texture.getHeight();    

6.   boolean portrait = ((theta / 90) % 2 == 1);    

7.   if (portrait) {    

8.           viewAspect = 1.0f / viewAspect;    

9.   }    

10.  quad.resizeQuad(viewAspect, u, v, imageWidth, imageHeight);//改变用来贴图片的长方

形的大小    

11.  quad.bindArrays(gl);//绑定新数据,为渲染做准备。  

 

而位置的改变有两种方式,一种是直接以顶点数据中改变,另一种是计算出在 3

维 3 个方向的偏移量,再调用 gltranslate 来做,从代码可以看出采用的是第二

种方式来做的,比第一种方式更方便一些。代码:

Java 代码       

1.   gl.glTranslatef(-translateXf, -translateYf, -translateZf);  

 

而这里的3个偏移量的计算是和camera相关的,相关文件为GridCamera.java,

GridCameraManager.java,过程很复杂,理清楚后再细化吧。

 

cache 管理

下面是 cache 文件

Java 代码       

1.   /sdcard/Android/data/com.cooliris.media/cache/local-album-cache    

2.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-album-cache    

3.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-meta-cache    

4.   ----rwxr-x system   sdcard_rw   299877 2010-05-28 07:36 local-album-cachechunk_0    

5.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 geocoder-cache    

6.   ----rwxr-x system   sdcard_rw      284 2010-05-28 07:36 local-album-cacheindex    

7.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-image-thumbs    

8.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 local-video-thumbs    

9.   d---rwxr-x system   sdcard_rw          2010-05-21 09:56 picasa-thumbs    

10.  ----rwxr-x system   sdcard_rw       80 2010-05-28 07:36 local-meta-cachechunk_0    

11.  ----rwxr-x system   sdcard_rw      164 2010-05-28 07:36 local-meta-cacheindex    

12.  d---rwxr-x system   sdcard_rw          2010-05-21 09:56 hires-image-cache    

13.  ----rwxr-x system   sdcard_rw   627629 2010-05-28 07:37 local-image-thumbschunk_0    

14.  ----rwxr-x system   sdcard_rw     3914 2010-05-21 09:56 local-image-thumbsindex    

15.  ----rwxr-x system   sdcard_rw    53343 2010-05-28 07:34 hires-image-cache-4982941342

287215583_1024.cache    

16.  ----rwxr-x system   sdcard_rw   237692 2010-05-28 07:33 hires-image-cache36845684843

69117627_1024.cache    

17.  ----rwxr-x system   sdcard_rw   133182 2010-05-28 07:34 hires-image-cache60754254408

1226432_1024.cache    

18.  ----rwxr-x system   sdcard_rw    83223 2010-05-28 07:34 hires-image-cache42754796232

10216146_1024.cache    

19.  ----rwxr-x system   sdcard_rw   292837 2010-05-28 07:34 hires-image-cache-6463165569

36433937_1024.cache    

20.  ----rwxr-x system   sdcard_rw   191377 2010-05-28 07:35 hires-image-cache26313646045

09958174_1024.cache    

21.  ----rwxr-x system   sdcard_rw   366905 2010-05-28 07:35 hires-image-cache-3280562009

766080884_1024.cache    

22.  ----rwxr-x system   sdcard_rw   323671 2010-05-28 07:35 hires-image-cache57524718275

33329222_1024.cache  

 

创建 cache 的关键代码

Java 代码       

1.   LocalDataSource    

2.   public static final DiskCache sThumbnailCache = new DiskCache("local-image-thumbs");--

--------------------local-image-thumbs local-image-thumbschunk_0  local-image-thumbsind

ex    

3.   public static final DiskCache sThumbnailCacheVideo = new DiskCache("local-video-thum

bs");--------------------local-video-thumbs    

4.   public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");---------

-------------local-album-cache  local-album-cacheindex    

5.   public static final DiskCache sMetaAlbumCache = new DiskCache("local-meta-cache");----

--------------local-meta-cache  local-meta-cacheindex    

6.   getChunkFile --------------local-meta-cachechunk_0  local-album-cachechunk_0    

7.     

8.   ReverseGeocoder::  private static final DiskCache sGeoCache = new DiskCache("geocoder

-cache"); -------------------------geocoder-cache    

9.   PicasaDataSource:: public static final DiskCache sThumbnailCache = new DiskCache("pica

sa-thumbs");-----------------------------picasa-thumbs    

10.  UriTexture::writeToCache  --------------------------hires-image-cache-xxx_1024.cache  

 

布局补充:

在画一个界面是,是分类化的,比如第一个界面是显示所有有图片的文件夹,在代

码里叫专辑.有这些元素要创建:

文本标签   显示专辑名和专辑内图片或视频数

路径条 显示路径名

按纽 拍照按纽,放大/缩小

菜单栏全选,取消全选,分享,删除,更多等

图片边框

用于显示图片的矩形

在渲染时一次把一类元素画完,再画另一类.如主界面顺序为:

路径条->按纽->文本标签->图片边框->图片.

具体代码见 drawBlendedComponents 函数

  

  

1.CacheService.java     中 写 缓 存 :      sAlbumCache.put(ALBUM_CACHE_LOCALE_INDEX,

sDummyData, 0);  

   第一个是  key  ,这里是正常数据,当然还有别的  key  ,  key  分别是  -1,-2,-3,-4,-5  。  

2.DiskCache.java  中,执行上面的写的过程,这里先得明白他的  cache  怎么装的:  

     它是由很多称之为“片”的文件组成的,形成一个  List  形式:  private final  

 

LongSparseArray  mChunkFiles  =  new

LongSparseArray();  

即  mChuckFiles  就是整个  cache  ,里面包括很多  chunk(  即片  )  ,每一个  chunk  大小为

1MB.  

当要写入某一个   chunk   里面的时候,先要找到他在   mChuckFiles   里面的索引值即

chunkIndex,  由  

 

mChunkFiles.get(chunkIndex);  来获取这个文件,  chunkIndex  怎么来的呢?  

private LongSparseArray mIndexMap;  

Record record = mIndexMap.get(key);  这里的  key  就是上面用  put  方法传过来的  

 

ALBUM_CACHE_LOCALE_INDEX  的值(就是  -5  )  

int chunkIndex = record.chunk;  

这么一步步来的。  

当然了,第一次都是空的,也就是  get  不到东西  mChunkFiles.get(chunkIndex);  和  Record

record =  

 

mIndexMap.get(key);  都  get  不到,那么第一次就先把东西放进去,  mIndexMap.put(key, new

Record  

 

(chunkIndex,  record.offset,  data.length,  record.sizeOnDisk,  timestamp));  (记录  key  值)以及

final  

 

String chunkFilePath = mCacheDirectoryPath + CHUNK_FILE_PREFIX + chunk; chunkFile = new  

 

RandomAccessFile(chunkFilePath, "rw");mChunkFiles.put(chunk, chunkFile);  (三句代码来新建

一个  

 

chunkfile  并放到  cache  列表里面)  

   

注意:  Record  是内部类,只是一个数据集合类而已,相当于文件描述信息。每个  cache (即

chunk  )对应一个。  

private           final           LongSparseArray           mChunkFiles           =           new

LongSparseArray();  中  mChunkFiles  最大装  13  个,每个  chunk  是  1M,

所以全部  Cache  是  13M.  

Gallery3d 代码分析之渲染流程

文章分类:移动开发  

RenderView  

 

gallery3d  的渲染从  RenderView  开始。RenderView  从  GLSurfaceView  继承而来,采用了通

知型绘制模式,即通过调用  requestRender  通知  RenderView  重绘屏幕。  

 

RenderView  将所有需要绘制的对象都保存一个  Lists 中,Lists  包含了 5 个 ArrayList,其定义

如下所示:  

Java 代码       

1.   public final ArrayList updateList = new ArrayList();    

2.   public final ArrayList opaqueList = new ArrayList();    

3.   public final ArrayList blendedList = new ArrayList();    

4.   public final ArrayList hitTestList = new ArrayList();    

5.   public final ArrayList systemList = new ArrayList();  

 

 

 

RenderView  的  onDrawFrame  接口完成每一帧的绘制操作,绘制时遍历  lists  里每个  list  的

每一个成员并调用其  renderXXX  函数。主要代码如下所示:  

Java 代码       

1.   ...    

2.   final Lists lists = sLists;    

3.     

4.   final ArrayList updateList = lists.updateList;    

5.   boolean isDirty = false;    

6.   for (int i = 0, size = updateList.size(); i != size; ++i) {    

7.       boolean retVal = updateList.get(i).update(this, mFrameInterval);    

8.       isDirty |= retVal;    

9.   }    

10.  if (isDirty) {    

11.      requestRender();    

12.  }    

13.    

14.  // Clear the depth buffer.    

15.  gl.glClear(GL11.GL_DEPTH_BUFFER_BIT);    

16.  gl.glEnable(GL11.GL_SCISSOR_TEST);    

17.  gl.glScissor(0, 0, getWidth(), getHeight());    

18.    

19.  // Run the opaque pass.    

20.  gl.glDisable(GL11.GL_BLEND);    

21.  final ArrayList opaqueList = lists.opaqueList;    

22.  for (int i = opaqueList.size() - 1; i >= 0; --i) {    

23.      final Layer layer = opaqueList.get(i);    

24.      if (!layer.mHidden) {    

25.          layer.renderOpaque(this, gl);    

26.      }    

27.  }    

28.    

29.  // Run the blended pass.    

30.  gl.glEnable(GL11.GL_BLEND);    

31.  final ArrayList blendedList = lists.blendedList;    

32.  for (int i = 0, size = blendedList.size(); i != size; ++i) {    

33.      final Layer layer = blendedList.get(i);    

34.      if (!layer.mHidden) {    

35.          layer.renderBlended(this, gl);    

36.      }    

37.  }    

38.  gl.glDisable(GL11.GL_BLEND);  

 

 

 

lists  的各个  list  里包含的各个  layer  如下所示:  

Java 代码       

1.   lists    

2.     |------------------|-----------------|-----------------|---------------|    

3.   updateList        opaqueList        blendedList      systemList     hitTestList    

4.     |                  |                 |                 |            |    

5.   GridLayer         GridLayer         GridLayer        GridLayer      GridLayer    

6.   BackgroudLayer    BackgroudLayer    BackgroudLayer    

7.   HudLayer           HudLayer         HudLayer                        HudLayer    

8.   TimeBar                             TimeBar                         TimeBar    

9.   PathBar                             PathBar                         PathBar    

10.  XXXButton                           XXXButton                       XXXButton    

11.  XXXMenu                             XXXMenu                         XXXMenu  

 

 

 

 

Layer  类提供了  update(...), renderOpaque (...), renderBlended (...)  接口,从上面  RenderView

的  onDrawFrame  绘制代码可以看到,这些接口被调用。  

Java 代码       

1.   public abstract class Layer {    

2.       ... ...    

3.     

4.       public abstract void generate(RenderView view, RenderView.Lists lists);    

5.     

6.       public boolean update(RenderView view, float frameInterval) {    

7.           return false;    

8.       }    

9.     

10.      public void renderOpaque(RenderView view, GL11 gl) {    

11.      }    

12.    

13.      public void renderBlended(RenderView view, GL11 gl) {    

14.      }    

15.      ... ...    

16.    

17.  }  

 

 

 

GridLayer  

 

GridLayer  中有个  GridDrawManager,专门负责绘制。  

 

下面是  GridDrawManager  的构造函数,从其参数里可以看出些门道。  

Java 代码       

1.   mDrawManager = new GridDrawManager(context, mCamera, mDrawables, sDisplayList,

sDisplayItems, sDisplaySlots);  

Gallery 3D 代码分析之 GLSurfaceView

文章分类:移动开发  

简介  

 

SDK  中的  android.opengl.GLSurfaceView  类提供如下功能:  

·           在  OpenGL ES  和  View  系统之间建立联系;  

·           使得  OpenGL ES  可以工作在  Activity  生命周期中;  

·           可选择合适的  frame buffer  像素格式;  

·           创建并管理一个单独的渲染线程,可以实现平滑的动画;  

·           提供  debugging  工具和  API。  

 

 

一个简单的  GLSurfaceView  应用  

Java 代码       

1.   package com.example.android.apis.graphics;    

2.     

3.   import javax.microedition.khronos.egl.EGLConfig;    

4.   import javax.microedition.khronos.opengles.GL10;    

5.     

6.   import android.app.Activity;    

7.   import android.opengl.GLSurfaceView;    

8.   import android.os.Bundle;    

9.     

10.  public class ClearActivity extends Activity {    

11.      @Override  

12.      protected void onCreate(Bundle savedInstanceState) {    

13.          super.onCreate(savedInstanceState);    

14.          mGLView = new GLSurfaceView(this);    

15.          mGLView.setRenderer(new ClearRenderer());    

16.          setContentView(mGLView);    

17.      }    

18.    

19.      @Override  

20.      protected void onPause() {    

21.          super.onPause();    

22.          mGLView.onPause();    

23.      }    

24.    

25.      @Override  

26.      protected void onResume() {    

27.          super.onResume();    

28.          mGLView.onResume();    

29.      }    

30.    

31.      private GLSurfaceView mGLView;    

32.  }    

33.    

34.  class ClearRenderer implements GLSurfaceView.Renderer {    

35.      public void onSurfaceCreated(GL10 gl, EGLConfig config) {    

36.          // Do nothing special.    

37.      }    

38.    

39.      public void onSurfaceChanged(GL10 gl, int w, int h) {    

40.          gl.glViewport(0, 0, w, h);    

41.      }    

42.    

43.      public void onDrawFrame(GL10 gl) {    

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

45.      }    

46.  }  

 

这个程序功能很简单,每帧绘制时将屏幕设置成黑色。但它是一个完整的工作在  Activity  生

命周期中的  OpenGL  程序。当  activity  暂停时,它暂停渲染;当  activity  继续时,它继续

渲染。可以将这个程序用作非交互式的  demo  程序。可以在  ClearRenderer.onDrawFrame()

接口中增加  OpenGL  调用做很多的绘制。  

 

GLSurfaceView.Render  接口有三个方法:  

 

     * onSurfaceCreated():该方法在渲染开始前调用,OpenGL ES  的绘制上下文被重建时也会被

调用。当  activity  暂停时绘制上下文会丢失,当  activity  继续时,绘制上下文会被重建。另

外,创建长期存在的  OpenGL  资源(如  texture)往往也在这里进行。  

     *  onSurfaceChanged():当  surface  的尺寸发生改变时该方法被调用。往往在这里设置

viewport。若你的  camera  是固定的,也可以在这里设置  camera。  

     *  onDrawFrame():每帧都通过该方法进行绘制。绘制时通常先调用  glClear  函数来清空

framebuffer,然后在调用  OpenGL ES  的起它的接口进行绘制。  

 

输入如何处理  

 

若是开发一个交互型的应用(如游戏),通常需要子类化  GLSurfaceView,由此可以获取输入

事件。下面有个例子:  

Java 代码       

1.   package com.google.android.ClearTest;    

2.     

3.   import javax.microedition.khronos.egl.EGLConfig;    

4.   import javax.microedition.khronos.opengles.GL10;    

5.     

6.   import android.app.Activity;    

7.   import android.content.Context;    

8.   import android.opengl.GLSurfaceView;    

9.   import android.os.Bundle;    

10.  import android.view.MotionEvent;    

11.    

12.  public class ClearActivity extends Activity {    

13.      @Override  

14.      protected void onCreate(Bundle savedInstanceState) {    

15.          super.onCreate(savedInstanceState);    

16.          mGLView = new ClearGLSurfaceView(this);    

17.          setContentView(mGLView);    

18.      }    

19.    

20.      @Override  

21.      protected void onPause() {    

22.          super.onPause();    

23.          mGLView.onPause();    

24.      }    

25.    

26.      @Override  

27.      protected void onResume() {    

28.          super.onResume();    

29.          mGLView.onResume();    

30.      }    

31.    

32.      private GLSurfaceView mGLView;    

33.  }    

34.    

35.  class ClearGLSurfaceView extends GLSurfaceView {    

36.      public ClearGLSurfaceView(Context context) {    

37.          super(context);    

38.          mRenderer = new ClearRenderer();    

39.          setRenderer(mRenderer);    

40.      }    

41.    

42.      public boolean onTouchEvent(final MotionEvent event) {    

43.          queueEvent(new Runnable(){    

44.              public void run() {    

45.                  mRenderer.setColor(event.getX() / getWidth(),    

46.                          event.getY() / getHeight(), 1.0f);    

47.              }});    

48.              return true;    

49.          }    

50.    

51.          ClearRenderer mRenderer;    

52.  }    

53.    

54.  class ClearRenderer implements GLSurfaceView.Renderer {    

55.      public void onSurfaceCreated(GL10 gl, EGLConfig config) {    

56.          // Do nothing special.    

57.      }    

58.    

59.      public void onSurfaceChanged(GL10 gl, int w, int h) {    

60.          gl.glViewport(0, 0, w, h);    

61.      }    

62.    

63.      public void onDrawFrame(GL10 gl) {    

64.          gl.glClearColor(mRed, mGreen, mBlue, 1.0f);    

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

66.      }    

67.    

68.      public void setColor(float r, float g, float b) {    

69.          mRed = r;    

70.          mGreen = g;    

71.          mBlue = b;    

72.      }    

73.    

74.      private float mRed;    

75.      private float mGreen;    

76.      private float mBlue;    

77.  }  

 

其他的  GLSurfaceView  例子  

 

在  Android SDK  的  API Demo 例子程序中还有很多例子:  

·           GLSurfaceView  

·           Kube  

·           Translucent GLSurfaceView:透明背景  

·           Textured Triangle:纹理贴图  

·           Sprite Text:在  texture  上写文本并显示在  3D  场景中  

·           Touch Rotate:旋转  3D  对象  

 

 

选择一个  Surface  

 

GLSurfaceView  提供了接口可选择  surface  的类型。默认情况下,  GLSurfaceView  会使用一

个  16  位  RGB  frame  buffer,带  16  位深度。你也可以根据自己的需要进行选择,比如在

Translucent GLSurfaceView  例子里,需要一个  Alpha  通道来实现透明。GLSurfaceView  提供

了  setEGLSurfaceChooser()方法来选择  surface。  

 

选择一个  RGB (565)的 16 位  framebuffer,接口如下:  

Java 代码       

1.   setEGLConfigChooser(boolean needDepth)  

 

 

若要定制  red, green, blue, alpha  和  depth,则用如下接口:  

Java 代码       

1.   setEGLConfigChooser(int redSize, int greenSize,int blueSize, int alphaSize,int depthSize, in

t stencilSize)  

 

 

使用自己实现的  EGLConfigChooser,用如下的接口:  

Java 代码       

1.   setEGLConfigChooser(EGLConfigChooser configChooser)  

 

 

持续型渲染模式  &  通知型渲染模式  

 

大多数  3D  应用,如游戏、模拟等都是持续型渲染的动画,还有些  3D  应用是反应式的

(reactive),它们往往先被动等待,当用户有了动作再做出反应。对于这种应用,持续渲染屏

幕是浪费时间。若开发反应式的应用,可以调用下面的方法  

Java 代码       

1.   GLSurfaceView.setRenderMode(RENDERMODE_WHEN_DIRTY);  

 

 

停止持续渲染。当调用  

Java 代码       

1.   GLSurfaceView.requestRender() 

时,程序再渲染屏幕。  

调试  

 

GLSurfaceView.setDebugFlags()  方法可以激活  log  或者错误检测,它们可以帮助调试

OpenGL  ES  调用。具体使用时,在  GLSurfaceView  的构造函数中,调用  setRender()  之前

调用  GLSurfaceView.setDebugFlags()就可以了。下面是个例子:  

Java 代码       

1.   public ClearGLSurfaceView(Context context) {    

2.       super(context);    

3.       // Turn on error-checking and logging    

4.       setDebugFlags(DEBUG_CHECK_GL_ERROR | DEBUG_LOG_GL_CALLS);    

5.       mRenderer = new ClearRenderer();    

6.       setRenderer(mRenderer);    

7.   }  

http://wenku.baidu.com/view/57d01ec1bb4cf7ec4afed0ec.html

你可能感兴趣的:(Android应用开发)