Subversion Repositories AndroidProjects

Rev

Rev 339 | Blame | Compare with Previous | Last modification | View Log | RSS feed

package com.gebauz.pingk.effects;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
import com.gebauz.Bauzoid.graphics.model.GeometryUtil;
import com.gebauz.Bauzoid.graphics.model.SimpleGeometry;
import com.gebauz.Bauzoid.graphics.renderstates.RenderStates;
import com.gebauz.Bauzoid.graphics.renderstates.BlendingStates.BlendingMode;
import com.gebauz.Bauzoid.graphics.shader.ShaderProgram;
import com.gebauz.Bauzoid.graphics.shader.ShaderUniform;
import com.gebauz.Bauzoid.graphics.shader.ShaderUtil;
import com.gebauz.Bauzoid.math.MathUtil;
import com.gebauz.Bauzoid.math.Matrix4;
import com.gebauz.Bauzoid.math.Vector2;
import com.gebauz.pingk.entities.Entity;
import com.gebauz.pingk.game.GameConsts;
import com.gebauz.pingk.game.GameLogic;

/** Handles all powerup effects that are done via offscreen rendering/postprocessing. */
public class OffscreenEffect extends Entity
{              
        private FrameBuffer mOffscreen = null;
        private SimpleGeometry mQuad = null;
       
        private ShaderProgram mShader = null;
        private ShaderUniform mTextureHandle = null;
        private ShaderUniform mDx = null;
        private ShaderUniform mDy = null;
        private ShaderUniform mAlpha = null;
        private ShaderUniform mWaveMax = null;
       
        private ShaderUniform mMoveX = null;
        private ShaderUniform mMoveY = null;
       
        private ShaderUniform mTime = null;
        private ShaderUniform mFlashFactor = null;
       
        private float mCurrentMosaicFade = 0.0f;
        private float mPixelationFactor = 1.0f;
        private float mCurrentFlowerFade = 0.0f;
       
        private float mMoveDirX = 0.0f;
        private float mMoveDirY = 0.0f;
        private float mShaderTime = 0.0f;
       
        private float mFlashTime = -1.0f;
        private float mTotalFlashTime = 1.0f;
       
        public OffscreenEffect(GameLogic gameLogic)
        {
                super(gameLogic);              
        }

        @Override
        public void init()
        {
                //mOffscreen = new FrameBuffer(Pixmap.Format.RGB565, GameConsts.POWERUP_MOSAIC_OFFSCREEN_WIDTH, GameConsts.POWERUP_MOSAIC_OFFSCREEN_HEIGHT, false);
               
                int w = Math.min(getGraphics().getWidth(), 800);
                int h = Math.min(getGraphics().getHeight(), 480);              
               
                mOffscreen = new FrameBuffer(Pixmap.Format.RGB565, w, h, false);
               
                //mQuad = GeometryUtil.createQuad(getGraphics(), 0.0f, 0.0f, GameConsts.VIRTUAL_SCREEN_WIDTH, getGameLogic().getPlayField().getVirtualHeight());
                //mQuad = GeometryUtil.createSubdividedQuad(getGraphics(), 0.0f, 0.0f, GameConsts.VIRTUAL_SCREEN_WIDTH, GameConsts.VIRTUAL_SCREEN_HEIGHT, 5, 4);
                mQuad = GeometryUtil.createSubdividedQuad(getGraphics(), -1.0f, 1.0f, 1.0f, -1.0f, 5, 4);
               
                //ShaderUtil.verbose = true;
               
                mShader = ShaderUtil.createShaderFromFile(getGraphics(), Gdx.files.internal("data/shaders/offscreen.vert"),
                                Gdx.files.internal("data/shaders/offscreen.frag"));
               
                if (mShader != null)
                {
                        mTextureHandle = mShader.getUniform("uDiffuse");
                        mDx = mShader.getUniform("uDx");
                        mDy = mShader.getUniform("uDy");
                        mAlpha = mShader.getUniform("uAlpha");
                        mMoveX = mShader.getUniform("uMoveX");
                        mMoveY = mShader.getUniform("uMoveY");
                        mTime = mShader.getUniform("uTime");
                        mWaveMax = mShader.getUniform("uWaveMax");
                        mFlashFactor = mShader.getUniform("uFlashFactor");
                }
               
                mCurrentMosaicFade = 0.0f;
                mShaderTime = 0.0f;
        }

        @Override
        public void exit()
        {
                if (mShader != null)
                {
                        mTextureHandle = null;
                        mDx = null;
                        mDy = null;
                        mAlpha = null;
                        mTime = null;
                        mFlashFactor = null;
                        mShader.dispose();
                        mShader = null;
                }
               
                if (mOffscreen != null)
                {
                        mOffscreen.dispose();
                        mOffscreen = null;
                }              
               
                if (mQuad != null)
                {
                        mQuad.dispose();
                        mQuad = null;
                }
        }

        @Override
        public void update(float deltaTime)
        {
                mFlashTime -= deltaTime;
                mShaderTime += deltaTime;
               
                updateMosaic(deltaTime);
                updateSlowMo(deltaTime);
                updateFlower(deltaTime);
        }
       
