前言-
明确了项目目录的结构,但是结构什么的也太"抽象"了。
本篇开始上代码!
模型的绘制-
前几天的学习中,live2d的绘制有了一些了解了,在Android端使用OpenGL ES绘制模型时需要Surface绘制和Renderer渲染,那么切入点就为GLSurfaceView和Renderer。
在SampleApp1中的sample包下LAppView和LAppRenderer就分别饰演的这两个角色
LAppRenderer implements GLSurfaceView.Renderer LAppView extends GLSurfaceView
渲染器类LAppRenderer -
LAppRenderer 类实现了Renderer接口,实现了onSurfaceCreated、onSurfaceChanged、onDrawFrame方法
@Override public void onSurfaceCreated(GL10 context, EGLConfig arg1) { setupBackground(context); } //设置背景图片 private void setupBackground(GL10 context) { try { InputStream in = FileManager.open(LAppDefine.BACK_IMAGE_NAME); bg=new SimpleImage(context,in); bg.setDrawRect( LAppDefine.VIEW_LOGICAL_MAX_LEFT, LAppDefine.VIEW_LOGICAL_MAX_RIGHT, LAppDefine.VIEW_LOGICAL_MAX_BOTTOM, LAppDefine.VIEW_LOGICAL_MAX_TOP); bg.setUVRect(0.0f,1.0f,0.0f,1.0f); } catch (IOException e) { e.printStackTrace(); } }
onSurfaceCreated()作为surface被创建后需要做的处理,但是这里只加载了背景图片
在onDrawFrame()方法中有很多的OpenGL绘制时的配置,由于LAppLive2DManager和Utils的存在很多操作都不在这里实现了,这里还是很明显的绘制出了background和models,方法还是熟悉的方法,只是藏了起来
if(bg!=null){ gl.glPushMatrix() ; { float SCALE_X = 0.25f ; float SCALE_Y = 0.1f ; gl.glTranslatef( -SCALE_X * accelX , SCALE_Y * accelY , 0 ) ; bg.draw(gl); } gl.glPopMatrix() ; } for(int i=0;i<delegate.getModelNum();i++) { LAppModel model = delegate.getModel(i); if(model.isInitialized() && ! model.isUpdating()) { model.update(); model.draw(gl); } }
而onSurfaceChanged方法的实现就非常interesting了,因为在Manager中也有一个同样的方法
而且在onSurfaceChanged()的第一行就调用了此方法
1 //LAppLive2DManager 2 3 public void onSurfaceChanged(GL10 gl, int width, int height){ 4 if(LAppDefine.DEBUG_LOG)Log.d(TAG, "onSurfaceChanged "+width+" "+height); 5 view.setupView(width,height); 6 7 if(getModelNum()==0){ 8 changeModel(); 9 } 10 }
***这是为了实现点击左下角按钮更换模型这个功能的,当没有模型的时候会把一个reloadFlg的Flag置为true,通过点击事件达到模型的更换。
同样的onSurfaceChanged中也存在着大量的OpenGL的配置,在最后的最后有这麽一行代码
OffscreenImage.createFrameBuffer(gl, width ,height, 0);
这里挖一个小小的坑,我查了半天说是离屏渲染(OffScreen Renderer),同样也单独存在OffscreenImage来实现此功能,但是我还没有搞懂
与这个相同的还有一个setAccel()方法的作用没有弄明白
=====================================================================================================================================================================================================
绘制类LAppView -
这是LAppView类的类图
相信从上图中可以看出很多属性和方法都是干什么的比如:
-GestureDetector gestureDetector是Android中的手势动作
-onTouchEvent() 则是触摸事件,还有很多的Began啊、Moved啊和utils中的TouchManage共同来获得触摸的点
而上面把Renderer写好了,但是还记得Renderer怎么画到Surface上面么?没错是setRenderer( renderer ) !这一行代码躺在setLive2DManager()方法中
1 public void setLive2DManager( LAppLive2DManager live2DMgr){ 2 this.delegate = live2DMgr ; 3 this.renderer = new LAppRenderer( live2DMgr ) ; 4 5 setRenderer(renderer); 6 7 gestureDetector = new GestureDetector(this.getContext() , simpleOnGestureListener ) ; 8 9 10 11 deviceToScreen=new L2DMatrix44(); 12 13 14 viewMatrix=new L2DViewMatrix(); 15 16 17 viewMatrix.setMaxScale( LAppDefine.VIEW_MAX_SCALE ); 18 viewMatrix.setMinScale( LAppDefine.VIEW_MIN_SCALE ); 19 20 21 22 viewMatrix.setMaxScreenRect( 23 LAppDefine.VIEW_LOGICAL_MAX_LEFT, 24 LAppDefine.VIEW_LOGICAL_MAX_RIGHT, 25 LAppDefine.VIEW_LOGICAL_MAX_BOTTOM, 26 LAppDefine.VIEW_LOGICAL_MAX_TOP 27 ); 28 29 30 touchMgr=new TouchManager(); 31 32 dragMgr = new L2DTargetPoint(); 33 }
其中为手势gestureDetector绑定了一个监听器simpleOnGestureListener
-setupView()则是一些数值的运算,尤其是那个ratio是不是感觉很熟悉,熟悉去看simple项目的onSurfaceChanged方法中glOrthof第三个参数