Subversion Repositories AndroidProjects

Rev

Rev 308 | Rev 314 | Go to most recent revision | 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 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;
       
        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);
               
                mOffscreen = new FrameBuffer(Pixmap.Format.RGB565, getGraphics().getWidth(), getGraphics().getHeight(), 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);
               
                ShaderUtil.verbose = true;
               
                mShader = ShaderUtil.createShaderFromFile(getGraphics(), Gdx.files.internal("data/shaders/mosaic.vs"),
                                Gdx.files.internal("data/shaders/mosaic.fs"));
               
                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");
                }
               
                mCurrentMosaicFade = 0.0f;
                mShaderTime = 0.0f;
        }

        @Override
        public void exit()
        {
                if (mShader != null)
                {
                        mTextureHandle = null;
                        mDx = null;
                        mDy = null;
                        mAlpha = null;
                        mTime = null;
                        mShader.dispose();
                        mShader = null;
                }
               
                //for (int i = 0; i < NUM_OFFSCREEN; i++)
                {
                        if (mOffscreen != null)
                        {
                                mOffscreen.dispose();
                                mOffscreen = null;
                        }
                }              
               
                if (mQuad != null)
                {
                        mQuad.dispose();
                        mQuad = null;
                }
        }

        @Override
        public void update(float 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)
        {
                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);
        }

        @Override
        public void render()
        {
                // pass-through if effect not active
                //if (getGameLogic().getPowerUpLogic().isMosaicActive())
                {
                        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);
                                       
                                        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();
                       
/*                      RenderStates rs = GLUtil.getRenderStates();
                       
                        rs.blending.setEnabled(true);
                        rs.blending.setBlendingMode(BlendingMode.ALPHABLEND);
                        rs.culling.setEnabled(false);
                        rs.getTextureStage(0).bindTexture(mOffscreen);
                       
                        rs.activate();                 
                        mMesh.render();
                        rs.deactivate();
                       
                        rs.getTextureStage(0).bindTexture(null);*/

                }
        }
       
        /** Called before the game is rendered. */
        public void beginRenderToTexture()
        {
                // pass-through if effect not active
                //if (getGameLogic().getPowerUpLogic().isMosaicActive())
                {
                        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,
                                        //getGameLogic().getPlayField().getVirtualHeight()-1,
                                        GameConsts.VIRTUAL_SCREEN_HEIGHT-1,
                                        0.0f,
                                        0.0f,
                                        1.0f
                                );
                       
/*                      mOffscreen.activate();
                       
                        GL10 gl = GLUtil.getGL();
                        gl.glClearColor(0.05f, 0.05f, 0.05f, 1.0f);
                        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
                       
                        gl.glViewport(0, 0, GameConsts.POWERUP_MOSAIC_OFFSCREEN_WIDTH, GameConsts.POWERUP_MOSAIC_OFFSCREEN_HEIGHT);
                       
                        gl.glMatrixMode(GL10.GL_PROJECTION);
                        gl.glLoadIdentity();
                        gl.glOrthof(0, GameConsts.VIRTUAL_SCREEN_WIDTH-1.0f, mGameLogic.getVirtualPlayFieldHeight()-1.0f, 0, 0, 1);
*/

                }              
        }
       
        /** Called after the game is rendered. */
        public void endRenderToTexture()
        {
                // pass-through if effect not active
                //if (getGameLogic().getPowerUpLogic().isMosaicActive())
                {
                       
                        mOffscreen.end();
                        getGraphics().renderStates.popProjectionMatrix();
/*                      getGraphics().renderStates.projection = Matrix4.createOrtho(
                                        0.0f,
                                        GameConsts.VIRTUAL_SCREEN_WIDTH-1,
                                        GameConsts.VIRTUAL_SCREEN_HEIGHT-1,
                                        0.0f,
                                        0.0f,
                                        1.0f
                                );*/

                       
/*                      mOffscreen.deactivate();
                        GL10 gl = GLUtil.getGL();
                        gl.glViewport(0, 0, GLUtil.getInstance().getWidth(), GLUtil.getInstance().getHeight());
                        gl.glMatrixMode(GL10.GL_PROJECTION);
                        gl.glLoadIdentity();
                        gl.glOrthof(0, GameConsts.VIRTUAL_SCREEN_WIDTH-1.0f, GameConsts.VIRTUAL_SCREEN_HEIGHT-1.0f, 0, 0, 1);*/

                }              
        }
       
/*      public final int getOtherOffscreen(int n)
        {
                if (n == 0)
                        return 1;
                return 0;
        }*/


}