android平台使用opengles2.0实现的翻书特效

  • Q0_710158
    了解作者
  • 5.3MB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-05-24 07:35
    上传日期
android平台利用opengles2.0技术实现的3D 翻书特效,带有完美阴影和光照技术;目前仅支持从右下角开始翻转,翻过一定角度松手后,自动翻转过去,否则的话,松手则还是翻回来;阴影是使用的阴影平面技术实现的,效果不错。
android平台使用opengles2.0实现的翻书特效.rar
内容介绍
package com.alex.Sample_PageTurning; import static com.alex.Sample_PageTurning.Constant.*; import java.io.IOException; import java.io.InputStream; import java.util.Currency; 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 android.graphics.PixelFormat; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.GLUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.util.Log; import android.view.MotionEvent; import com.alex.PageTurning.R; class MySurfaceView extends GLSurfaceView { PageRect pageRect = null; private SceneRenderer mRenderer;//场景渲染器 int[] textureIds =new int[TEXTURES_COUNT]; //系统分配的纹理id private HandlerThread ht = new HandlerThread("MyGLSurfaceView"); private Handler handler; private float ox,oy;//touch down坐标点 int touch_flag = 0; float newX,newY;//移动到新点的坐标 boolean bAllowTouch = true; //线程运行标志 public boolean threadFlag = true; public bg_view refBgView; //光源总变换矩阵 float[] mMVPMatrixGY; public MySurfaceView(Context context, bg_view bgView) { super(context); refBgView = bgView; //设置背景是否透明 this.setZOrderOnTop(true); this.setEGLConfigChooser(8, 8, 8, 8, 16, 0); this.getHolder().setFormat(PixelFormat.TRANSLUCENT); ht.start(); this.setEGLContextClientVersion(2); //设置使用OPENGL ES2.0 mRenderer = new SceneRenderer(); //创建场景渲染器 setRenderer(mRenderer); //设置渲染器 setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染 //setRenderMode(RENDERMODE_WHEN_DIRTY); handler = new Handler(ht.getLooper()) { public void handleMessage(Message msg) { mRenderer.startTurningAction(msg.what); } }; } //触摸事件回调方法 @Override public boolean onTouchEvent(MotionEvent e) { float x = e.getX(); float y = e.getY(); switch(e.getAction()) { case MotionEvent.ACTION_DOWN: touch_flag = 0; if(bAllowTouch) { if ((x >= allowX) && (y >= allowY)) { ox = x; oy = y; touch_flag = TOUCH_FLAG_DOWN; }else { Log.i(APP_TAG, "Invalid touch point: x= "+x+", y= "+y); } } break; case MotionEvent.ACTION_MOVE: if (TOUCH_FLAG_DOWN == (TOUCH_FLAG_DOWN & touch_flag)) { newX = x; newY = y; Message msg_move = handler.obtainMessage(MSG_TURNING_ACTION_MOVE); handler.sendMessage(msg_move); touch_flag = touch_flag | TOUCH_FLAG_MOVE; } break; case MotionEvent.ACTION_UP: if (TOUCH_FLAG_DOWN == (TOUCH_FLAG_DOWN & touch_flag)) { bAllowTouch = false; Message msg_up = handler.obtainMessage(MSG_TURNING_ACTION_UP); handler.sendMessage(msg_up); touch_flag = touch_flag | TOUCH_FLAG_UP; } break; } return true; } public int initTexture(int drawableID) { //生成纹理ID int[] textures = new int[1]; GLES20.glGenTextures ( 1, //产生的纹理id的数量 textures, //纹理id的数组 0 //偏移量 ); int textureId=textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE); //通过输入流加载图片===============begin=================== InputStream is = this.getResources().openRawResource(drawableID); Bitmap bitmapTmp; try { bitmapTmp = BitmapFactory.decodeStream(is); } finally { try { is.close(); } catch(IOException e) { e.printStackTrace(); } } //通过输入流加载图片===============end===================== //实际加载纹理 GLUtils.texImage2D ( GLES20.GL_TEXTURE_2D, //纹理类型,在OpenGL ES中必须为GL10.GL_TEXTURE_2D 0, //纹理的层次,0表示基本图像层,可以理解为直接贴图 bitmapTmp, //纹理图像 0 //纹理边框尺寸 ); bitmapTmp.recycle(); //纹理加载成功后释放图片 return textureId; } private class SceneRenderer implements GLSurfaceView.Renderer { public Object lock = new Object(); public float coneVertex = start_coneVertex; public float coneAngle = start_coneAngle;//90度表示是个平面,无任何卷起的角度; public int curTextureID = 0;//当前页的纹理图片 int drawableIDs[] = new int[] { R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e, }; int frameBufferId; int shadowId;// 动态产生的阴影纹理Id int renderDepthBufferId;// 动态产生的阴影纹理Id public void settingCameraAndProject(int project_type, float camera_x, float camera_y, float camera_z) { if (project_type == project_Ortho)//正交投影矩阵 { //调用此方法产生摄像机9参数位置矩阵 MatrixState.setCamera(camera_x,camera_y,camera_z,0f,0f,0f,0f,1.0f,0f); //调用此方法计算产生透视投影矩阵 float fScaleFactor = 2f; //MatrixState.setProjectOrtho(-NEAR_LEN, NEAR_LEN, -NEAR_LEN/ratio, NEAR_LEN/ratio, 1.0f, 10f); MatrixState.setProjectOrtho(0f, fScaleFactor*NEAR_LEN, 0f, fScaleFactor*NEAR_LEN/ratio, 1.0f, 20f); } else { //调用此方法产生摄像机9参数位置矩阵 float fScaleFactor = 2f; MatrixState.setCamera(0f,0f,2f,0f,0f,0f,0f,1.0f,0f); //MatrixState.setProjectFrustum(-NEAR_LEN/2, NEAR_LEN/2, -NEAR_LEN/2/ratio, NEAR_LEN/2/ratio, 1.0f, 20f); MatrixState.setProjectOrtho(0f, fScaleFactor*NEAR_LEN, 0f, fScaleFactor*NEAR_LEN/ratio, 1.0f, 20f); } } public void drawScene(GL10 gl) { //设置屏幕背景色RGBA GLES20.glClearColor(0.0f,0.0f,0.0f, 0.0f); //清除深度缓冲与颜色缓冲 GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); //设置镜头位置和投影矩阵 settingCameraAndProject(project_Ortho, camera_x,camera_y,camera_z); float iAlphoaValue = 1.0f; if (coneAngle < 90f) { //绘制阴影 MatrixState.setLightLocation(light1_x,light1_y,light1_z); MatrixState.pushMatrix(); pageRect.drawSelf(textureIds[curTextureID], coneVertex, coneAngle, iAlphoaValue, 1); MatrixState.popMatrix(); } //绘制自身 MatrixState.setLightLocation(light2_x,light2_y,light2_z); MatrixState.pushMatrix(); pageRect.drawSelf(textureIds[curTextureID], coneVertex, coneAngle, iAlphoaValue, 0); MatrixState.popMatrix(); } public void onDrawFrame(GL10 gl) { //Log.i(APP_TAG, "onDrawFrame: coneVertex = "+coneVertex+", coneAngle = "+coneAngle); //绘制真实场景 drawScene(gl); synchronized (lock) {
评论
    相关推荐