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());
}
}