`
cev773wq
  • 浏览: 14944 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

Android中的3D相册

 
阅读更多

Android中的3D相册
2011年11月28日
      最近学习,工作走很忙,空闲之余,我还学习了一下Android编程和Android上的一些好玩的东西。
  这几天,我做了一个Android的3D相册,简单但是听好玩的,算是学习吧。也借鉴了一些别人的东西。这个相册的开发过程中,我用到了OpenGL ES中的图形绘制技术,包括纹理映射技术、物体旋转技术glRotatef()、物体平移技术glTranslatef(),并且用到了屏幕触控技术。
  下图是3D相册的效果图,通过滑动手机屏幕可以改变照片呈现的角度。
  
  
  
  通过单击操作来查看相册中的某张图片,按返回键会返回相册显示。
  3D相册的具体代码已上传到日志,感兴趣的可以查看,有什么不足和待改进的地方请大神们指教。
  界面实现类MySufaceView中的代码如下:
  package com.bn.ex11f;
  import java.io.IOException;
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Collections;
  import android.opengl.GLSurfaceView;
  import android.opengl.GLUtils;
  import android.view.KeyEvent;
  import android.view.MotionEvent;
  import javax.microedition.khronos.egl.EGLConfig;
  import javax.microedition.khronos.opengles.GL10;
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import static com.bn.ex11f.Constant.*;
  class MySurfaceView extends GLSurfaceView
  {
  public float screenWidth;//屏幕宽带
  public float screenHeight;//屏幕高度
  public float ratio;//屏幕宽高比
  private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度缩放比例
  private SceneRenderer mRenderer;//场景渲染器
  float mPreviousX;//上次按下位置x坐标
  float mPreviousY;//上次按下位置y坐标
  long previousTime;//上次按下的时间
  boolean isCheck=false;//是否点击查看图片
  boolean isMove=false;
  int[] textureIds=new int[PHOTO_COUNT];//n张照片纹理id数组
  float yAngle=0;//总场景旋转角度
  int currIndex=0;//当前选中的索引
  float yAngleV=0;//总场景角度变化速度
  public MySurfaceView(Context context) {
  super(context);
  mRenderer = new SceneRenderer(); //创建场景渲染器
  setRenderer(mRenderer);    //设置渲染器 
  setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染  
  //启动一个线程根据当前的角速度旋转场景
  threadWork=true;
  new Thread()
  {
  public void run()
  {
  while(threadWork)
  {
  if(Float.isNaN(yAngle)||Float.isNaN(yAngleV))
  {
  throw new RuntimeException("yangle "+yAngle+"yAngleV="+yAngleV);
  }
  //根据角速度计算新的场景旋转角度
  yAngle+=yAngleV;
  if(Float.isNaN(yAngle))
  {
  throw new RuntimeException("yangle"+yAngle);
  }
  //将角度规格化到0~360之间
  yAngle=(yAngle+360)%360;
  if(Float.isNaN(yAngle)||Float.isNaN(yAngleV))
  {
  throw new RuntimeException("yangle "+yAngle+"yAngleV="+yAngleV);
  }
  //若当前手指已经抬起则角速度衰减
  if(!isMove)
  {
  yAngleV=yAngleV*0.7f;
  }
  //若 角速度小于阈值则归0
  if(Math.abs(yAngleV)5||Math.abs(dy)>5)
  {//触控位移大于阈值则进入移动状态
  isMove=true;
  }           
  if(isMove)
  {//若在移动状态则计算角度变化速度
  if(timeSpan!=0)
  {
  yAngleV=dx * TOUCH_SCALE_FACTOR/timeSpan;   
  }                       
  }           
  break;
  case MotionEvent.ACTION_UP:
  //若在非移动状态且角度速度为0则看选中的是哪幅照片来显示
  if(!isMove&&yAngleV==0)
  {  
  //折算出触控点在NEAR面上的位置
  float nearX=(x-screenWidth/2)*ratio/(screenWidth/2);
  float nearY=(screenHeight/2-y)/(screenHeight/2);
  //先判断点下去的是左边还是右边
  if(x>screenWidth/2)
  {//右边
  ArrayList al=new ArrayList();
  for(int i=0;i270&&tempAngle al=new ArrayList();
  for(int i=0;i180&&tempAngle纹理矩形   
  @Override
  public void onDrawFrame(GL10 gl)
  {
  //清除颜色缓存于深度缓存
  gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  //设置当前矩阵为模式矩阵
  gl.glMatrixMode(GL10.GL_MODELVIEW);
  //设置当前矩阵为单位矩阵
  gl.glLoadIdentity();   
  if(isCheck)
  {
  //显示某一幅照片,detail状态
  gl.glPushMatrix();
  gl.glTranslatef(0, 0f, -52f);
  gl.glTranslatef(-Board.length-Board.width*0.5f, 0, 0);
  tp.drawSelf(gl,textureIds[currIndex]);
  gl.glPopMatrix(); 
  }
  else
  {
  //显示照片组,可触控旋转选择
  gl.glPushMatrix();
  gl.glTranslatef(0, 0f, CENTER_Z); 
  yAngle=yAngle%360;
  gl.glRotatef(yAngle, 0, 1, 0);
  for(int i=0;i纹理数组,显示每幅照片
  gl.glPushMatrix();
  gl.glRotatef(i*PHOTO_ANGLE_SPAN, 0, 1, 0);
  tp.drawSelf(gl,textureIds);
  gl.glPopMatrix();
  }
  gl.glPopMatrix();
  }
  }
  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
  //设置视窗大小及位置
  gl.glViewport(0, 0, width, height);
  //设置当前矩阵为投影矩阵
  gl.glMatrixMode(GL10.GL_PROJECTION);
  //设置当前矩阵为单位矩阵
  gl.glLoadIdentity();
  //调用此方法计算产生透视投影矩阵
  gl.glFrustumf(-ratio, ratio, -1, 1, NEAR, 100);
  //设置为关闭背面剪裁
  gl.glDisable(GL10.GL_CULL_FACE);
  }
  @Override
  public void onSurfaceCreated(GL10 gl, EGLConfig config)
  {                 
  //关闭抗抖动
  gl.glDisable(GL10.GL_DITHER);
  //设置特定Hint项目的模式,这里为设置为使用快速模式
  gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
  //设置屏幕背景色黑色RGBA
  gl.glClearColor(0,0,0,0);           
  //启用深度测试
  gl.glEnable(GL10.GL_DEPTH_TEST);
  //加载n幅纹理图
  textureIds[0]=initTexture(gl,R.drawable.fj1);//图片1
  textureIds[1]=initTexture(gl,R.drawable.fj2);//图片2
  textureIds[2]=initTexture(gl,R.drawable.fj3);//图片3
  textureIds[3]=initTexture(gl,R.drawable.fj4);//图片4
  textureIds[4]=initTexture(gl,R.drawable.fj5);//图片5
  textureIds[5]=initTexture(gl,R.drawable.fj6);//图片6
  textureIds[6]=initTexture(gl,R.drawable.fj7);//图片7
  textureIds[7]=initTexture(gl,R.drawable.fj8);//图片8
  textureIds[8]=initTexture(gl,R.drawable.fj9);//图片9
  textureIds[9]=initTexture(gl,R.drawable.fj10);//图片10
  textureIds[10]=initTexture(gl,R.drawable.fj11);//图片11
  textureIds[11]=initTexture(gl,R.drawable.fj12);//图片12
  textureIds[12]=initTexture(gl,R.drawable.fj13);//图片13
  textureIds[13]=initTexture(gl,R.drawable.fj14);//图片14
  }
  }
  //初始化纹理
  public int initTexture(GL10 gl,int drawableId)//textureId
  {
  //生成纹理ID
  int[] textures = new int[1];
  gl.glGenTextures(1, textures, 0);   
  int currTextureId=textures[0];   
  gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_CLAMP_TO_EDGE);
  gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_CLAMP_TO_EDGE);       
  InputStream is = this.getResources().openRawResource(drawableId);
  Bitmap bitmapTmp;
  try
  {
  bitmapTmp = BitmapFactory.decodeStream(is);
  }
  finally
  {
  try
  {
  is.close();
  }
  catch(IOException e)
  {
  e.printStackTrace();
  }
  }
  GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0);
  bitmapTmp.recycle();
  return currTextureId;
  }
  }
  其中,public MySurfaceView (Context context) {    }是界面类的构造部分,设置渲染器对象,根据当前的角度旋转场景的线程。
分享到:
评论

相关推荐

    Android项目3D相册.rar

    在3D相册中,开发者可能编写了自定义的着色器来实现独特的光照、纹理映射和3D变换效果。 5. **Android资源管理**:项目中会涉及到Android的资源管理,包括图片资源的加载、解码和优化,以适应不同设备的性能需求。...

    android相册3D源码

    3D相册的核心在于利用OpenGL ES(OpenGL for Embedded Systems),这是Android系统中的一个图形库,用于处理2D和3D图形。通过OpenGL ES,开发者可以创建复杂的3D场景,包括旋转、缩放和平移等效果,将图片以立体的...

    android 3D旋转相册

    在构建3D相册时,我们需要用到OpenGL ES来绘制和操纵3D物体,如图片卡片。理解顶点坐标、纹理映射以及着色器语言(GLSL)是必要的。 2. **Matrix和MatrixStack**:Android的`android.graphics.Matrix`类提供了2D和...

    Android应用源码3D相册.zip

    《Android应用源码3D相册》是一款基于Android平台的3D效果相册应用程序,它展示了如何在Android环境中实现复杂的视觉特效,同时提供了一个学习和借鉴的实例。本项目源码主要采用Java语言编写,是Android开发者提升...

    android 3d相册代码

    android 3d grally的代码,实现3D相册功能

    Android 3D相册图片滑动倾斜放大倒影处理源码

    "Android 3D相册图片滑动+倾斜+放大+倒影处理源码"是一个专门针对这一需求的解决方案,它提供了丰富的3D效果,使得用户在浏览相册时能感受到更加生动、立体的视觉体验。 首先,我们要理解3D相册的核心概念。在...

    android 3d相册源码

    在Android平台上,开发一款引人入胜的3D相册应用可以极大地提升用户体验。"android 3d相册"源码提供了一个实现此类功能的实例,对于开发者来说,这是一个宝贵的资源,可以用来学习如何在Android上创建具有立体视觉...

    超炫的android 3d相册

    超炫的android 3d相册

    android自定义3d画廊效果

    在这个案例中,开发者创建了一个继承自Android内置Gallery类的自定义View,以便添加3D旋转效果。 2. **矩阵运算**(Matrix):3D画廊的核心在于对图片进行3D旋转,这需要利用Android的Matrix类来完成。Matrix提供了...

    Android 3D特效相册+电子书翻页效果

    为了实现3D相册,你需要: 1. **数据结构与模型加载**:创建一个3D模型来表示相册,这可能涉及到将2D图片映射到3D表面上。使用例如Assimp库来导入3D模型或自己解析3D格式(如OBJ、3DS)。 2. **纹理映射**:将用户...

    android 3D相册完美实现

    本项目名为"android 3D相册完美实现",它展示了如何将普通的相册功能提升到一个新的维度,包括立体滑动和透明阴影等特效。 首先,3D相册的核心在于实现图片的三维旋转和平移。这通常涉及到Android的`ImageView`或...

    android 3D相册

    android 供学习 3D 相册开发

    Android 3D相册图片滑动+倾斜+放大+倒影处理源码-IT计算机-毕业设计.zip

    这篇文档将深入解析《Android 3D相册图片滑动+倾斜+放大+倒影处理源码》这一项目,这是一个适合计算机专业学生进行毕业设计学习的Android应用源码示例。我们将探讨其中的关键技术点,包括3D效果实现、图片滑动交互、...

    Android 3D选择相册

    通过OpenGL ES,开发者可以创建复杂的3D模型,实现旋转、缩放、平移等交互操作,使相册中的图片能够在3D空间中自由移动和展示。 其次,"verticalCarousel"这一文件名暗示了应用可能采用了一种垂直滚动的轮播样式。...

    Android应用源码3D相册 .zip

    【Android应用源码3D相册 .zip】这个压缩包文件提供了一个实现3D效果的Android相册应用的源代码,对于想要学习Android图形渲染、动画处理以及自定义控件开发的开发者来说,是一个非常有价值的参考资料。源码中的关键...

    Android 3D相册图片滑动+倾斜+放大+倒影处理源码.rar

    这个"Android 3D相册图片滑动+倾斜+放大+倒影处理源码"提供了实现此类高级视觉效果的方法。下面将详细探讨这个源码中的关键知识点。 1. **3D相册效果**:此源码实现了3D翻转效果,让用户在浏览相册时仿佛在操作真实...

    Android 3D相册图片滑动+倾斜+放大+倒影处理源码

    在Android开发中,创建一个具有视觉吸引力的3D相册是一项挑战,但通过巧妙地结合各种技术,可以实现像标题中描述的那样——3D相册图片滑动、倾斜、放大以及倒影处理。这个源码项目正是为了解决这个问题,提供了一种...

    Android 3d电子相册

    在本文中,我们将详细探讨该3D相册的实现原理,关键技术和设计模式,以及如何利用这些知识进行自己的项目开发。 1. **3D渲染技术** - OpenGL ES:Android系统中用于3D图形编程的主要API,是OpenGL的一个子集,专为...

Global site tag (gtag.js) - Google Analytics