        public void updateMosaic(float deltaTime)
        {              
                if (getGameLogic().getPowerUpLogic().isMosaicActive())
                {
                        float mosaicTime = getGameLogic().getPowerUpLogic().getMoasicTime();
                        float mosaicFade = 1.0f;
                        if (mosaicTime < GameConsts.POWERUP_MOSAIC_FADE_TIME)
                        {
                                mosaicFade = MathUtil.clamp(mosaicTime / GameConsts.POWERUP_MOSAIC_FADE_TIME, 0.0f, 1.0f);
                        }                              
                        else if (mosaicTime > (GameConsts.POWERUP_MOSAIC_TIME - GameConsts.POWERUP_MOSAIC_FADE_TIME))
                        {
                                float v = mosaicTime - (GameConsts.POWERUP_MOSAIC_TIME - GameConsts.POWERUP_MOSAIC_FADE_TIME);
                                mosaicFade = 1.0f - MathUtil.clamp(v / GameConsts.POWERUP_MOSAIC_FADE_TIME, 0.0f, 1.0f);
                        }
                       
                        // go to target
                        float diff = mosaicFade - mCurrentMosaicFade;
                        mCurrentMosaicFade += (diff * deltaTime * GameConsts.POWERUP_MOSAIC_FADE_TIME);
                       
                        mPixelationFactor = 1.0f + (float)Math.floor(14.0f * mCurrentMosaicFade) / 2.0f;
                }
                else
                {
                        mPixelationFactor = 1.0f;
                }
        }
       
        public void updateSlowMo(float deltaTime)
        {              
                if (getGameLogic().getPowerUpLogic().isSlowMoActive())
                {
                        Vector2 move = getGameLogic().getBall().getMoveDirection();
                        move.normalize();
                       
                        float diff = move.x - mMoveDirX;
                        mMoveDirX += (diff * deltaTime * 2.0f);
                       
                        diff = move.y - mMoveDirY;
                        mMoveDirY += (diff * deltaTime * 2.0f);
                }
                else
                {
                        mMoveDirX = 0.0f;
                        mMoveDirY = 0.0f;                      
                }
        }
       
        public void updateFlower(float deltaTime)
        {
                if (getGameLogic().getPowerUpLogic().isFlowerActive())
                {
                        float flowerTime = getGameLogic().getPowerUpLogic().getFlowerTime();
                        float flowerFade = 1.0f;
                        if (flowerTime < GameConsts.POWERUP_FLOWER_FADE_TIME)
                        {
                                flowerFade = MathUtil.clamp(flowerTime / GameConsts.POWERUP_FLOWER_FADE_TIME, 0.0f, 1.0f);
                        }                              
                        else if (flowerTime > (GameConsts.POWERUP_FLOWER_TIME - GameConsts.POWERUP_FLOWER_FADE_TIME))
                        {
                                float v = flowerTime - (GameConsts.POWERUP_MOSAIC_TIME - GameConsts.POWERUP_FLOWER_FADE_TIME);
                                flowerFade = 1.0f - MathUtil.clamp(v / GameConsts.POWERUP_FLOWER_FADE_TIME, 0.0f, 1.0f);
                        }
                       
                        // go to target
                        float diff = flowerFade - mCurrentFlowerFade;
                        mCurrentFlowerFade += (diff * deltaTime * GameConsts.POWERUP_FLOWER_FADE_TIME);
                }
                else
                {
                        mCurrentFlowerFade = 0.0f;
                }
        }

        @Override
        public void render()
        {
                RenderStates rs = getGraphics().renderStates;
                       
                //Matrix4 modelMatrix = Matrix4.createIdentity();
                       
                //rs.pushModelMatrix();
                {
                        //rs.model = modelMatrix;
                               
                        mShader.activate();
                        {
                                mTextureHandle.set(0);
                                rs.getTextureStage(0).bindTexture(mOffscreen.getColorBufferTexture());
                                       
                                mDx.set(mPixelationFactor * (1.0f / GameConsts.VIRTUAL_SCREEN_WIDTH));
                                mDy.set(mPixelationFactor * (1.0f / GameConsts.VIRTUAL_SCREEN_HEIGHT));
                                mAlpha.set(1.0f);
                               
                                //mMoveX.set(mMoveDirX / 100.0f);
                                //mMoveY.set(mMoveDirY / 100.0f);
                                       
                                if (mTime != null)
                                        mTime.set(mShaderTime);
                                       
                                if (mWaveMax != null)
                                        mWaveMax.set(mCurrentFlowerFade * GameConsts.POWERUP_FLOWER_WAVE_MAX);
                               
                                float flashAmount = MathUtil.clamp(mFlashTime/mTotalFlashTime, 0.0f, 1.0f);
                                if (mFlashFactor != null)
                                        mFlashFactor.set(flashAmount);
                                       
                                rs.blending.setEnabled(true);
                                rs.blending.setBlendingMode(BlendingMode.ALPHABLEND);
                                rs.culling.setEnabled(false);
                                rs.depthTest.setEnabled(false);
                                rs.activate();
                                {
                                        mQuad.render();
                                }
                                rs.deactivate();
                        }
                        mShader.deactivate();
                }
                //rs.popModelMatrix();
        }
       
        /** Called before the game is rendered. */
        public void beginRenderToTexture()
        {
                mOffscreen.begin();
                       
                getGraphics().clear(0.05f, 0.05f, 0.05f, 0.0f);
                       
                getGraphics().renderStates.pushProjectionMatrix();                     
                getGraphics().renderStates.projection = Matrix4.createOrtho(
                                0.0f,
                                GameConsts.VIRTUAL_SCREEN_WIDTH-1,
                                GameConsts.VIRTUAL_SCREEN_HEIGHT-1,
                                0.0f,
                                0.0f,
                                1.0f
                        );
        }
       
        /** Called after the game is rendered. */
        public void endRenderToTexture()
        {
                mOffscreen.end();
                getGraphics().renderStates.popProjectionMatrix();
        }
       
        public void startFlash(float time)
        {
                mFlashTime = time;
                mTotalFlashTime = time;
        }
}