Refactor Graphics to support clipping and avoid drawing things outside the bounds of its parent

This commit is contained in:
drdev
2014-02-20 20:47:27 +00:00
parent 4425029892
commit 08ec2cc9d9
3 changed files with 47 additions and 11 deletions

View File

@@ -18,7 +18,7 @@ public abstract class FScreen extends FContainer implements Screen {
@Override @Override
public final void render(float delta) { public final void render(float delta) {
draw(new Graphics()); Graphics.drawScreen(this);
} }
@Override @Override

View File

@@ -13,15 +13,19 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer; import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType; import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
import forge.assets.FSkin; import forge.assets.FSkin;
import forge.assets.FSkinColor; import forge.assets.FSkinColor;
import forge.assets.FSkinFont; import forge.assets.FSkinFont;
import forge.assets.FSkinImage; import forge.assets.FSkinImage;
import forge.screens.home.HomeScreen; import forge.screens.home.HomeScreen;
import forge.toolbox.FDisplayObject;
public class Forge extends Game { public class Forge extends Game {
private static Forge game; private static Forge game;
private static int screenWidth;
private static int screenHeight; private static int screenHeight;
private static SpriteBatch batch; private static SpriteBatch batch;
private static ShapeRenderer shapeRenderer; private static ShapeRenderer shapeRenderer;
@@ -68,6 +72,7 @@ public class Forge extends Game {
@Override @Override
public void resize(int width, int height) { public void resize(int width, int height) {
super.resize(width, height); super.resize(width, height);
screenWidth = width;
screenHeight = height; screenHeight = height;
} }
@@ -79,16 +84,47 @@ public class Forge extends Game {
} }
public static class Graphics { public static class Graphics {
private final float offsetX, offsetY; private Rectangle bounds;
private int failedClipCount;
public Graphics() { public static void drawScreen(FScreen screen) {
offsetX = 0; Gdx.gl.glEnable(GL10.GL_SCISSOR_TEST);
offsetY = 0; Graphics g = new Graphics();
g.draw(screen);
Gdx.gl.glDisable(GL10.GL_SCISSOR_TEST);
} }
public Graphics(Graphics g, float x, float y) { private Graphics() {
offsetX = g.offsetX + x; bounds = new Rectangle(0, 0, screenWidth, screenHeight);
offsetY = g.offsetY + y; }
public void startClip() {
startClip(0, 0, bounds.width, bounds.height);
}
public void startClip(float x, float y, float w, float h) {
batch.flush(); //must flush batch to prevent other things not rendering
if (!ScissorStack.pushScissors(new Rectangle(adjustX(0), adjustY(0, h), w, h))) {
failedClipCount++; //tracked failed clips to prevent calling popScissors on endClip
}
}
public void endClip() {
if (failedClipCount == 0) {
ScissorStack.popScissors();
}
else {
failedClipCount--;
}
}
public void draw(FDisplayObject displayObj) {
final Rectangle parentBounds = bounds;
bounds = new Rectangle(parentBounds.x + displayObj.getLeft(), parentBounds.y + displayObj.getTop(), displayObj.getWidth(), displayObj.getHeight());
if (bounds.overlaps(parentBounds)) { //avoid drawing object if it's not within visible region
displayObj.draw(this);
}
bounds = parentBounds;
} }
public void fillRect(FSkinColor skinColor, float x, float y, float w, float h) { public void fillRect(FSkinColor skinColor, float x, float y, float w, float h) {
@@ -147,11 +183,11 @@ public class Forge extends Game {
} }
private float adjustX(float x) { private float adjustX(float x) {
return x + offsetX; return x + bounds.x;
} }
private float adjustY(float y, float height) { private float adjustY(float y, float height) {
return screenHeight - y - offsetY - height; //flip y-axis return screenHeight - y - bounds.y - height; //flip y-axis
} }
} }
} }

View File

@@ -18,7 +18,7 @@ public abstract class FContainer extends FDisplayObject {
public final void draw(Graphics g) { public final void draw(Graphics g) {
drawBackground(g); drawBackground(g);
for (FDisplayObject child : children) { for (FDisplayObject child : children) {
child.draw(new Graphics(g, child.getLeft(), child.getTop())); g.draw(child);
} }
drawOverlay(g); drawOverlay(g);
} }