add 3d projected coordinate support for sprite rendering methods, refactor a bit, add some more overloads mainly for convenience

This commit is contained in:
Gered 2013-07-01 18:33:30 -04:00
parent 334ff14e94
commit 9d2fdc00a0
2 changed files with 183 additions and 16 deletions

View file

@ -1,11 +1,13 @@
package com.blarg.gdx.graphics;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
/***
@ -24,12 +26,15 @@ import com.badlogic.gdx.utils.Array;
* </p>
*/
public class DelayedSpriteBatch {
static final Vector3 projTemp = new Vector3();
static final int CAPACITY_INCREMEMT = 128;
Array<Sprite> sprites;
int pointer;
boolean hasBegun;
SpriteBatch spriteBatch;
Camera perspectiveCamera;
int pixelScale;
public DelayedSpriteBatch() {
sprites = new Array<Sprite>(true, CAPACITY_INCREMEMT, Sprite.class);
@ -41,16 +46,24 @@ public class DelayedSpriteBatch {
}
public void begin(SpriteBatch spriteBatch) {
begin(spriteBatch, null, 1);
}
public void begin(SpriteBatch spriteBatch, Camera perspectiveCamera, int pixelScale) {
if (hasBegun)
throw new IllegalStateException("Cannot be called within an existing begin/end block.");
if (spriteBatch == null)
throw new IllegalArgumentException();
this.spriteBatch = spriteBatch;
this.perspectiveCamera = perspectiveCamera;
this.pixelScale = pixelScale;
hasBegun = true;
pointer = 0;
}
/**************************************************************************/
public void draw(Texture texture, float x, float y) {
draw(texture, x, y, texture.getWidth(), texture.getHeight(), Color.WHITE);
}
@ -68,10 +81,33 @@ public class DelayedSpriteBatch {
sprite.setTexture(texture);
sprite.setRegion(0, 0, texture.getWidth(), texture.getHeight());
sprite.setColor(tint);
sprite.setSize(width, height);
sprite.setPosition(x, y);
sprite.setBounds(x, y, width, height);
}
/**************************************************************************/
public void draw(Texture texture, float x, float y, float z) {
draw(texture, x, y, z, texture.getWidth(), texture.getHeight(), Color.WHITE);
}
public void draw(Texture texture, float x, float y, float z, Color tint) {
draw(texture, x, y, z, texture.getWidth(), texture.getHeight(), tint);
}
public void draw(Texture texture, float x, float y, float z, float width, float height) {
draw(texture, x, y, z, width, height, Color.WHITE);
}
public void draw(Texture texture, float x, float y, float z, float width, float height, Color tint) {
Sprite sprite = nextUsable();
sprite.setTexture(texture);
sprite.setRegion(0, 0, texture.getWidth(), texture.getHeight());
sprite.setColor(tint);
setProjectedPositionAndSize(sprite, x, y, z, width, height);
}
/**************************************************************************/
public void draw(Texture texture, float x, float y, float width, float height, float u, float v, float u2, float v2) {
draw(texture, x, y, width, height, u, v, u2, v2, Color.WHITE);
}
@ -81,23 +117,69 @@ public class DelayedSpriteBatch {
sprite.setTexture(texture);
sprite.setRegion(u, v, u2, v2);
sprite.setColor(tint);
sprite.setSize(width, height);
sprite.setPosition(x, y);
sprite.setBounds(x, y, width, height);
}
/**************************************************************************/
public void draw(Texture texture, float x, float y, float z, float width, float height, float u, float v, float u2, float v2) {
draw(texture, x, y, z, width, height, u, v, u2, v2, Color.WHITE);
}
public void draw(Texture texture, float x, float y, float z, float width, float height, float u, float v, float u2, float v2, Color tint) {
Sprite sprite = nextUsable();
sprite.setTexture(texture);
sprite.setRegion(u, v, u2, v2);
sprite.setColor(tint);
setProjectedPositionAndSize(sprite, x, y, z, width, height);
}
/**************************************************************************/
public void draw(Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight) {
draw(texture, x, y, srcX, srcY, srcWidth, srcHeight, Color.WHITE);
draw(texture, x, y, Math.abs(srcWidth), Math.abs(srcHeight), srcX, srcY, srcWidth, srcHeight, Color.WHITE);
}
public void draw(Texture texture, float x, float y, int srcX, int srcY, int srcWidth, int srcHeight, Color tint) {
draw(texture, x, y, Math.abs(srcWidth), Math.abs(srcHeight), srcX, srcY, srcWidth, srcHeight, tint);
}
public void draw(Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight) {
draw(texture, x, y, width, height, srcX, srcY, srcWidth, srcHeight, Color.WHITE);
}
public void draw(Texture texture, float x, float y, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight, Color tint) {
Sprite sprite = nextUsable();
sprite.setTexture(texture);
sprite.setRegion(srcX, srcY, srcWidth, srcHeight);
sprite.setColor(tint);
sprite.setSize(Math.abs(srcWidth), Math.abs(srcHeight));
sprite.setPosition(x, y);
sprite.setBounds(x, y, width, height);
}
/**************************************************************************/
public void draw(Texture texture, float x, float y, float z, int srcX, int srcY, int srcWidth, int srcHeight) {
draw(texture, x, y, z, Math.abs(srcWidth), Math.abs(srcHeight), srcX, srcY, srcWidth, srcHeight, Color.WHITE);
}
public void draw(Texture texture, float x, float y, float z, int srcX, int srcY, int srcWidth, int srcHeight, Color tint) {
draw(texture, x, y, z, Math.abs(srcWidth), Math.abs(srcHeight), srcX, srcY, srcWidth, srcHeight, tint);
}
public void draw(Texture texture, float x, float y, float z, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight) {
draw(texture, x, y, z, width, height, srcX, srcY, srcWidth, srcHeight, Color.WHITE);
}
public void draw(Texture texture, float x, float y, float z, float width, float height, int srcX, int srcY, int srcWidth, int srcHeight, Color tint) {
Sprite sprite = nextUsable();
sprite.setTexture(texture);
sprite.setRegion(srcX, srcY, srcWidth, srcHeight);
sprite.setColor(tint);
setProjectedPositionAndSize(sprite, x, y, z, width, height);
}
/**************************************************************************/
public void draw(TextureRegion region, float x, float y) {
draw(region, x, y, region.getRegionWidth(), region.getRegionWidth(), Color.WHITE);
}
@ -114,20 +196,52 @@ public class DelayedSpriteBatch {
Sprite sprite = nextUsable();
sprite.setRegion(region);
sprite.setColor(tint);
sprite.setSize(width, height);
sprite.setPosition(x, y);
sprite.setBounds(x, y, width, height);
}
/**************************************************************************/
public void draw(TextureRegion region, float x, float y, float z) {
draw(region, x, y, z, region.getRegionWidth(), region.getRegionWidth(), Color.WHITE);
}
public void draw(TextureRegion region, float x, float y, float z, Color tint) {
draw(region, x, y, z, region.getRegionWidth(), region.getRegionWidth(), tint);
}
public void draw(TextureRegion region, float x, float y, float z, float width, float height) {
draw(region, x, y, z, width, height, Color.WHITE);
}
public void draw(TextureRegion region, float x, float y, float z, float width, float height, Color tint) {
Sprite sprite = nextUsable();
sprite.setRegion(region);
sprite.setColor(tint);
setProjectedPositionAndSize(sprite, x, y, z, width, height);
}
/**************************************************************************/
public void draw(BitmapFont font, float x, float y, CharSequence str) {
draw(font, x, y, str, Color.WHITE);
draw(font, x, y, 1.0f, str, Color.WHITE);
}
public void draw(BitmapFont font, float x, float y, CharSequence str, Color tint) {
draw(font, x, y, 1.0f, str, tint);
}
public void draw(BitmapFont font, float x, float y, float scale, CharSequence str) {
draw(font, x, y, scale, str, Color.WHITE);
}
public void draw(BitmapFont font, float x, float y, float scale, CharSequence str, Color tint) {
BitmapFont.BitmapFontData fontData = font.getData();
Texture fontTexture = font.getRegion().getTexture();
float currentX = x;
float currentY = y;
float lineHeight = fontData.lineHeight * scale;
float spaceWidth = fontData.spaceWidth * scale;
for (int i = 0; i < str.length(); ++i) {
char c = str.charAt(i);
@ -136,7 +250,7 @@ public class DelayedSpriteBatch {
if (c == '\r')
continue; // can't render this anyway, and likely a '\n' is right behind ...
if (c == '\n') {
currentY -= fontData.lineHeight;
currentY -= lineHeight;
currentX = x;
continue;
}
@ -144,16 +258,46 @@ public class DelayedSpriteBatch {
BitmapFont.Glyph glyph = fontData.getGlyph(c);
if (glyph == null) {
// TODO: maybe rendering some special char here instead would be better?
currentX += fontData.spaceWidth;
currentX += spaceWidth;
continue;
}
draw(fontTexture, currentX + glyph.xoffset, currentY + glyph.yoffset, glyph.srcX, glyph.srcY, glyph.width, glyph.height, tint);
float glyphWidth = ((float)glyph.width * scale);
float glyphHeight = ((float)glyph.height * scale);
draw(
fontTexture,
currentX + glyph.xoffset, currentY + glyph.yoffset,
glyphWidth, glyphHeight,
glyph.srcX, glyph.srcY, glyph.width, glyph.height,
tint
);
currentX += glyph.xadvance;
currentX += ((float)glyph.xadvance * scale);
}
}
/**************************************************************************/
public void draw(BitmapFont font, float x, float y, float z, float scale, CharSequence str) {
draw(font, x, y, z, scale, str, Color.WHITE);
}
public void draw(BitmapFont font, float x, float y, float z, float scale, CharSequence str, Color tint) {
BitmapFont.TextBounds bounds = font.getMultiLineBounds(str);
float scaledBoundsWidth = bounds.width * scale;
float scaledBoundsHeight = bounds.height * scale;
getProjectedCenteredPosition(x, y, z, scaledBoundsWidth, scaledBoundsHeight, projTemp);
// projected position is used as the position to center the whole text on
projTemp.x -= (scaledBoundsWidth / 2);
projTemp.y += (scaledBoundsHeight / 2);
draw(font, projTemp.x, projTemp.y, scale, str, tint);
}
/**************************************************************************/
public void flush() {
if (!hasBegun)
throw new IllegalStateException("Cannot call outside of a begin/end block.");
@ -177,7 +321,30 @@ public class DelayedSpriteBatch {
flush();
hasBegun = false;
spriteBatch = null; // don't need to hold on to this particular reference anymore
spriteBatch = null; // don't need to hold on to these references anymore
perspectiveCamera = null;
}
private void getProjectedCenteredPosition(float x, float y, float z, float width, float height, Vector3 result) {
if (perspectiveCamera == null)
throw new UnsupportedOperationException("Cannot project 3D coordinates to screen space when no perspective camera is provided.");
result.set(x, y, z);
perspectiveCamera.project(result);
// screen coordinates will be unscaled, need to apply appropriate scaling...
result.x /= pixelScale;
result.y /= pixelScale;
}
private void setProjectedPositionAndSize(Sprite sprite, float x, float y, float z, float width, float height) {
getProjectedCenteredPosition(x, y, z, width, height, projTemp);
// projected position is used as the position to center the rendered sprite on
projTemp.x -= (width / 2);
projTemp.y -= (height / 2);
sprite.setBounds(projTemp.x, projTemp.y, width, height);
}
private void increaseCapacity() {

View file

@ -84,7 +84,7 @@ public class RenderContext implements Disposable {
public void onPreRender() {
spriteBatch.setProjectionMatrix(orthographicCamera.combined);
debugGeometryRenderer.begin(ShapeRenderer.ShapeType.Line);
delayedSpriteBatch.begin(spriteBatch);
delayedSpriteBatch.begin(spriteBatch, perspectiveCamera, pixelScaler.getScale());
billboardSpriteBatch.begin(decalBatch, perspectiveCamera);
modelBatch.begin(perspectiveCamera);
}