add 3d projected coordinate support for sprite rendering methods, refactor a bit, add some more overloads mainly for convenience
This commit is contained in:
parent
334ff14e94
commit
9d2fdc00a0
|
@ -1,11 +1,13 @@
|
||||||
package com.blarg.gdx.graphics;
|
package com.blarg.gdx.graphics;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Camera;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
import com.badlogic.gdx.graphics.g2d.Sprite;
|
import com.badlogic.gdx.graphics.g2d.Sprite;
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.math.Vector3;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -24,12 +26,15 @@ import com.badlogic.gdx.utils.Array;
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class DelayedSpriteBatch {
|
public class DelayedSpriteBatch {
|
||||||
|
static final Vector3 projTemp = new Vector3();
|
||||||
static final int CAPACITY_INCREMEMT = 128;
|
static final int CAPACITY_INCREMEMT = 128;
|
||||||
|
|
||||||
Array<Sprite> sprites;
|
Array<Sprite> sprites;
|
||||||
int pointer;
|
int pointer;
|
||||||
boolean hasBegun;
|
boolean hasBegun;
|
||||||
SpriteBatch spriteBatch;
|
SpriteBatch spriteBatch;
|
||||||
|
Camera perspectiveCamera;
|
||||||
|
int pixelScale;
|
||||||
|
|
||||||
public DelayedSpriteBatch() {
|
public DelayedSpriteBatch() {
|
||||||
sprites = new Array<Sprite>(true, CAPACITY_INCREMEMT, Sprite.class);
|
sprites = new Array<Sprite>(true, CAPACITY_INCREMEMT, Sprite.class);
|
||||||
|
@ -41,16 +46,24 @@ public class DelayedSpriteBatch {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void begin(SpriteBatch spriteBatch) {
|
public void begin(SpriteBatch spriteBatch) {
|
||||||
|
begin(spriteBatch, null, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void begin(SpriteBatch spriteBatch, Camera perspectiveCamera, int pixelScale) {
|
||||||
if (hasBegun)
|
if (hasBegun)
|
||||||
throw new IllegalStateException("Cannot be called within an existing begin/end block.");
|
throw new IllegalStateException("Cannot be called within an existing begin/end block.");
|
||||||
if (spriteBatch == null)
|
if (spriteBatch == null)
|
||||||
throw new IllegalArgumentException();
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
this.spriteBatch = spriteBatch;
|
this.spriteBatch = spriteBatch;
|
||||||
|
this.perspectiveCamera = perspectiveCamera;
|
||||||
|
this.pixelScale = pixelScale;
|
||||||
hasBegun = true;
|
hasBegun = true;
|
||||||
pointer = 0;
|
pointer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
public void draw(Texture texture, float x, float y) {
|
public void draw(Texture texture, float x, float y) {
|
||||||
draw(texture, x, y, texture.getWidth(), texture.getHeight(), Color.WHITE);
|
draw(texture, x, y, texture.getWidth(), texture.getHeight(), Color.WHITE);
|
||||||
}
|
}
|
||||||
|
@ -68,10 +81,33 @@ public class DelayedSpriteBatch {
|
||||||
sprite.setTexture(texture);
|
sprite.setTexture(texture);
|
||||||
sprite.setRegion(0, 0, texture.getWidth(), texture.getHeight());
|
sprite.setRegion(0, 0, texture.getWidth(), texture.getHeight());
|
||||||
sprite.setColor(tint);
|
sprite.setColor(tint);
|
||||||
sprite.setSize(width, height);
|
sprite.setBounds(x, y, width, height);
|
||||||
sprite.setPosition(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
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) {
|
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);
|
draw(texture, x, y, width, height, u, v, u2, v2, Color.WHITE);
|
||||||
}
|
}
|
||||||
|
@ -81,23 +117,69 @@ public class DelayedSpriteBatch {
|
||||||
sprite.setTexture(texture);
|
sprite.setTexture(texture);
|
||||||
sprite.setRegion(u, v, u2, v2);
|
sprite.setRegion(u, v, u2, v2);
|
||||||
sprite.setColor(tint);
|
sprite.setColor(tint);
|
||||||
sprite.setSize(width, height);
|
sprite.setBounds(x, y, width, height);
|
||||||
sprite.setPosition(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
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) {
|
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) {
|
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 sprite = nextUsable();
|
||||||
sprite.setTexture(texture);
|
sprite.setTexture(texture);
|
||||||
sprite.setRegion(srcX, srcY, srcWidth, srcHeight);
|
sprite.setRegion(srcX, srcY, srcWidth, srcHeight);
|
||||||
sprite.setColor(tint);
|
sprite.setColor(tint);
|
||||||
sprite.setSize(Math.abs(srcWidth), Math.abs(srcHeight));
|
sprite.setBounds(x, y, width, height);
|
||||||
sprite.setPosition(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
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) {
|
public void draw(TextureRegion region, float x, float y) {
|
||||||
draw(region, x, y, region.getRegionWidth(), region.getRegionWidth(), Color.WHITE);
|
draw(region, x, y, region.getRegionWidth(), region.getRegionWidth(), Color.WHITE);
|
||||||
}
|
}
|
||||||
|
@ -114,20 +196,52 @@ public class DelayedSpriteBatch {
|
||||||
Sprite sprite = nextUsable();
|
Sprite sprite = nextUsable();
|
||||||
sprite.setRegion(region);
|
sprite.setRegion(region);
|
||||||
sprite.setColor(tint);
|
sprite.setColor(tint);
|
||||||
sprite.setSize(width, height);
|
sprite.setBounds(x, y, width, height);
|
||||||
sprite.setPosition(x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
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) {
|
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) {
|
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();
|
BitmapFont.BitmapFontData fontData = font.getData();
|
||||||
Texture fontTexture = font.getRegion().getTexture();
|
Texture fontTexture = font.getRegion().getTexture();
|
||||||
|
|
||||||
float currentX = x;
|
float currentX = x;
|
||||||
float currentY = y;
|
float currentY = y;
|
||||||
|
float lineHeight = fontData.lineHeight * scale;
|
||||||
|
float spaceWidth = fontData.spaceWidth * scale;
|
||||||
|
|
||||||
for (int i = 0; i < str.length(); ++i) {
|
for (int i = 0; i < str.length(); ++i) {
|
||||||
char c = str.charAt(i);
|
char c = str.charAt(i);
|
||||||
|
@ -136,7 +250,7 @@ public class DelayedSpriteBatch {
|
||||||
if (c == '\r')
|
if (c == '\r')
|
||||||
continue; // can't render this anyway, and likely a '\n' is right behind ...
|
continue; // can't render this anyway, and likely a '\n' is right behind ...
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
currentY -= fontData.lineHeight;
|
currentY -= lineHeight;
|
||||||
currentX = x;
|
currentX = x;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -144,16 +258,46 @@ public class DelayedSpriteBatch {
|
||||||
BitmapFont.Glyph glyph = fontData.getGlyph(c);
|
BitmapFont.Glyph glyph = fontData.getGlyph(c);
|
||||||
if (glyph == null) {
|
if (glyph == null) {
|
||||||
// TODO: maybe rendering some special char here instead would be better?
|
// TODO: maybe rendering some special char here instead would be better?
|
||||||
currentX += fontData.spaceWidth;
|
currentX += spaceWidth;
|
||||||
continue;
|
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() {
|
public void flush() {
|
||||||
if (!hasBegun)
|
if (!hasBegun)
|
||||||
throw new IllegalStateException("Cannot call outside of a begin/end block.");
|
throw new IllegalStateException("Cannot call outside of a begin/end block.");
|
||||||
|
@ -177,7 +321,30 @@ public class DelayedSpriteBatch {
|
||||||
flush();
|
flush();
|
||||||
|
|
||||||
hasBegun = false;
|
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() {
|
private void increaseCapacity() {
|
||||||
|
|
|
@ -84,7 +84,7 @@ public class RenderContext implements Disposable {
|
||||||
public void onPreRender() {
|
public void onPreRender() {
|
||||||
spriteBatch.setProjectionMatrix(orthographicCamera.combined);
|
spriteBatch.setProjectionMatrix(orthographicCamera.combined);
|
||||||
debugGeometryRenderer.begin(ShapeRenderer.ShapeType.Line);
|
debugGeometryRenderer.begin(ShapeRenderer.ShapeType.Line);
|
||||||
delayedSpriteBatch.begin(spriteBatch);
|
delayedSpriteBatch.begin(spriteBatch, perspectiveCamera, pixelScaler.getScale());
|
||||||
billboardSpriteBatch.begin(decalBatch, perspectiveCamera);
|
billboardSpriteBatch.begin(decalBatch, perspectiveCamera);
|
||||||
modelBatch.begin(perspectiveCamera);
|
modelBatch.begin(perspectiveCamera);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue