font loading update
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-11-20 18:14:26 -05:00
parent fe8466c2f8
commit d84a993739
25 changed files with 390 additions and 54 deletions

View File

@ -14,5 +14,6 @@ void main(){
textColorModifier.y = 1;
textColorModifier.z = 1;
}
FragColor = texture(screenTexture, TexCoords) * vec4(textColorModifier.xyz, 1.0);
vec4 sample = texture(screenTexture, TexCoords);
FragColor = vec4(sample.r) * vec4(textColorModifier.xyz, 1.0);
}

View File

@ -1,3 +1,3 @@
#maven.buildNumber.plugin properties file
#Wed Nov 20 13:22:48 EST 2024
buildNumber=392
#Wed Nov 20 16:01:40 EST 2024
buildNumber=398

View File

@ -1090,6 +1090,8 @@ Fix invalid normals from transvoxel rasterizer
Design storm engine icon
Fix edge-polygon generation for invalid cases
Add engine logo to title menu
Use STBttf for font loading/remove dependency on java.awt.fonts
Fix font height lookups in string carousel, text input, and word
# TODO

View File

@ -7,8 +7,8 @@
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<lwjgl.version>3.3.3</lwjgl.version>
<joml.version>1.9.19</joml.version>
<recast.version>1.5.7</recast.version>

View File

