Skip to content

Commit

Permalink
Work on pictures & effects, and the blob effect.
Browse files Browse the repository at this point in the history
  • Loading branch information
zzorn committed Aug 31, 2012
1 parent 12ef6bd commit c20db66
Show file tree
Hide file tree
Showing 5 changed files with 348 additions and 61 deletions.
126 changes: 126 additions & 0 deletions main/src/org/gameflow/tools/BlobEffect.java
@@ -0,0 +1,126 @@
package org.gameflow.tools;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.math.MathUtils;
import org.gameflow.utils.SimplexGradientNoise;

import java.util.Random;

import static org.gameflow.utils.MathTools.TauFloat;
import static org.gameflow.utils.MathTools.clamp;

/**
*
*/
public class BlobEffect extends PicEffectBase {

private float noiseAmount = 0.5f;
private float noiseScaleX = 0.1f;
private float noiseScaleY = 0.1f;
private float noiseOffsetX = 0;
private float noiseOffsetY = 0;
private Gradient gradient = new SimpleGradient(Color.WHITE, Color.BLACK);


public BlobEffect() {
}

public boolean getUseBlending() {
return true;
}

@Override
protected void onSeedChanged(Random random) {
noiseOffsetX = (float) random.nextGaussian() * 1000;
noiseOffsetY = (float) random.nextGaussian() * 1000;
}

public float getNoiseAmount() {
return noiseAmount;
}

public void setNoiseAmount(float noiseAmount) {
this.noiseAmount = noiseAmount;
}

public float getNoiseScaleX() {
return noiseScaleX;
}

public void setNoiseScaleX(float noiseScaleX) {
this.noiseScaleX = noiseScaleX;
}

public float getNoiseScaleY() {
return noiseScaleY;
}

public void setNoiseScaleY(float noiseScaleY) {
this.noiseScaleY = noiseScaleY;
}

public Gradient getGradient() {
return gradient;
}

public void setGradient(Gradient gradient) {
this.gradient = gradient;
}

public boolean draw(Pixmap pixmap,
float x, float y,
float scaleX, float scaleY,
boolean flipX, boolean flipY,
float direction,
float hueDelta, float satDelta, float lumDelta) {
float rx = 0.5f * getW() * scaleX;
float ry = 0.5f * getH() * scaleY;

boolean anythingDrawn = false;

if (rx > 0 && ry > 0) {
final float angle = TauFloat * direction;
float cosA = MathUtils.cos(angle);
float sinA = MathUtils.sin(angle);

int r = (int) Math.max(rx, ry) + 1;

int txDelta = flipX ? -1 : 1;
int tyDelta = flipY ? -1 : 1;

int x1 = clamp((int) x - r * txDelta, 0, pixmap.getWidth());
int y1 = clamp((int) y - r * tyDelta, 0, pixmap.getHeight());
int x2 = clamp((int) x + r * txDelta, 0, pixmap.getWidth());
int y2 = clamp((int) y + r * tyDelta, 0, pixmap.getHeight());

for (int ty = y1; ty != y2; ty += tyDelta) {
for (int tx = x1; tx != x2; tx += txDelta) {
float xOffs = tx - x;
float yOffs = ty - y;
float ux = (xOffs * cosA - yOffs * sinA);
float vy = (xOffs * sinA + yOffs * cosA);
float u = ux / rx;
float v = vy / ry;
float uDistSqr = u * u;
float vDistSqr = v * v;
float d = uDistSqr + vDistSqr;
d += noiseAmount * (float) SimplexGradientNoise.sdnoise2(u * noiseScaleX + noiseOffsetX, v * noiseScaleY + noiseOffsetY);
if (d <= 1) {
int color = gradient.getColor(d);
pixmap.drawPixel(tx, ty, color);
anythingDrawn = true;
}
}
}
}

return anythingDrawn;
}


public void getNoiseScale(float scale) {
noiseScaleX = scale;
noiseScaleY = scale;
}
}
19 changes: 15 additions & 4 deletions main/src/org/gameflow/tools/GraphicsEditScreen.java
Expand Up @@ -19,6 +19,8 @@
public class GraphicsEditScreen extends Screen2D {

private static final int SIZE = 256;
private static final Color MID_COLOR = new Color(0.8f, 0.7f, 0.5f, 1);
private static final Color EDGE_COLOR = new Color(0.3f, 0.2f, 0.3f, 1f);
private Texture texture;
//private Pixmap pixmap;
private Random random = new Random();
Expand Down Expand Up @@ -74,12 +76,21 @@ private void updateTexture(float deltaSeconds) {
//pixmap.drawPixel(random.nextInt(width), random.nextInt(height), Color.PINK.toIntBits());

time += deltaSeconds;
pic.clearToColor(Color.BLUE);
pic.clearToColor(Color.ORANGE);

BlobEffect blobEffect = new BlobEffect();
blobEffect.setSize(100, 100);
blobEffect.getNoiseScale(0.95f);
blobEffect.setUseBlending(false);
blobEffect.setGradient(new SimpleGradient(MID_COLOR, EDGE_COLOR));

random.setSeed(232);
float scale = SIZE * 0.8f;
for (int i = 0; i < 40; i++) {
pic.drawOval(random.nextInt(SIZE), random.nextInt(SIZE), random.nextFloat() * scale, random.nextFloat() * scale, time * (float) random.nextGaussian(), new SimpleGradient(Color.YELLOW, Color.RED));
float scale = 1.2f;
for (int i = 0; i < 50; i++) {
blobEffect.setSeed(i + 100);
pic.drawEffect(blobEffect, random.nextInt(SIZE), random.nextInt(SIZE),
random.nextFloat() * scale + scale * 0.5f,
random.nextFloat() * scale + scale * 0.5f, false, false, time * (float) random.nextGaussian() * 0.1f);
scale *= 0.97f;
}

Expand Down
148 changes: 94 additions & 54 deletions main/src/org/gameflow/tools/Pic.java
Expand Up @@ -3,6 +3,7 @@
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.Array;

import java.util.HashMap;
import java.util.Map;
Expand All @@ -21,8 +22,10 @@ public class Pic {

private Map<String, Channel> channels = null;

boolean wrapVertically = false;
boolean wrapHorizontally = false;
private Array<PicEffect> effects = new Array<PicEffect>();

boolean wrapVertically = true;
boolean wrapHorizontally = true;

public Pic(int width, int height) {
this(width, height, false, false);
Expand Down Expand Up @@ -92,6 +95,20 @@ public void clearToColor(Color color) {
pixmap.fill();
}

public void addEffect(PicEffect effect) {
effects.add(effect);
}

public void removeEffect(PicEffect effect) {
effects.removeValue(effect, true);
}

public void drawEffects() {
for (PicEffect effect : effects) {
drawEffect(effect, getWidth() / 2, getHeight() / 2, 1, 1, false, false, 0, 0, 0, 0);
}
}

/**
* @param pixmap
* @return true if the picture was wrapped.
Expand Down Expand Up @@ -130,41 +147,99 @@ public boolean draw(Pixmap pixmap,
return wrapRight || wrapLeft || wrapDown || wrapUp;
}

public boolean drawEffect(PicEffect effect) {
return drawEffect(effect, pixmap.getWidth()/2, pixmap.getHeight()/2, 1, 1, false, false, 0, 0,0,0);
}

public boolean drawEffect(PicEffect effect,
float x, float y) {
return drawEffect(effect,x, y, 1, 1, false, false, 0, 0,0,0);
}

public boolean drawEffect(PicEffect effect,
float x, float y,
float scale) {
return drawEffect(effect,x, y, scale, scale, false, false, 0, 0,0,0);
}

public boolean drawEffect(PicEffect effect,
float x, float y,
float scaleX, float scaleY) {
return drawEffect(effect,x, y, scaleX, scaleY, false, false, 0, 0,0,0);
}

public boolean drawEffect(PicEffect effect,
float x, float y,
float scaleX, float scaleY,
boolean flipX, boolean flipY) {
return drawEffect(effect,x, y, scaleX, scaleY, flipX, flipY, 0, 0,0,0);
}

public boolean drawEffect(PicEffect effect,
float x, float y,
float scaleX, float scaleY,
boolean flipX, boolean flipY,
float direction) {
return drawEffect(effect,x, y, scaleX, scaleY, flipX, flipY, direction, 0,0,0);
}

/**
* Draws a sphere on the pixmap.
*/
public void drawOval(float x, float y, float rx, float ry, float direction, Gradient gradient) {
if (rx > 0 && ry > 0) {
int r = (int) Math.max(rx, ry) + 1;
* Draws an effect on the pixmap.
*/
public boolean drawEffect(PicEffect effect,
float x, float y,
float scaleX, float scaleY,
boolean flipX, boolean flipY,
float direction,
float hueDelta, float satDelta, float lumDelta) {
if (scaleX > 0 && scaleX > 0) {
float effectW = effect.getW();
float effectH = effect.getH();

// TODO: Adjust bounding box for rotation
float sizeX = effectW * scaleX;
float sizeY = effectH * scaleY;
int r = (int) Math.max(sizeX, sizeY) + 1;
int x1 = (int) x - r;
int y1 = (int) y - r;
int x2 = (int) x + r;
int y2 = (int) y + r;

int w = getWidth();
int h = getHeight();
boolean wrapRight = wrapRight(x1, x2);
boolean wrapLeft = wrapLeft(x1, x2);
boolean wrapUp = wrapUp(y1, y2);
boolean wrapDown = wrapDown(y1, y2);

Pixmap.Blending oldBlending = Pixmap.getBlending();
Pixmap.setBlending(Pixmap.Blending.None);
if (effect.getUseBlending()) {
Pixmap.setBlending(Pixmap.Blending.SourceOver);
}
else {
Pixmap.setBlending(Pixmap.Blending.None);
}

int w = getWidth();
int h = getHeight();

if (wrapDown && wrapRight) drawOvalOnce(x + w, y + h, rx, ry, direction, gradient);
if (wrapDown) drawOvalOnce(x, y + h, rx, ry, direction, gradient);
if (wrapDown && wrapLeft) drawOvalOnce(x - w, y + h, rx, ry, direction, gradient);
boolean b = false;
if (wrapDown && wrapRight) b = b || effect.draw(pixmap, x + w, y + h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
if (wrapDown) b = b || effect.draw(pixmap, x , y + h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
if (wrapDown && wrapLeft) b = b || effect.draw(pixmap, x - w, y + h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);

if (wrapRight) drawOvalOnce(x + w, y, rx, ry, direction, gradient);
drawOvalOnce(x, y, rx, ry, direction, gradient);
if (wrapLeft) drawOvalOnce(x - w, y, rx, ry, direction, gradient);
if (wrapRight) b = b || effect.draw(pixmap, x + w, y , scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
effect.draw(pixmap, x, y, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
if (wrapLeft) b = b || effect.draw(pixmap, x - w, y , scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);

if (wrapUp && wrapRight) drawOvalOnce(x + w, y - h, rx, ry, direction, gradient);
if (wrapUp) drawOvalOnce(x, y - h, rx, ry, direction, gradient);
if (wrapUp && wrapLeft) drawOvalOnce(x - w, y - h, rx, ry, direction, gradient);
if (wrapUp && wrapRight) b = b || effect.draw(pixmap, x + w, y - h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
if (wrapUp) b = b || effect.draw(pixmap, x , y - h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);
if (wrapUp && wrapLeft) b = b || effect.draw(pixmap, x - w, y - h, scaleX, scaleY, flipX, flipY, direction, hueDelta, satDelta, lumDelta);

Pixmap.setBlending(oldBlending);

return b;
}
else {
return false;
}
}

Expand All @@ -184,40 +259,5 @@ private boolean wrapRight(int x1, int x2) {
return wrapHorizontally && x1 < 0 && x2 >= 0;
}

private void drawOvalOnce(float x, float y, float rx, float ry, float direction, Gradient gradient) {
if (rx > 0 && ry > 0) {
final float angle = TauFloat * direction;
float cosA = MathUtils.cos(angle);
float sinA = MathUtils.sin(angle);

int r = (int) Math.max(rx, ry) + 1;

int x1 = clamp((int) x - r, 0, getWidth());
int y1 = clamp((int) y - r, 0, getHeight());
int x2 = clamp((int) x + r, 0, getWidth());
int y2 = clamp((int) y + r, 0, getHeight());

float rxSqr = rx*rx;
float rySqr = ry*ry;
for (int ty = y1; ty < y2; ty++) {
for (int tx = x1; tx < x2; tx++) {
float tdx = tx - x;
float tdy = ty - y;
float dx = (tdx * cosA - tdy * sinA);
float dy = (tdx * sinA + tdy * cosA);
float xDistSqr = dx*dx;
float yDistSqr = dy*dy;
float relXDist = xDistSqr / rxSqr;
float relYDist = yDistSqr / rySqr;
float d = relXDist + relYDist;
if (d <= 1) {
int color = gradient.getColor(d);
pixmap.drawPixel(tx, ty, color);
}
}
}

}
}

}

0 comments on commit c20db66

Please sign in to comment.