Subversion Repositories AndroidProjects

Rev

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

package com.gebauz.pingK.game;

import javax.microedition.khronos.opengles.GL10;

import com.gebauz.framework.util.GLUtil;
import com.gebauz.framework.util.MathUtil;
import com.gebauz.framework.util.Mesh;
import com.gebauz.framework.util.RenderTexture;
import com.gebauz.framework.util.RenderUtil;
import com.gebauz.framework.util.Texture;
import com.gebauz.framework.util.Vector4;
import com.gebauz.framework.util.renderstates.RenderStates;
import com.gebauz.framework.util.renderstates.BlendingStates.BlendingMode;

public class WaveEffect
{
        private GameLogic mGameLogic = null;
       
        private RenderTexture mOffscreen = null;
        private Mesh mQuad = null;
        private Mesh mQuadTransparent = null;
        private Mesh mWave = null;
       
        static final int NUM_VERTICES_X = 5;
        static final int NUM_VERTICES_Y = 4;
       
        private int mViewportWidth;
        private int mViewportHeight;
       
        private float mWaveTimer = 0.0f;
        private float mCurrentAlpha = 0.0f;
       
        public WaveEffect(GameLogic gameLogic)
        {
                mGameLogic = gameLogic;
               
                mViewportWidth = getOptimumWidth();
                mViewportHeight = getOptimumHeight();
               
                mOffscreen = RenderTexture.create(mViewportWidth, mViewportHeight);
                mOffscreen.setFiltering(Texture.Filter.LINEAR, Texture.Filter.LINEAR);
               
                float widthRatio = (float)mOffscreen.width / (float)GLUtil.getInstance().getWidth();
                float heightRatio = (float)mOffscreen.height/ (float)GLUtil.getInstance().getHeight();
               
                //mQuad = RenderUtil.createQuad(0.0f, 10.0f, GameConsts.VIRTUAL_SCREEN_WIDTH, mGameLogic.getVirtualPlayFieldHeight(), 0.0f, 0.0f, widthRatio, heightRatio);            
                mQuad = RenderUtil.createQuad(0.0f, 0.0f, GameConsts.VIRTUAL_SCREEN_WIDTH, mGameLogic.getVirtualPlayFieldHeight());
                mQuadTransparent = RenderUtil.createQuad(0.0f, 0.0f, GameConsts.VIRTUAL_SCREEN_WIDTH, mGameLogic.getVirtualPlayFieldHeight(), new Vector4(1.0f, 1.0f, 1.0f, 0.5f));
               
                mWave = new Mesh();
               
                float intervalX = GameConsts.VIRTUAL_SCREEN_WIDTH / (float)(NUM_VERTICES_X-1);
                float intervalY = mGameLogic.getVirtualPlayFieldHeight() / (float)(NUM_VERTICES_Y-1);
               
                float texIntervalX = 1.0f / (float)(NUM_VERTICES_X-1);
                float texIntervalY = 1.0f / (float)(NUM_VERTICES_Y-1);
               
                Mesh.AttributeArray vertices = new Mesh.AttributeArray(Mesh.COORD_ELEMENTS_COUNT * NUM_VERTICES_X * NUM_VERTICES_Y);
                Mesh.AttributeArray colors = new Mesh.AttributeArray(Mesh.COLOR_ELEMENTS_COUNT * NUM_VERTICES_X * NUM_VERTICES_Y);
                Mesh.AttributeArray texCoords = new Mesh.AttributeArray(Mesh.TEX_COORD_ELEMENTS_COUNT * NUM_VERTICES_X * NUM_VERTICES_Y);
               
                for (int y = 0; y < NUM_VERTICES_Y; y++)
                {
                        for (int x = 0; x < NUM_VERTICES_X; x++)                       
                        {
                                float vx = x * intervalX;
                                float vy = y * intervalY;
                                float tx = x * texIntervalX;
                                float ty = 1.0f - y * texIntervalY;
                               
                                vertices.fill(vx, vy, 0.0f);
                                colors.fill(1.0f, 1.0f, 1.0f, 1.0f);
                                texCoords.fill(tx, ty);
                        }
                }
               
                // indexing
                short indices[] = new short[(NUM_VERTICES_X - 1) * (NUM_VERTICES_Y - 1) * 3 * 2];
                int idx = 0;
                for (int y = 0; y < (NUM_VERTICES_Y - 1); y++)
                {
                        for (int x = 0; x < (NUM_VERTICES_X - 1); x++)
                        {
                                indices[idx] = (short)(y * NUM_VERTICES_X + x); idx++;
                                indices[idx] = (short)(y * NUM_VERTICES_X + (x + 1)); idx++;
                                indices[idx] = (short)((y + 1) * NUM_VERTICES_X + x); idx++;
                               
                                indices[idx] = (short)((y + 1) * NUM_VERTICES_X + x); idx++;
                                indices[idx] = (short)(y * NUM_VERTICES_X + (x + 1)); idx++;
                                indices[idx] = (short)((y + 1) * NUM_VERTICES_X + (x + 1)); idx++;
                        }
                }
               
                mWave.setVertices(vertices.getAttributeArray());
                mWave.setColors(colors.getAttributeArray());
                mWave.setTexCoords(texCoords.getAttributeArray());
                mWave.setIndices(indices);
        }
       