@ -43,31 +43,31 @@ public class MenuGeneratorsTitleMenu {
//label (title)
Label titleLabel = Label.createLabel("ORPG");
Label titleLabel = Label.createLabel("ORPG",3.0f);
optionPanel.addChild(titleLabel);
//button (multiplayer)
optionPanel.addChild(Button.createButtonCentered("Singleplayer", () -> {
optionPanel.addChild(Button.createButtonCentered("Singleplayer", 2.0f, () -> {
WindowUtils.replaceMainMenuContents(MenuGenerators.createWorldSelectMenu());
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (multiplayer)
optionPanel.addChild(Button.createButtonCentered("Multiplayer", () -> {
optionPanel.addChild(Button.createButtonCentered("Multiplayer", 2.0f, () -> {
WindowUtils.replaceMainMenuContents(MenuGenerators.createMultiplayerMenu());
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (static level)
optionPanel.addChild(Button.createButtonCentered("Level Editor", () -> {
optionPanel.addChild(Button.createButtonCentered("Level Editor", 2.0f, () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsLevelEditor.createLevelEditorTopMenu());
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (options)
optionPanel.addChild(Button.createButtonCentered("Options", () -> {
optionPanel.addChild(Button.createButtonCentered("Options", 2.0f, () -> {
WindowUtils.replaceMainMenuContents(MenuGenerators.createOptionsMainMenu());
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (sp debug)
optionPanel.addChild(Button.createButtonCentered("Debug SP Quickstart", () -> {
optionPanel.addChild(Button.createButtonCentered("Debug SP Quickstart", 2.0f, () -> {
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.DEBUG_RANDOM_SP_WORLD);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
@ -75,7 +75,7 @@ public class MenuGeneratorsTitleMenu {
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (sp debug)
optionPanel.addChild(Button.createButtonCentered("Load Test Generation Realm", () -> {
optionPanel.addChild(Button.createButtonCentered("Load Test Generation Realm", 2.0f, () -> {
LoadingThread loadingThread = new LoadingThread(LoadingThreadType.CHUNK_GENERATION_REALM);
Globals.RUN_CLIENT = true;
Globals.RUN_SERVER = true;
@ -83,12 +83,12 @@ public class MenuGeneratorsTitleMenu {
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (ui testing)
optionPanel.addChild(Button.createButtonCentered("UI Testing", () -> {
optionPanel.addChild(Button.createButtonCentered("UI Testing", 2.0f, () -> {
WindowUtils.replaceMainMenuContents(MenuGeneratorsUITesting.createUITestMenu());
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));
//button (Viewport Test)
optionPanel.addChild(Button.createButtonCentered("Viewport Test", () -> {
optionPanel.addChild(Button.createButtonCentered("Viewport Test", 2.0f, () -> {
Globals.threadManager.start(new LoadingThread(LoadingThreadType.LOAD_VIEWPORT));
}).setOnClickAudio(AssetDataStrings.UI_TONE_BUTTON_TITLE));

View File

@ -677,22 +677,22 @@ public class RenderUtils {
//texture coords
FloatBuffer textureArrayBufferData = BufferUtils.createFloatBuffer(12);
textureArrayBufferData.put(0);
textureArrayBufferData.put(0);
textureArrayBufferData.put(0);
textureArrayBufferData.put(1);
textureArrayBufferData.put(1);
textureArrayBufferData.put(1);
textureArrayBufferData.put(0);
textureArrayBufferData.put(0);
textureArrayBufferData.put(1);
textureArrayBufferData.put(0);
textureArrayBufferData.put(0);
textureArrayBufferData.put(1);
textureArrayBufferData.put(1);
textureArrayBufferData.put(0);
textureArrayBufferData.put(1);
textureArrayBufferData.put(1);
textureArrayBufferData.flip();

View File

@ -275,6 +275,44 @@ public class Texture {
}
}
}
/**
* Generates a texture based on a buffer (for use passing data to gpu)
* @param openGlState The OpenGL state
* @param buffer The buffer of data
* @param width the 'width' of the 'texture'
* @param height the 'height' of the 'texture'
*/
public static Texture createBitmap(OpenGLState openGlState, ByteBuffer buffer, int width, int height){
Texture rVal = null;
if(!Globals.HEADLESS){
rVal = new Texture();
//generate the texture object on gpu
rVal.texturePointer = GL40.glGenTextures();
Globals.renderingEngine.checkError();
//bind the new texture
openGlState.glBindTexture(GL_TEXTURE_2D, rVal.getTexturePointer());
//how are we gonna wrap the texture??
rVal.setWrap(openGlState, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
rVal.setWrap(openGlState, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
//disable mipmap
rVal.setMinFilter(openGlState, GL_LINEAR);
rVal.setMagFilter(openGlState, GL_LINEAR);
//call if width != height so opengl figures out how to unpack it properly
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
//GL_RED = 32bit r value
//buffer the texture information
rVal.pixelFormat = GL_RED;
rVal.datatype = GL_FLOAT;
rVal.glTexImage2D(openGlState, GL40.GL_RED, width, height, GL40.GL_RED, GL40.GL_UNSIGNED_BYTE, buffer);
//check build status
String errorMessage = RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError());
if(errorMessage != null){
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Texture Constructor[from bytebuffer]: " + errorMessage));
}
}
return rVal;
}
/**
* Binds the texture to unit 0

View File

@ -10,6 +10,7 @@ import electrosphere.renderer.model.Model;
import electrosphere.renderer.ui.elementtypes.DrawableElement;
import electrosphere.renderer.ui.events.Event;
import electrosphere.renderer.ui.font.Font;
import org.joml.Vector3f;
/**
@ -22,6 +23,8 @@ public class BitmapCharacter extends StandardElement implements DrawableElement
Vector3f color = new Vector3f(1.0f);
Font font;
float fontSize = 1.0f;
/**
@ -33,12 +36,13 @@ public class BitmapCharacter extends StandardElement implements DrawableElement
* @param height
* @param toDraw
*/
public BitmapCharacter(Font font, int width, int height, char toDraw){
public BitmapCharacter(Font font, int width, int height, float fontSize, char toDraw){
super();
setWidth(width);
setHeight(height);
this.text = "" + toDraw;
this.font = font;
this.fontSize = fontSize;
}
/**
@ -52,7 +56,7 @@ public class BitmapCharacter extends StandardElement implements DrawableElement
this.font = font;
Vector3f discreteDims = this.font.getDimensionOfCharacterDiscrete(toDraw);
setMinWidth((int)discreteDims.x);
setMinHeight((int)discreteDims.y);
setMinHeight((int)Math.max(discreteDims.y,this.font.getFontHeight()));
}
@ -81,20 +85,14 @@ public class BitmapCharacter extends StandardElement implements DrawableElement
framebuffer.bind(openGLState);
openGLState.glViewport(framebuffer.getWidth(), framebuffer.getHeight());
float ndcX = (float)this.absoluteToFramebuffer(getAbsoluteX(),framebufferPosX)/framebuffer.getWidth();
float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteY(),framebufferPosY)/framebuffer.getHeight();
float ndcY = (float)this.absoluteToFramebuffer(getAbsoluteYPlacement(),framebufferPosY)/framebuffer.getHeight();
float ndcWidth = (float)getWidth()/framebuffer.getWidth();
float ndcHeight = (float)getHeight()/framebuffer.getHeight();
// float charWidth = ndcWidth/cols;
// float charHeight = ndcHeight/rows;
float ndcHeight = (float)getHeightPlacement()/framebuffer.getHeight();
char toDraw = text.charAt(0);
Vector3f characterPosition = new Vector3f(ndcX,ndcY,0);
Vector3f characterDimensions = new Vector3f(ndcWidth,ndcHeight,0);
Vector3f bitMapPosition = this.font.getPositionOfCharacter(toDraw);
Vector3f bitMapDimension = this.font.getDimensionOfCharacter(toDraw);
// bitMapDimension.y = 1;
// System.out.println(bitMapPosition);
// System.out.println(bitMapDimension);
// System.out.println("\n\n");
//load model and try overwriting with font material
Model charModel = Globals.assetManager.fetchModel(AssetDataStrings.BITMAP_CHARACTER_MODEL);
Material mat = this.font.getMaterial();
@ -109,6 +107,23 @@ public class BitmapCharacter extends StandardElement implements DrawableElement
}
}
/**
* Gets the absolute y to use for placement
* @return The absolute y to use for placement
*/
public int getAbsoluteYPlacement(){
return super.getAbsoluteY() + (int)Math.ceil(this.font.getOffsetY(text.charAt(0)) * this.fontSize);
}
/**
* Gets the height to use for placement
* @return The height to use for placement
*/
public int getHeightPlacement(){
return (int)(Math.ceil(super.getHeight() * this.font.getQuadScalingY(text.charAt(0))));
}
public boolean handleEvent(Event event){
return true;
}

View File

@ -119,6 +119,29 @@ public class Button extends StandardContainerElement implements DrawableElement,
return rVal;
}
/**
* Creates a button that fires a callback when clicked
* @param text The text for the button label
* @param fontSize The size of the font for the label
* @param callback The callback
* @return The button
*/
public static Button createButtonCentered(String text, float fontSize, Runnable callback){
Button rVal = new Button();
Label rValLabel = Label.createLabel(text, fontSize);
rValLabel.setText(text);
rVal.addChild(rValLabel);
rVal.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
callback.run();
if(Globals.virtualAudioSourceManager != null && rVal.audioPathOnClick != null){
Globals.virtualAudioSourceManager.createUI(rVal.audioPathOnClick);
}
return false;
}});
rVal.setAlignSelf(YogaAlignment.Center);
return rVal;
}
public boolean getVisible() {
return visible;
}

View File

@ -43,6 +43,18 @@ public class Label extends StandardContainerElement implements DrawableElement {
return rVal;
}
/**
* Creates a label element
* @param text the text for the label
* @param fontSize The size of the font
* @return the label element
*/
public static Label createLabel(String text, float fontSize){
Label rVal = new Label(fontSize);
rVal.setText(text);
return rVal;
}
/**
* Simplified constructor
* @param fontSize the size of the font (default is 1.0f)
@ -65,13 +77,23 @@ public class Label extends StandardContainerElement implements DrawableElement {
for(int i = 0; i < text.length(); i++){
char toDraw = text.charAt(i);
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), fontSize, toDraw);
accumulatingWidth += bitMapDimension.x * fontSize;
childList.add(newLetter);
Yoga.YGNodeInsertChild(yogaNode, newLetter.getYogaNode(), childList.size() - 1);
}
Yoga.YGNodeStyleSetWidth(yogaNode, accumulatingWidth);
}
/**
* Sets the size of the font for this label
* @param fontSize The size of the font
*/
public void setFontSize(float fontSize){
this.fontSize = fontSize;
this.setHeight((int)(font.getFontHeight() * fontSize));
this.generateLetters();
}
public void setText(String text){
this.text = text;

View File

@ -58,7 +58,7 @@ public class StringCarousel extends StandardContainerElement implements Drawable
super();
this.font = Globals.fontManager.getFont("default");
this.fontSize = fontSize;
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize);
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.getFontHeight() * fontSize);
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
}
@ -68,7 +68,7 @@ public class StringCarousel extends StandardContainerElement implements Drawable
private StringCarousel(){
super();
this.font = Globals.fontManager.getFont("default");
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize);
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.getFontHeight() * fontSize);
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
}
@ -120,7 +120,7 @@ public class StringCarousel extends StandardContainerElement implements Drawable
for(int i = 0; i < textCurrent.length(); i++){
char toDraw = textCurrent.charAt(i);
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), fontSize, toDraw);
accumulatingWidth += bitMapDimension.x * fontSize;
addChild(newLetter);
}

View File

@ -88,7 +88,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
this.color = new Vector3f(1,1,1);
setHeight((int)(font.getFontHeight() * fontSize));
Yoga.YGNodeStyleSetFlexDirection(this.yogaNode, Yoga.YGFlexDirectionRow);
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.imageHeight * fontSize);
Yoga.YGNodeStyleSetMinHeight(this.yogaNode, font.getFontHeight() * fontSize);
Yoga.YGNodeStyleSetMinWidth(this.yogaNode, 1);
}
@ -100,7 +100,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
for(int i = 0; i < text.length(); i++){
char toDraw = text.charAt(i);
Vector3f bitMapDimension = this.font.getDimensionOfCharacterDiscrete(toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), toDraw);
BitmapCharacter newLetter = new BitmapCharacter(this.font,(int)(bitMapDimension.x * fontSize), this.getHeight(), fontSize, toDraw);
newLetter.setColor(color);
this.addChild(newLetter);
}

View File

@ -2,6 +2,8 @@ package electrosphere.renderer.ui.font;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.joml.Vector3f;
import electrosphere.renderer.model.Material;
@ -23,6 +25,8 @@ public class Font {
HashMap<Character,Vector3f> positionMap = new HashMap<Character,Vector3f>();
//the map of character->dimension of the character in pixels
HashMap<Character,Vector3f> dimensionMap = new HashMap<Character,Vector3f>();
Map<Character,Glyph> glyphMap = new HashMap<Character,Glyph>();
/**
* Creates the font object
@ -53,6 +57,8 @@ public class Font {
public int startY;
public int width;
public int height;
public int offsetY = 0;
public float quadScalingY = 1;
}
/**
@ -103,13 +109,45 @@ public class Font {
}
return dimension;
}
/**
* Gets the offset y of the character
* @param c The character
* @return The offset y
*/
public int getOffsetY(Character c){
int rVal = 0;
if(glyphMap.containsKey(c)){
rVal = glyphMap.get(c).offsetY;
}
return rVal;
}
/**
* Gets the quad y scaling of the character
* @param c The character
* @return The scaling
*/
public float getQuadScalingY(Character c){
float rVal = 1.0f;
if(glyphMap.containsKey(c)){
rVal = glyphMap.get(c).quadScalingY;
}
return rVal;
}
/**
* Gets the height of the font
* @return the height
*/
public int getFontHeight(){
return imageHeight;
int maxHeight = 0;
for(Glyph glyph : this.glyphs){
if(glyph.height > maxHeight){
maxHeight = glyph.height;
}
}
return maxHeight;
}
@ -129,6 +167,10 @@ public class Font {
Vector3f dimension = new Vector3f(glyph.width,glyph.height,0);
dimensionMap.put(charVal,dimension);
}
//fill glyph map
for(Glyph glyph: glyphs){
this.glyphMap.put(glyph.symbol.charAt(0),glyph);
}
}
/**

View File

@ -34,22 +34,24 @@ public class FontManager {
* Loads fonts at engine startup during the init graphics resource phase
*/
public void loadFonts(){
java.awt.Font font = null;
try {
font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, FileUtils.getAssetFileAsStream("Fonts/Tuffy_Bold.ttf"));
font = font.deriveFont(24f);
} catch (FontFormatException e) {
LoggerInterface.loggerEngine.ERROR("Failed to load a font!", e);
} catch (IOException e) {
LoggerInterface.loggerEngine.ERROR("Failed to load a font!", e);
}
if(font==null){
font = new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.PLAIN, 16);
}
if(font!=null){
defaultFont = FontUtils.loadFont(Globals.renderingEngine.getOpenGLState(), font, true);
fontMap.put("default",defaultFont);
}
// java.awt.Font font = null;
// try {
// font = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, FileUtils.getAssetFileAsStream("Fonts/Tuffy_Bold.ttf"));
// font = font.deriveFont(24f);
// } catch (FontFormatException e) {
// LoggerInterface.loggerEngine.ERROR("Failed to load a font!", e);
// } catch (IOException e) {
// LoggerInterface.loggerEngine.ERROR("Failed to load a font!", e);
// }
// if(font==null){
// font = new java.awt.Font(java.awt.Font.MONOSPACED, java.awt.Font.PLAIN, 16);
// }
// if(font != null){
// defaultFont = FontUtils.loadFont(Globals.renderingEngine.getOpenGLState(), font, true);
// fontMap.put("default",defaultFont);
// }
defaultFont = FontUtils.loadTTF(Globals.renderingEngine.getOpenGLState(), "Fonts/Tuffy_Bold.ttf");
fontMap.put("default",defaultFont);
}
}

View File

@ -1,10 +1,24 @@
package electrosphere.renderer.ui.font;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.model.Material;
import electrosphere.renderer.texture.Texture;
import electrosphere.util.FileUtils;
import org.lwjgl.BufferUtils;
import org.lwjgl.stb.STBTTAlignedQuad;
import org.lwjgl.stb.STBTTFontinfo;
import org.lwjgl.stb.STBTTPackContext;
import org.lwjgl.stb.STBTTPackedchar;
import org.lwjgl.stb.STBTruetype;
import org.lwjgl.system.MemoryStack;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.awt.RenderingHints;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
@ -17,6 +31,29 @@ import java.util.List;
*/
public class FontUtils {
public static final int TTF_CHAR_WIDTH = 32;
public static final int TTF_CHAR_HEIGHT = 24;
static final char FIRST_CHAR_TO_BAKE = 32;
static final char LAST_CHAR_TO_BAKE = 127;
static final int CHAR_COUNT = LAST_CHAR_TO_BAKE - FIRST_CHAR_TO_BAKE;
static final int TTF_BITMAP_WIDTH = 512;
static final int TTF_BITMAP_HEIGHT = 512;
static final int SPACE_WIDTH = 8;
/**
* Manual offset to align them
*/
static final int MANUAL_OFFSET = -2;
/**
* The factor to adjust the descent by. Just intuiting this from how the data looks, not guaranteed to be correct
*/
static final int DESCENT_DIVISOR = 100;
static float[] scale = new float[]{
TTF_CHAR_HEIGHT,
};
/**
* Renders a single character to a buffered image
@ -157,5 +194,136 @@ public class FontUtils {
return rVal;
}
/**
* Loads the TTF font
* @param openGLState The opengl state
* @param path The path to the ttf font file
* @return The font if it loaded successfully, null otherwise
*/
protected static Font loadTTF(OpenGLState openGLState, String path){
//used for cosntructing the font object to return
List<Font.Glyph> glyphs = new LinkedList<Font.Glyph>();
Material uiMat = new Material();
//read the file
ByteBuffer fileContent = null;
try {
fileContent = FileUtils.getAssetFileAsByteBuffer(path);
} catch (IOException e) {
LoggerInterface.loggerFileIO.ERROR("Failed to read font file", e);
}
if(fileContent == null){
return null;
}
//load info about the file
STBTTFontinfo info = STBTTFontinfo.create();
if(!STBTruetype.stbtt_InitFont(info, fileContent)){
throw new Error("Failed to init font info!");
}
int descent = 0;
try(MemoryStack stack = MemoryStack.stackPush()){
IntBuffer ascentBuff = stack.mallocInt(1);
IntBuffer descentBuff = stack.mallocInt(1);
IntBuffer lineGapBuff = stack.mallocInt(1);
//get data on the font
STBTruetype.stbtt_GetFontVMetrics(info, ascentBuff, descentBuff, lineGapBuff);
// int ascent = ascentBuff.get(0);
descent = descentBuff.get(0);
// int lineGap = lineGapBuff.get(0);
}
try(STBTTPackContext packContext = STBTTPackContext.malloc()){
//get char data
STBTTPackedchar.Buffer charData = STBTTPackedchar.malloc(6 * 128);
ByteBuffer bakedTextureData = BufferUtils.createByteBuffer(TTF_BITMAP_WIDTH * TTF_BITMAP_HEIGHT);
STBTruetype.stbtt_PackBegin(packContext, bakedTextureData, TTF_BITMAP_WIDTH, TTF_BITMAP_HEIGHT, 0, 1);
//make image
for(int i = 0; i < scale.length; i++){
int p = (i * 3 + 0) * CHAR_COUNT + FIRST_CHAR_TO_BAKE;
charData.limit(p + 95);
charData.position(p);
STBTruetype.stbtt_PackSetOversampling(packContext, 1, 1);
STBTruetype.stbtt_PackFontRange(packContext, fileContent, 0, scale[i], FIRST_CHAR_TO_BAKE, charData);
p = (i * 3 + 1) * CHAR_COUNT + FIRST_CHAR_TO_BAKE;
charData.limit(p + 95);
charData.position(p);
STBTruetype.stbtt_PackSetOversampling(packContext, 2, 2);
STBTruetype.stbtt_PackFontRange(packContext, fileContent, 0, scale[i], FIRST_CHAR_TO_BAKE, charData);
p = (i * 3 + 2) * CHAR_COUNT + FIRST_CHAR_TO_BAKE;
charData.limit(p + 95);
charData.position(p);
STBTruetype.stbtt_PackSetOversampling(packContext, 3, 1);
STBTruetype.stbtt_PackFontRange(packContext, fileContent, 0, scale[i], FIRST_CHAR_TO_BAKE, charData);
}
charData.clear();
STBTruetype.stbtt_PackEnd(packContext);
//create the bitmap image off of the raw texture data
Texture texture = Texture.createBitmap(openGLState, bakedTextureData, TTF_BITMAP_WIDTH, TTF_BITMAP_HEIGHT);
uiMat.setTexturePointer(texture.getTexturePointer());
//parse the glyphs
try(MemoryStack stack = MemoryStack.stackPush()){
STBTTAlignedQuad quad = STBTTAlignedQuad.malloc(stack);
FloatBuffer xPos = stack.floats(0.0f);
FloatBuffer yPos = stack.floats(0.0f);
for (int i = FIRST_CHAR_TO_BAKE; i < LAST_CHAR_TO_BAKE; i++) {
xPos.put(0,0);
yPos.put(0,0);
if (i == 127) {
//skip del character command
continue;
}
STBTruetype.stbtt_GetPackedQuad(charData, TTF_BITMAP_WIDTH, TTF_BITMAP_HEIGHT, i, xPos, yPos, quad, false);
// float charX = xPos.get(0);
// float charY = yPos.get(0);
// float x0 = quad.x0();
// float x1 = quad.x1();
// float y0 = quad.y0();
// float y1 = quad.y1();
// float s0 = quad.s0();
// float s1 = quad.s1();
// float t0 = quad.t0();
// float t1 = quad.t1();
//create glyph and push it into the array
Font.Glyph glyph = new Font.Glyph();
glyph.width = (int)((quad.s1() - quad.s0()) * TTF_BITMAP_WIDTH);
glyph.height = (int)Math.ceil((quad.t1() - quad.t0()) * TTF_BITMAP_HEIGHT);
glyph.startX = (int)(quad.s0() * TTF_BITMAP_WIDTH);
glyph.startY = (int)Math.ceil((quad.t0() * TTF_BITMAP_HEIGHT));
glyph.offsetY = (int)(TTF_CHAR_HEIGHT + quad.y0()) + (descent / DESCENT_DIVISOR) + MANUAL_OFFSET;
glyph.quadScalingY = (quad.y1() - quad.y0()) / (float)TTF_CHAR_HEIGHT;
glyph.symbol = (char)i + "";
if(i == 32){
glyph.width = SPACE_WIDTH;
}
glyphs.add(glyph);
// if(i == 110 || i == 100 || i == 76 || i == 82){
// System.out.println((char)i + "");
// }
}
}
}
//construct final font object and return
Font rVal = new Font(uiMat,glyphs,TTF_BITMAP_WIDTH,TTF_BITMAP_HEIGHT);
rVal.process();
return rVal;
}
}

View File

@ -21,6 +21,8 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -32,6 +34,8 @@ import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import org.lwjgl.BufferUtils;
/**
* Utilities for dealing with files
*/
@ -186,6 +190,25 @@ public class FileUtils {
return targetFile;
}
/**
* Gets an assets file as a byte buffer
* @param pathName The relative path in the assets folder
* @return The byte buffer containing the contents of the asset file
* @throws IOException Thrown if there are any io issues
*/
public static ByteBuffer getAssetFileAsByteBuffer(String pathName) throws IOException{
String sanitizedFilePath = sanitizeFilePath(pathName);
File targetFile = new File("./assets" + sanitizedFilePath);
ByteBuffer buff = null;
try(SeekableByteChannel byteChannel = Files.newByteChannel(targetFile.toPath())){
buff = BufferUtils.createByteBuffer((int)(byteChannel.size() + 1));
while(byteChannel.read(buff) != -1){
}
buff.flip();
}
return buff;
}
/**
* Gets a cache file
* @param pathName The relative path in the cache folder

View File

@ -14,7 +14,7 @@ public class BitmapCharacterTests extends UITestTemplate {
public void test_Create(){
//setup
this.setupBlankView();
BitmapCharacter el = new BitmapCharacter(Globals.fontManager.getFont("default"), 16, 24, 'A');
BitmapCharacter el = new BitmapCharacter(Globals.fontManager.getFont("default"), 16, 24, 1.0f, 'A');
WindowUtils.replaceMainMenuContents(el);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 70 KiB