RiverRenderer.java :  » Image » floatingimage » dk » nindroid » rss » Android Open Source

Android Open Source » Image » floatingimage 
floatingimage » dk » nindroid » rss » RiverRenderer.java
package dk.nindroid.rss;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Intent;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.util.Log;
import android.view.Surface;
import dk.nindroid.rss.data.ImageReference;
import dk.nindroid.rss.gfx.Vec2f;
import dk.nindroid.rss.renderers.FeedProgress;
import dk.nindroid.rss.renderers.OSD;
import dk.nindroid.rss.renderers.Renderer;
import dk.nindroid.rss.renderers.floating.BackgroundPainter;
import dk.nindroid.rss.renderers.floating.GlowImage;
import dk.nindroid.rss.renderers.floating.ShadowPainter;

public class RiverRenderer implements GLSurfaceView.Renderer, dk.nindroid.rss.helpers.GLWallpaperService.Renderer {
  public Display      mDisplay;
  
  private boolean     mTranslucentBackground = false;
  private boolean      mMoveEventHandled = false;
  private TextureBank   mBank;
  private long      mUpTime;
  private Vec2f       mClickedPos = new Vec2f();
  private boolean     mClicked = false;
  private boolean     mShowOSD = false;
  private boolean     mHideOSD = false;
  private long       mOffset = 0;
  private float      mFadeOffset = 0;
  private static final float mSensitivityX = 70.0f;
  private final boolean   mLimitFramerate;
  
  private Renderer      mRenderer;
  private OSD        mOSD;
  private FeedProgress  mFeedProgress;
  MainActivity       mActivity;
  private long      mLastFrameTime = 0;
  private long      mLastFPSTime = 0;
  private int        mFrames = 0;
  private boolean      mPause = false;
  
  private int        mFeedsLoaded;
  private int        mFeedsTotal;
  private boolean      mReinit = true;
    
  public RiverRenderer(MainActivity activity, boolean useTranslucentBackground, TextureBank textureBank, boolean limitFramerate){
    this.mActivity = activity;
    this.mLimitFramerate = limitFramerate;
    mDisplay = new Display(activity.getSettings());
    mTranslucentBackground = useTranslucentBackground;
    mBank = textureBank;
    mOSD = new OSD(activity);
    mFeedProgress = new FeedProgress(activity.context());
    mLastFrameTime = System.currentTimeMillis();
  }
  
  public void setRenderer(Renderer renderer){
    this.mRenderer = renderer;
  }
  
  public Renderer getRenderer(){
    return this.mRenderer;
  }
  
  @Override
  public void onDrawFrame(GL10 gl) {
    if(mReinit){
      Log.v("Floating Image", "initting");
      mReinit = false;
      GlowImage.initTexture(gl);
          ShadowPainter.initTexture(gl);
          BackgroundPainter.initTexture(gl, mActivity.context(), mActivity.getSettings().backgroundColor);
          mOSD.init(gl, mDisplay);
          mRenderer.init(gl, System.currentTimeMillis() + mOffset, mOSD);
      FeedProgress.init();
      Log.v("Floating Image", "initting done!");
    }
    
    gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                GL10.GL_MODULATE);
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
    
    gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_PROJECTION);
        //gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        //GLU.gluLookAt(gl, mCamDir.getX(), mCamDir.getY(), mCamDir.getZ(), mCamPos.getX(), mCamPos.getY(), mCamPos.getZ(), 0.0f, 1.0f, 0.0f);
        GLU.gluLookAt(gl, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        
        
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                GL10.GL_FASTEST);
        //EGL10 egl = (EGL10)EGLContext.getEGL();
        //egl.eglGetConfigs(egl.eglGetCurrentDisplay(), egl.eglg, config_size, num_config)
        //gl.glEnable(GL10.GL_MULTISAMPLE);
        
        //gl.glScalef(0.25f, 0.25f, 1.0f);
        long realTime = System.currentTimeMillis();
        
        long timeDiff = realTime - mLastFrameTime;
        mLastFrameTime = realTime;
        if(mPause){
          this.mOffset -= timeDiff;
        } else if(timeDiff > 200){ // We left the app, and have returned, or experienced a lag.
          this.mOffset -= timeDiff - 80; 
        }
        
        if(mLimitFramerate){
          int targetFrametime = mActivity.getSettings().lowFps ? 80 : 40;
          if(timeDiff < targetFrametime){
            try {
          Thread.sleep(targetFrametime - timeDiff);
        } catch (InterruptedException e) {
          Log.w("Floating Image", "Framerate limiting sleep interrupted.", e);
        }
          }
        }
        
        //*
        ++mFrames;
        if(realTime - mLastFPSTime > 1000){
          //Log.v("Floating Image", "Framerate is " + mFrames + " frames per second");
          mFrames = 0;
          mLastFPSTime = realTime;
        }
        //*/
        fadeOffset(realTime);
        //mOffset = mRenderer.editOffset(mOffset, realTime);
        long time = realTime + mOffset;
        
        mDisplay.setFrameTime(realTime);
        if(mShowOSD){
          mShowOSD = false;
          mOSD.show(realTime);
        }else if(mHideOSD){
          mHideOSD = false;
          if(mOSD.hide(realTime)){
            mMoveEventHandled = true;
          }
        }else if(mClicked){
          mClicked = false;
          mRenderer.click(gl, mClickedPos.getX(), mClickedPos.getY(), time, realTime);
        }
        
        mRenderer.update(gl, time, realTime);
        
        ///////// DRAWING /////////
        gl.glRotatef(mDisplay.getRotation(), 0.0f, 0.0f, 1.0f);
        mRenderer.render(gl, time, realTime);
        if(!mDisplay.isTurning()){
          mFeedProgress.draw(gl, mFeedsLoaded, mFeedsTotal, mDisplay);
          mOSD.draw(gl, realTime);
        }
  }
  private void fadeOffset(long time) {
    float timeFactor = (3000 - (time - mUpTime)) / 3000.0f;
    float fadeOffset = mFadeOffset * timeFactor * timeFactor * mSensitivityX;
    if(timeFactor > 0){
      mOffset += fadeOffset;
    }else{
      mFadeOffset = 0.0f;
    }
  }
  
  public void setFeeds(int progress, int total){
    this.mFeedsTotal = total;
    this.mFeedsLoaded = progress;
  }
  
  public Intent followSelected(){
    return mRenderer.followCurrent();
  }
  
  public ImageReference getSelected(){
    return mRenderer.getCurrent();
  }
  
  public boolean unselect(){
    return mRenderer.back();
  }
  
  public void onResume(){
    mBank.start();
    mFadeOffset = 0.0f;
    mReinit = true;
    mRenderer.onResume();
  }
  public void onPause(){
    mRenderer.onPause();
    mBank.stop();
  }
  
  public void setBackground(){
    mRenderer.setBackground();
  }
  
  public int[] getConfigSpec() {
    if (mTranslucentBackground) {
            // We want a depth buffer and an alpha buffer
            int[] configSpec = {
                    EGL10.EGL_RED_SIZE,      8,
                    EGL10.EGL_GREEN_SIZE,    8,
                    EGL10.EGL_BLUE_SIZE,     8,
                    EGL10.EGL_ALPHA_SIZE,    8,
                    EGL10.EGL_DEPTH_SIZE,   16,
                    EGL10.EGL_NONE
            };
            return configSpec;
        } else {
            // We want a depth buffer, don't care about the
            // details of the color buffer.
            int[] configSpec = {
                    EGL10.EGL_DEPTH_SIZE,   16,
                    EGL10.EGL_NONE
            };
            return configSpec;
        }
  }
  
  public void resetImages(){
    Log.v("Floating Image", "Resetting images");
    mRenderer.resetImages();
  }

  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    mDisplay.onSurfaceChanged(width, height);
    
        /*
         * Set our projection matrix. This doesn't have to be done
         * each time we draw, but usually a new projection needs to
         * be set when the viewport is resized.
         */
            
    // Half screen width * depth (plus a little) + a little for rotation of pictures + jitter distance
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float screenAspect = (float)width / height;
        
        gl.glFrustumf(-screenAspect, screenAspect, -1, 1, 1, 50);
  }
  
  public void xChanged(float amount){
    if(mDisplay.getOrientation() == Surface.ROTATION_0){
      mOffset += amount * mSensitivityX;
    }else if(mDisplay.getOrientation() == Surface.ROTATION_180){
      mOffset -= amount * mSensitivityX;
    }
  }
  
  public void yChanged(float amount){
    if(mDisplay.getOrientation() == Surface.ROTATION_270){
      mOffset += amount * mSensitivityX;
    }else if(mDisplay.getOrientation() == Surface.ROTATION_90){
      mOffset -= amount * mSensitivityX;
    }
  }
  
  private boolean showOSD(float x, float y){
    if(y > 0){
      mHideOSD = true;
      return true;
    }
    /*
    if(y < 150){
      if(y < 0){
        //mShowOSD = true;
      }else{
        mHideOSD = true;
      }
      return true;
    }else if(y > mDisplay.getHeightPixels() - 150){
      if(y > 0){
        //mShowOSD = true;
      }else{
        mHideOSD = true;
      }
      return true;
    }
    */
    return false;
  }
  
  public boolean isVertical(float speedX, float speedY){
    return Math.abs(speedY) > Math.abs(speedX);
  }
  
  public boolean pause(){
    this.mPause ^= true;
    return this.mPause;
  }
  
  float lastX;
  float lastY;
  
  public void wallpaperMove(float fraction){
    mRenderer.wallpaperMove(fraction);
  }
  
  public void move(float x, float y, float speedX, float speedY){
    // Transform event!
    int orientation = mDisplay.getOrientation();
    float tmp;
    switch(orientation){
    case Surface.ROTATION_0:
      // Do nothing
      break;
    case Surface.ROTATION_270:
      tmp = x; x = y; y = tmp;
      y *= -1;
      tmp = speedX; speedX = speedY; speedY = tmp;
      speedY *= -1;
      break;
    case Surface.ROTATION_90:
      tmp = x; x = y; y = tmp;
      x *= -1;
      tmp = speedX; speedX = speedY; speedY = tmp;
      speedX *= -1;
      break;
    case Surface.ROTATION_180:
      x *= -1;
      y *= -1;
      speedX *= -1;
      speedY *= -1;
    }
    
    mRenderer.streamMoved(speedX, speedY);
    
    // Free image movement, override gestures
    if(mRenderer.freeMove()){
      mMoveEventHandled = true;
      y *= -1;
      x = x / mDisplay.getWidthPixels() * mDisplay.getWidth() * 2.0f;
      y = y / mDisplay.getHeightPixels() * mDisplay.getHeight() * 2.0f;
      mRenderer.move(x, y);
    }else{
      if(!mMoveEventHandled){
        // Pull up OSD?
        if(isVertical(speedX, speedY)){
          showOSD(speedX, speedY);
        }else if(mRenderer.getCurrent() == null){
          mFadeOffset = speedX;
          mUpTime = System.currentTimeMillis();
        }
      }
    }
  }
  
  public void moveEnd(float speedX, float speedY){
    if(!mMoveEventHandled){
      // Transform event!
      int orientation = mDisplay.getOrientation();
      float tmp;
      switch(orientation){
      case Surface.ROTATION_0:
        // Do nothing
        break;
      case Surface.ROTATION_270:        
        tmp = speedX; speedX = speedY; speedY = tmp;
        speedY *= -1;
        break;
      case Surface.ROTATION_90:
        tmp = speedX; speedX = speedY; speedY = tmp;
        speedX *= -1;
        break;
      case Surface.ROTATION_180:
        speedX *= -1;
        speedY *= -1;
      }
      
      // Slide right or left gesture?
      if(Math.abs(speedX) > Math.abs(speedY)){
        if(speedX > 0.0f){
          mRenderer.slideRight(System.currentTimeMillis());
        }
        else{
          mRenderer.slideLeft(System.currentTimeMillis());
        }
      }
    }
    transformEnd();
  }
  
  public void transform(float centerX, float centerY, float x, float y, float rotate, float scale){
    int orientation = mDisplay.getOrientation();
    float tmp;
    y *= -1;
    centerY = mDisplay.getHeightPixels() - centerY;
    switch(orientation){
    case Surface.ROTATION_0:
      break;
    case Surface.ROTATION_270:
      tmp = x; x = y; y = tmp;
      x *= -1;
      tmp = centerX; centerX = centerY; centerY = tmp;
      break;
    case Surface.ROTATION_90:
      tmp = x; x = y; y = tmp;
      y *= -1;
      tmp = centerX; centerX = centerY; centerY = tmp;
      break;
    case Surface.ROTATION_180:
      x *= -1;
      y *= -1;
      break;
    }
    
    x /= mDisplay.getWidthPixels();
    y /= mDisplay.getHeightPixels();
    centerX /= mDisplay.getWidthPixels();
    centerY /= mDisplay.getHeightPixels();
    
    x *= mDisplay.getWidth() * 2.0f;
    y *= mDisplay.getHeight() * 2.0f;
    centerX *= mDisplay.getWidth() * 2.0f;
    centerY *= mDisplay.getHeight() * 2.0f;
    
    switch(orientation){
    case Surface.ROTATION_0:
      centerX -=  mDisplay.getWidth();
      centerY -=  mDisplay.getHeight();
      break;
    case Surface.ROTATION_270:
      centerY -=  mDisplay.getHeight();
      centerX *= -1;
      break;
    case Surface.ROTATION_90:
      centerY -=  mDisplay.getHeight();
      centerY *= -1;
      break;
    case Surface.ROTATION_180:
      centerX -=  mDisplay.getWidth();
      centerY -=  mDisplay.getHeight();
      centerX *= -1;
      centerY *= -1;
      break;
    }
    
    mRenderer.transform(centerX, centerY, x, y, rotate, scale);
  }
  
  public void moveInit(){
    mMoveEventHandled = false;
    mRenderer.initTransform();
  }
  
  public void transformEnd(){
    mRenderer.transformEnd();
  }
  
  public void onClick(float x, float y){
    // Transform coordinates!
    int orientation = mDisplay.getOrientation();
    float tmp;
    switch(orientation){
    case Surface.ROTATION_0:
      // Do nothing
      break;
    case Surface.ROTATION_270:
      tmp = x; x = y; y = tmp;
      y = mDisplay.getHeightPixels() - y;
      break;
    case Surface.ROTATION_90:
      tmp = x; x = y; y = tmp;
      x = mDisplay.getWidthPixels() - x;
      break;
    case Surface.ROTATION_180:
      x = mDisplay.getWidthPixels() - x;
      y = mDisplay.getHeightPixels() - y;
    }
    
    if(!mOSD.click(x, y, System.currentTimeMillis())){ // This is ok, we're using realtime for the OSD
      mClicked = true;
      mClickedPos = new Vec2f((x/mDisplay.getWidthPixels() * 2.0f - 1.0f) * mDisplay.getWidth() / 2.0f, -(y / mDisplay.getHeightPixels() * 2.0f - 1.0f) * mDisplay.getHeight() / 2.0f);
    }
    
    Log.v("RiverRenderer", "Clicked position: " + mClickedPos.toString());
  }
  
  public void toggleMenu(){
    if(mOSD.isShowing()){
      mHideOSD = true;
    }else{
      mShowOSD = true;
    }
  }
 
  @Override 
  public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glMatrixMode(GL10.GL_TEXTURE);
    gl.glLoadIdentity();
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    //mOSD.init(gl);
    
    /*
         * By default, OpenGL enables features that improve quality
         * but reduce performance. One might want to tweak that
         * especially on software renderer.
         */
        gl.glDisable(GL10.GL_DITHER);
        /*
         * Some one-time OpenGL initialization can be made here
         * probably based on features of this particular context
         */
         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
                 GL10.GL_FASTEST);
         gl.glEnable(GL10.GL_TEXTURE_2D);
         
         gl.glHint(GL10.GL_LINE_SMOOTH_HINT, GL10.GL_NICEST);
      gl.glHint(GL10.GL_POINT_SMOOTH_HINT, GL10.GL_NICEST);
         

         if (mTranslucentBackground) {
             gl.glClearColor(0,0,0,0);
         } else {
             gl.glClearColor(0,0,0,1);
         }
         gl.glEnable(GL10.GL_CULL_FACE);
         gl.glShadeModel(GL10.GL_SMOOTH);
         gl.glEnable(GL10.GL_DEPTH_TEST);
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.