        public void update(float deltaTime)
        {
                mWaveTimer += deltaTime;
               
                float flowerTime = mGameLogic.getPowerUpEffect().getFlowerTime();
                float alpha = 1.0f;
                if (flowerTime < GameConsts.POWERUP_FLOWER_FADE_TIME)
                {
                        alpha = 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);
                        alpha = 1.0f - MathUtil.clamp(v / GameConsts.POWERUP_FLOWER_FADE_TIME, 0.0f, 1.0f);
                }
               
                // go to target
                float diff = alpha - mCurrentAlpha;
                mCurrentAlpha += (diff * deltaTime * GameConsts.POWERUP_FLOWER_FADE_TIME);
               
                updateWave();
        }

        public void render()
        {
                // pass-through if effect not active
               
                RenderStates rs = GLUtil.getRenderStates();
                       
                rs.blending.setEnabled(true);
                rs.blending.setBlendingMode(BlendingMode.ALPHABLEND);
                rs.culling.setEnabled(false);
                rs.getTextureStage(0).bindTexture(mOffscreen);
                       
                rs.activate();                 
                if (mGameLogic.getPowerUpEffect().isFlowerActive())
                {
//                      if (mGameLogic.getPowerUpEffect().isFlowerFading())
//                              mQuad.render();
                       
                        mWave.render();
                }
                else
                {
                        mQuad.render();                
                }
                rs.deactivate();
                       
                rs.getTextureStage(0).bindTexture(null);
        }
       
        public void renderTransparent()
        {
                RenderStates rs = GLUtil.getRenderStates();
               
                rs.blending.setEnabled(true);
                rs.blending.setBlendingMode(BlendingMode.ALPHABLEND);
                rs.culling.setEnabled(false);
                rs.getTextureStage(0).bindTexture(mOffscreen);
                       
                rs.activate();                 
                mQuadTransparent.render();
                rs.deactivate();
                       
                rs.getTextureStage(0).bindTexture(null);
        }
       
        public void beginRenderToTexture()
        {
                // pass-through if effect not active
                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, mViewportWidth, mViewportHeight);

                gl.glMatrixMode(GL10.GL_PROJECTION);
                gl.glLoadIdentity();
                gl.glOrthof(0, GameConsts.VIRTUAL_SCREEN_WIDTH-1.0f, mGameLogic.getVirtualPlayFieldHeight()-1.0f, 0, 0, 1);
        }
       
        public void endRenderToTexture()
        {
                // pass-through if effect not active
                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 int getOptimumWidth()
        {
                int screenWidth = GLUtil.getInstance().getWidth();
                int potWidth = 256;
               
                while (potWidth < screenWidth)
                {
                        potWidth *= 2;
                }
               
                if (potWidth > 512)
                        potWidth = 512;
               
                return potWidth;
        }
       
        public int getOptimumHeight()
        {
                int screenHeight = GLUtil.getInstance().getWidth();
                int potHeight = 256;
               
                while (potHeight < screenHeight)
                {
                        potHeight *= 2;
                }
               
                if (potHeight > 256)
                        potHeight = 256;
               
                return potHeight;
        }
       
        public void updateWave()
        {
                Mesh.AttributeArray vertices = new Mesh.AttributeArray(Mesh.COORD_ELEMENTS_COUNT * NUM_VERTICES_X * NUM_VERTICES_Y);
                Mesh.AttributeArray colors = new Mesh.AttributeArray(Mesh.COLOR_ELEMENTS_COUNT * NUM_VERTICES_X * NUM_VERTICES_Y);
               
                float intervalX = GameConsts.VIRTUAL_SCREEN_WIDTH / (float)(NUM_VERTICES_X-1);
                float intervalY = mGameLogic.getVirtualPlayFieldHeight() / (float)(NUM_VERTICES_Y-1);
               
                final float WAVE_DEVIATION_X = 10.0f * mCurrentAlpha;
                final float WAVE_DEVIATION_Y = 10.0f * mCurrentAlpha;
               
                for (int y = 0; y < NUM_VERTICES_Y; y++)
                {
                        for (int x = 0; x < NUM_VERTICES_X; x++)                       
                        {
                                float deviationX = (float)Math.cos((float)y + mWaveTimer) * WAVE_DEVIATION_X;
                                float deviationY = (float)Math.sin((float)x + mWaveTimer) * WAVE_DEVIATION_Y;
                               
                                float vx = x * intervalX + deviationX;
                                float vy = y * intervalY + deviationY;
                               
                                vertices.fill(vx, vy, 0.0f);
                                colors.fill(1.0f, 1.0f, 1.0f, mCurrentAlpha);
                        }
                }
               
                mWave.setVertices(vertices.getAttributeArray());
                //mWave.setColors(colors.getAttributeArray());
        }

}