Skip to content

Commit

Permalink
Add support for rendering BitmapFonts in 3D
Browse files Browse the repository at this point in the history
  • Loading branch information
Evrim Öztamur committed Sep 28, 2020
1 parent 8e007af commit d604a48
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Dungeoneer/assets/data/entities.dat
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
entities:{
"Features": {
"NeoText": {
class: com.interrupt.dungeoneer.entities.NeoText
}
}
"Areas": {
"Spawn Blocker": {
class:com.interrupt.dungeoneer.entities.areas.SpawnBlockerArea,
Expand Down
18 changes: 18 additions & 0 deletions Dungeoneer/src/com/interrupt/dungeoneer/entities/NeoText.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.interrupt.dungeoneer.entities;

import com.badlogic.gdx.graphics.Color;
import com.interrupt.dungeoneer.annotations.EditorProperty;
import com.interrupt.dungeoneer.gfx.drawables.DrawableText;

public class NeoText extends DirectionalEntity {

@EditorProperty
public String text = "Test";

@EditorProperty
public Color textColor = Color.WHITE;

public NeoText() {
this.drawable = new DrawableText(this.text);
}
}
87 changes: 82 additions & 5 deletions Dungeoneer/src/com/interrupt/dungeoneer/gfx/GlRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,7 @@
import com.interrupt.dungeoneer.entities.triggers.TriggeredShop;
import com.interrupt.dungeoneer.game.*;
import com.interrupt.dungeoneer.gfx.decals.DDecal;
import com.interrupt.dungeoneer.gfx.drawables.DrawableBeam;
import com.interrupt.dungeoneer.gfx.drawables.DrawableMesh;
import com.interrupt.dungeoneer.gfx.drawables.DrawableProjectedDecal;
import com.interrupt.dungeoneer.gfx.drawables.DrawableSprite;
import com.interrupt.dungeoneer.gfx.drawables.*;
import com.interrupt.dungeoneer.gfx.shaders.ShaderInfo;
import com.interrupt.dungeoneer.gfx.shaders.WaterShaderInfo;
import com.interrupt.dungeoneer.overlays.OverlayManager;
Expand Down Expand Up @@ -130,6 +127,9 @@ public class GlRenderer {

public SpriteBatch uiBatch;

public Array<DrawableText> textToRender = new Array<>();
public SpriteBatch textBatch;

protected ArrayMap<String, DecalBatch> opaqueSpriteBatches = new ArrayMap<String, DecalBatch>();
protected ArrayMap<String, DecalBatch> transparentSpriteBatches = new ArrayMap<String, DecalBatch>();

Expand Down Expand Up @@ -396,6 +396,8 @@ public void init() {
uiBatch = new SpriteBatch();
uiBatch.setShader(uiShader);

textBatch = new SpriteBatch();

postProcessBatch = new SpriteBatch();
postProcessBatch.disableBlending();

Expand Down Expand Up @@ -778,6 +780,69 @@ public void updateShaderAttributes() {
}
}

public void renderTextBatches() {
ShaderProgram activeProgram;

if (renderingForPicking) {
activeProgram = ShaderManager.getShaderManager().getCompiledShader("picking").shader;
} else {
activeProgram = smoothLighting;
}

textBatch.setShader(activeProgram);

try {
int pvMatrixLoc = activeProgram.getUniformLocation("u_projectionViewMatrix");

for (int i = 0; i < textToRender.size; i++) {
DrawableText dT = textToRender.get(i);

textBatch.begin();

Gdx.gl.glDepthMask(true); // SpriteBatch.begin() forces off depth writing, which we need for 3D space.

Vector3 position = dT.parentPosition.cpy().add(dT.drawOffset);

if (renderingForPicking) {
font.setColor(dT.pickingColor);
} else {
if (dT.editorState == Entity.EditorState.hovered) {
font.setColor(Color.SKY);
} else {
font.setColor(dT.worldColor.cpy().mul(dT.color)); // How to 'light' this correctly?
}
}

GlyphLayout layout = font.draw(textBatch, dT.text, 0, 0);

float scale = 0.025f * dT.scale;
Matrix4 pvmMatrix = camera.combined.cpy() // Calculate a new matrix to override the already-set uniform.
.translate(position.x, position.z, position.y)
.rotate(new Quaternion().setEulerAngles(dT.parentRotation.z, dT.parentRotation.y, dT.parentRotation.x))
.scale(scale, scale, scale)
.translate( -layout.width / 2, 0, 0); // Center text on origin.

activeProgram.setUniformMatrix(pvMatrixLoc, pvmMatrix);

if (dT.editorState == Entity.EditorState.picked) {
textBatch.flush();

font.setColor(Color.CORAL);
font.draw(textBatch, dT.text, 0, 0);

activeProgram.setUniformMatrix(pvMatrixLoc, pvmMatrix.translate(0, 0, -0.2f));
}

textBatch.end();
}

activeProgram.setUniformMatrix(pvMatrixLoc, camera.combined); // Reset the projection matrix.

textToRender.clear();
}
catch(Exception ex) { }
}

public void renderOpaqueSprites() {
try {
for (int i = 0; i < opaqueSpriteBatches.size; i++) {
Expand Down Expand Up @@ -1057,6 +1122,7 @@ public void renderEntities(Level level) {
}

renderOpaqueSprites();
renderTextBatches();
}

public void renderEntitiesForPicking(Level level) {
Expand Down Expand Up @@ -1094,6 +1160,7 @@ public void renderEntitiesForPicking(Level level) {
}

renderOpaqueSprites();
renderTextBatches();

renderingForPicking = false;
}
Expand Down Expand Up @@ -1501,6 +1568,10 @@ else if(s.drawable instanceof DrawableSprite)
else
renderDrawableSprite(s.x, s.y, s.z, false, s, (DrawableSprite)s.drawable);
}

else if(s.drawable instanceof DrawableText) {
renderDrawableText(s.x, s.y, s.z, s, (DrawableText)s.drawable);
}
else if(s.drawable instanceof DrawableBeam) {
renderDrawableBeam(s.x, s.y, s.z, (DrawableBeam)s.drawable);
}
Expand Down Expand Up @@ -2237,7 +2308,6 @@ else if(drawable.billboard) {
}
else {
Color lightmap = GetLightmapAt(x + drawable.drawOffset.x, z, y + drawable.drawOffset.y);

if(drawable.colorLastFrame != null) {
drawable.colorLastFrame.lerp(lightmap.r, lightmap.g, lightmap.b, 1f, 4.5f * Gdx.graphics.getDeltaTime());
sd.setColor(drawable.colorLastFrame.r, drawable.colorLastFrame.g, drawable.colorLastFrame.b, drawable.color.a);
Expand Down Expand Up @@ -2296,6 +2366,13 @@ else if(drawable.billboard) {
usedDecals.add(sd);
}

public void renderDrawableText(float x, float y, float z, Entity entity, DrawableText drawable)
{
drawable.worldColor.set(GetLightmapAt(x + drawable.drawOffset.x, z, y + drawable.drawOffset.y));
drawable.pickingColor.set(entityPickColor);
textToRender.add(drawable);
}

Vector3 t_beam_axis = new Vector3();
Vector3 beam_tmp = new Vector3();
Vector3 t_beam_look = new Vector3();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.interrupt.dungeoneer.gfx.drawables;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.math.Vector3;
import com.interrupt.dungeoneer.entities.Entity;
import com.interrupt.dungeoneer.entities.NeoText;

public class DrawableText extends Drawable {

public String text = "";
public Color worldColor = Color.WHITE;
public Vector3 parentPosition = new Vector3();
public Vector3 parentRotation = new Vector3();
public Entity.EditorState editorState = Entity.EditorState.hovered;
public Color pickingColor = Color.BLACK;

public DrawableText() {
}

public DrawableText(String text) {
this.text = text;
}

public void update(Entity e) {
if (e instanceof NeoText) {
text = ((NeoText) e).text;
color.set(((NeoText) e).textColor);
}

scale = e.scale;

parentPosition.set(e.x, e.y, e.z);
parentRotation.set(e.getRotation());

editorState = e.editorState;
}
}

0 comments on commit d604a48

Please sign in to comment.