Using MC resource provider to get Unifont to allow changing it in resource packs (and code for re-generating char lookup texture accordingly).

This commit is contained in:
Florian Nücke 2014-07-21 14:36:50 +02:00
parent 48516beebd
commit 2f46c07ed5
3 changed files with 87 additions and 31 deletions

View File

@ -2,6 +2,8 @@ package li.cil.oc.client.renderer.font
import li.cil.oc.client.renderer.font.DynamicFontRenderer.CharTexture
import li.cil.oc.util.{FontUtil, RenderState}
import net.minecraft.client.Minecraft
import net.minecraft.client.resources.{ReloadableResourceManager, ResourceManager, ResourceManagerReloadListener}
import org.lwjgl.BufferUtils
import org.lwjgl.opengl._
@ -11,16 +13,37 @@ import scala.collection.mutable
* Font renderer that dynamically generates lookup textures by rendering a font
* to it. It's pretty broken right now, and font rendering looks crappy as hell.
*/
class DynamicFontRenderer extends TextureFontRenderer {
private val glyphProvider = new FontParserUnifont()
class DynamicFontRenderer extends TextureFontRenderer with ResourceManagerReloadListener {
private val glyphProvider: IGlyphProvider = new FontParserUnifont()
private val textures = mutable.ArrayBuffer(new DynamicFontRenderer.CharTexture(this))
private val textures = mutable.ArrayBuffer.empty[CharTexture]
private val charMap = mutable.Map.empty[Char, DynamicFontRenderer.CharIcon]
var activeTexture: CharTexture = textures(0)
private var activeTexture: CharTexture = _
generateChars(basicChars.toCharArray)
initialize()
Minecraft.getMinecraft.getResourceManager match {
case reloadable: ReloadableResourceManager => reloadable.registerReloadListener(this)
case _ =>
}
def initialize() {
for (texture <- textures) {
texture.delete()
}
textures.clear()
charMap.clear()
textures += new DynamicFontRenderer.CharTexture(this)
activeTexture = textures(0)
generateChars(basicChars.toCharArray)
}
def onResourceManagerReload(manager: ResourceManager) {
glyphProvider.initialize()
initialize()
}
override protected def charWidth = glyphProvider.getGlyphWidth
@ -40,7 +63,7 @@ class DynamicFontRenderer extends TextureFontRenderer {
override protected def drawChar(tx: Float, ty: Float, char: Char) {
val icon = charMap(char)
if (icon.texture == activeTexture) {
if (icon != null && icon.texture == activeTexture) {
icon.draw(tx, ty)
}
}
@ -84,6 +107,10 @@ object DynamicFontRenderer {
private var chars = 0
def delete() {
GL11.glDeleteTextures(id)
}
def bind() {
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id)
}

View File

@ -1,39 +1,64 @@
package li.cil.oc.client.renderer.font;
import li.cil.oc.OpenComputers;
import li.cil.oc.Settings;
import net.minecraft.client.Minecraft;
import net.minecraft.util.ResourceLocation;
import org.lwjgl.BufferUtils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.util.logging.Level;
public class FontParserUnifont implements IGlyphProvider {
private final byte[][] glyphs;
public FontParserUnifont() throws Exception {
OpenComputers.log().info("Initialized Unifont glyph provider.");
glyphs = new byte[65536][];
final InputStream font = getClass().getResourceAsStream("/assets/opencomputers/unifont.hex");
final BufferedReader input = new BufferedReader(new InputStreamReader(font));
String line;
int glyphCount = 0;
while ((line = input.readLine()) != null) {
glyphCount++;
final String[] info = line.split(":");
final int charCode = Integer.parseInt(info[0], 16);
final byte[] glyph = new byte[info[1].length() >> 1];
for (int i = 0; i < glyph.length; i++) {
glyph[i] = (byte) Integer.parseInt(info[1].substring(i * 2, i * 2 + 2), 16);
}
glyphs[charCode] = glyph;
}
OpenComputers.log().info("Loaded " + glyphCount + " glyphs.");
}
private static final byte[] b_set = {(byte) 255, (byte) 255, (byte) 255, (byte) 255};
private static final byte[] b_unset = {0, 0, 0, 0};
private final byte[][] glyphs = new byte[65536][];
public FontParserUnifont() {
initialize();
}
@Override
public void initialize() {
for (int i = 0; i < glyphs.length; ++i) {
glyphs[i] = null;
}
final InputStream font = Minecraft.getMinecraft().getResourceManager().getResource(new ResourceLocation(Settings.resourceDomain(), "unifont.hex")).getInputStream();
if (font == null) {
OpenComputers.log().warning("Failed opening unifont file.");
return;
}
try {
OpenComputers.log().info("Initialized Unifont glyph provider.");
final BufferedReader input = new BufferedReader(new InputStreamReader(font));
String line;
int glyphCount = 0;
while ((line = input.readLine()) != null) {
glyphCount++;
final String[] info = line.split(":");
final int charCode = Integer.parseInt(info[0], 16);
final byte[] glyph = new byte[info[1].length() >> 1];
for (int i = 0; i < glyph.length; i++) {
glyph[i] = (byte) Integer.parseInt(info[1].substring(i * 2, i * 2 + 2), 16);
}
glyphs[charCode] = glyph;
}
OpenComputers.log().info("Loaded " + glyphCount + " glyphs.");
} catch (IOException ex) {
OpenComputers.log().log(Level.WARNING, "Failed loading glyphs.", ex);
} finally {
try {
font.close();
} catch (IOException ignored) {
}
}
}
@Override
public ByteBuffer getGlyph(int charCode) {
if (charCode >= 65536 || glyphs[charCode] == null || glyphs[charCode].length == 0)

View File

@ -3,7 +3,11 @@ package li.cil.oc.client.renderer.font;
import java.nio.ByteBuffer;
public interface IGlyphProvider {
public ByteBuffer getGlyph(int charCode);
public int getGlyphWidth();
public int getGlyphHeight();
public void initialize();
public ByteBuffer getGlyph(int charCode);
public int getGlyphWidth();
public int getGlyphHeight();
}