Fix font rendering
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
info face="m6x11 Medium" size=16 bold=0 italic=0 charset="unic" unicode=1 padding=4,4,4,4 spacing=0,0
|
||||
common lineHeight=15.4375 base=11 ascent=11 descent=-3 scaleW=256 scaleH=128 pages=1 packed=0
|
||||
page id=0 file="Unknown.png"
|
||||
chars count=95
|
||||
char id=32 x=20 y=95 width=9 height=9 xoffset=0 yoffset=11 xadvance=5 page=1 chnl=15
|
||||
char id=33 x=108 y=60 width=10 height=19 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=34 x=217 y=79 width=13 height=11 xoffset=0 yoffset=0 xadvance=6 page=1 chnl=15
|
||||
char id=35 x=176 y=0 width=15 height=19 xoffset=0 yoffset=0 xadvance=8 page=1 chnl=15
|
||||
char id=36 x=96 y=0 width=14 height=20 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=37 x=199 y=60 width=14 height=16 xoffset=0 yoffset=2 xadvance=7 page=1 chnl=15
|
||||
char id=38 x=127 y=0 width=17 height=19 xoffset=0 yoffset=0 xadvance=10 page=1 chnl=15
|
||||
char id=39 x=240 y=79 width=10 height=11 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=40 x=62 y=0 width=12 height=21 xoffset=0 yoffset=0 xadvance=5 page=1 chnl=15
|
||||
char id=41 x=74 y=0 width=12 height=21 xoffset=0 yoffset=0 xadvance=5 page=1 chnl=15
|
||||
char id=42 x=204 y=79 width=13 height=13 xoffset=0 yoffset=0 xadvance=6 page=1 chnl=15
|
||||
char id=43 x=120 y=79 width=14 height=14 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=44 x=230 y=79 width=10 height=11 xoffset=0 yoffset=9 xadvance=3 page=1 chnl=15
|
||||
char id=45 x=190 y=79 width=14 height=10 xoffset=0 yoffset=5 xadvance=7 page=1 chnl=15
|
||||
char id=46 x=10 y=95 width=10 height=10 xoffset=0 yoffset=9 xadvance=3 page=1 chnl=15
|
||||
char id=47 x=70 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=48 x=84 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=49 x=98 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=50 x=112 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=51 x=126 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=52 x=140 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=53 x=154 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=54 x=168 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=55 x=182 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=56 x=14 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=57 x=210 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=58 x=110 y=79 width=10 height=16 xoffset=0 yoffset=3 xadvance=3 page=1 chnl=15
|
||||
char id=59 x=128 y=60 width=10 height=17 xoffset=0 yoffset=3 xadvance=3 page=1 chnl=15
|
||||
char id=60 x=84 y=79 width=13 height=16 xoffset=0 yoffset=3 xadvance=6 page=1 chnl=15
|
||||
char id=61 x=134 y=79 width=14 height=14 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=62 x=97 y=79 width=13 height=16 xoffset=0 yoffset=3 xadvance=6 page=1 chnl=15
|
||||
char id=63 x=28 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=64 x=110 y=0 width=17 height=19 xoffset=0 yoffset=0 xadvance=10 page=1 chnl=15
|
||||
char id=65 x=42 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=66 x=56 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=67 x=70 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=68 x=84 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=69 x=140 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=70 x=235 y=0 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=71 x=0 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=72 x=14 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=73 x=28 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=74 x=42 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=75 x=56 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=76 x=70 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=77 x=160 y=0 width=16 height=19 xoffset=0 yoffset=0 xadvance=9 page=1 chnl=15
|
||||
char id=78 x=84 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=79 x=98 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=80 x=112 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=81 x=206 y=0 width=15 height=19 xoffset=0 yoffset=0 xadvance=8 page=1 chnl=15
|
||||
char id=82 x=126 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=83 x=221 y=0 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=84 x=154 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=85 x=168 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=86 x=182 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=87 x=144 y=0 width=16 height=19 xoffset=0 yoffset=0 xadvance=9 page=1 chnl=15
|
||||
char id=88 x=191 y=0 width=15 height=19 xoffset=0 yoffset=0 xadvance=8 page=1 chnl=15
|
||||
char id=89 x=196 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=90 x=210 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=91 x=50 y=0 width=12 height=21 xoffset=0 yoffset=0 xadvance=5 page=1 chnl=15
|
||||
char id=92 x=224 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=93 x=38 y=0 width=12 height=21 xoffset=0 yoffset=0 xadvance=5 page=1 chnl=15
|
||||
char id=94 x=162 y=79 width=14 height=12 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=95 x=176 y=79 width=14 height=10 xoffset=0 yoffset=9 xadvance=7 page=1 chnl=15
|
||||
char id=96 x=0 y=95 width=10 height=11 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=97 x=185 y=60 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=98 x=0 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=99 x=56 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=100 x=238 y=22 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=101 x=70 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=102 x=14 y=60 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=103 x=0 y=60 width=14 height=19 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=104 x=238 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=105 x=98 y=60 width=10 height=19 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=106 x=0 y=0 width=12 height=22 xoffset=0 yoffset=0 xadvance=5 page=1 chnl=15
|
||||
char id=107 x=56 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=108 x=118 y=60 width=10 height=19 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=109 x=154 y=60 width=16 height=16 xoffset=0 yoffset=3 xadvance=9 page=1 chnl=15
|
||||
char id=110 x=42 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=111 x=28 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=112 x=42 y=41 width=14 height=19 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=113 x=28 y=41 width=14 height=19 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=114 x=14 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=115 x=0 y=79 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=116 x=196 y=41 width=14 height=19 xoffset=0 yoffset=0 xadvance=7 page=1 chnl=15
|
||||
char id=117 x=241 y=60 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=118 x=227 y=60 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=119 x=138 y=60 width=16 height=16 xoffset=0 yoffset=3 xadvance=9 page=1 chnl=15
|
||||
char id=120 x=170 y=60 width=15 height=16 xoffset=0 yoffset=3 xadvance=8 page=1 chnl=15
|
||||
char id=121 x=224 y=41 width=14 height=19 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=122 x=213 y=60 width=14 height=16 xoffset=0 yoffset=3 xadvance=7 page=1 chnl=15
|
||||
char id=123 x=25 y=0 width=13 height=21 xoffset=0 yoffset=0 xadvance=6 page=1 chnl=15
|
||||
char id=124 x=86 y=0 width=10 height=21 xoffset=0 yoffset=0 xadvance=3 page=1 chnl=15
|
||||
char id=125 x=12 y=0 width=13 height=21 xoffset=0 yoffset=0 xadvance=6 page=1 chnl=15
|
||||
char id=126 x=148 y=79 width=14 height=12 xoffset=0 yoffset=4 xadvance=7 page=1 chnl=15
|
||||
kernings count=0
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@@ -8,8 +8,38 @@ function clear_folder() {
|
||||
Deno.mkdir(BUILD_FOLDER);
|
||||
}
|
||||
|
||||
function build_fonts() {
|
||||
copy(`assets/fonts`, `${BUILD_FOLDER}/assets/fonts`);
|
||||
async function build_fonts() {
|
||||
// i used https://fonts.varg.dev/ to build the font, its confusing
|
||||
const canvas_size = 256;
|
||||
|
||||
const font = await loadImage("assets/fonts/m6x11.png");
|
||||
const canvas = createCanvas(canvas_size, canvas_size);
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
ctx.drawImage(font, 0, 0);
|
||||
const image_data = ctx.getImageData(0, 0, canvas_size, canvas_size);
|
||||
const data = image_data.data;
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
const r = data[i];
|
||||
const g = data[i + 1];
|
||||
const b = data[i + 2];
|
||||
|
||||
if (r === 0 && g === 0 && b === 0) {
|
||||
// black pixel, alpha = 0
|
||||
data[i + 3] = 0;
|
||||
} else {
|
||||
// force white white
|
||||
data[i] = 255;
|
||||
data[i + 1] = 255;
|
||||
data[i + 2] = 255;
|
||||
data[i + 3] = 255;
|
||||
}
|
||||
}
|
||||
ctx.putImageData(image_data, 0, 0);
|
||||
|
||||
Deno.mkdir(`${BUILD_FOLDER}/assets/fonts`);
|
||||
Deno.writeFileSync(`${BUILD_FOLDER}/assets/fonts/m6x11.png`, canvas.toBuffer());
|
||||
copy("assets/fonts/m6x11.fnt", `${BUILD_FOLDER}/assets/fonts/m6x11.fnt`);
|
||||
}
|
||||
|
||||
function next_power_of_two(value: number): number {
|
||||
@@ -96,11 +126,15 @@ async function build_client() {
|
||||
}
|
||||
|
||||
async function build() {
|
||||
const now = performance.now();
|
||||
clear_folder();
|
||||
await build_assets();
|
||||
await build_client();
|
||||
console.log(`Built in ${(performance.now() - now).toFixed(2)}ms`);
|
||||
try {
|
||||
const now = performance.now();
|
||||
clear_folder();
|
||||
await build_assets();
|
||||
await build_client();
|
||||
console.log(`Built in ${(performance.now() - now).toFixed(2)}ms`);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
let last_build = 0;
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ export class AssetManager {
|
||||
audio.load();
|
||||
this.assets[key] = audio;
|
||||
this.loading_promises.push(promise);
|
||||
} else if (src.endsWith(".txt") || src.endsWith(".md")) {
|
||||
} else if (src.endsWith(".txt") || src.endsWith(".md") || src.endsWith(".fnt")) {
|
||||
const promise = async () => {
|
||||
const resp = await fetch(src);
|
||||
this.assets[key] = await resp.text();
|
||||
|
||||
@@ -5,24 +5,12 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>bworld</title>
|
||||
<style>
|
||||
/*
|
||||
Font by Daniel Linssen (https://managore.itch.io)
|
||||
https://managore.itch.io/m6x11
|
||||
*/
|
||||
@font-face {
|
||||
font-family: "m6x11";
|
||||
src: url("/assets/fonts/m6x11.ttf");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-smooth: never;
|
||||
}
|
||||
html, body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
image-rendering: pixelated;
|
||||
|
||||
+6
-1
@@ -2,7 +2,7 @@ import { EverythingRegistry } from "../common/everything_registry.ts";
|
||||
import { AssetManager } from "./assets.ts";
|
||||
import { ClientWorld } from "./client_world.ts";
|
||||
import { InputManager } from "./input_manager.ts";
|
||||
import { begin_drawing, end_drawing, init_window } from "./renderer.ts";
|
||||
import { begin_drawing, end_drawing, init_font, init_window } from "./renderer.ts";
|
||||
|
||||
EverythingRegistry.add_registry("tiles");
|
||||
await import("./tiles/mod.ts");
|
||||
@@ -77,8 +77,13 @@ AssetManager.instance.load("bworld:player", "/assets/sprites/player.png");
|
||||
AssetManager.instance.load("bworld:roguelike", "/assets/sprites/roguelike.png");
|
||||
AssetManager.instance.load("bworld:ui", "/assets/sprites/ui.png");
|
||||
|
||||
AssetManager.instance.load("bworld:m6x11", "/assets/fonts/m6x11.png");
|
||||
AssetManager.instance.load("bworld:m6x11_fnt", "/assets/fonts/m6x11.fnt");
|
||||
|
||||
await AssetManager.instance.load_all();
|
||||
|
||||
init_font();
|
||||
|
||||
const client_world = new ClientWorld();
|
||||
|
||||
const loop = new ClientLoop(client_world);
|
||||
|
||||
+152
-115
@@ -1,8 +1,9 @@
|
||||
import { AssetManager } from "./assets.ts";
|
||||
import { Camera } from "./components/camera.ts";
|
||||
|
||||
const MAX_SPRITES = 10000;
|
||||
const VERTS_PER_SPRITE = 6;
|
||||
const FLOATS_PER_VERT = 4;
|
||||
const FLOATS_PER_VERT = 8;
|
||||
|
||||
let gl: WebGLRenderingContext;
|
||||
export let canvas: HTMLCanvasElement;
|
||||
@@ -27,18 +28,15 @@ let _texture_loc: WebGLUniformLocation | null;
|
||||
|
||||
let current_texture: WebGLTexture | null = null;
|
||||
|
||||
const glyph_size = 32;
|
||||
let font_texture: WebGLTexture;
|
||||
const glyphs: Record<string, { u0: number; v0: number; u1: number; v1: number }> = {};
|
||||
|
||||
const vertex_src = `
|
||||
attribute vec2 aPos;
|
||||
attribute vec2 aUV;
|
||||
attribute vec4 aColor;
|
||||
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
|
||||
uniform vec2 uResolution;
|
||||
|
||||
uniform vec2 uCameraPos;
|
||||
uniform float uCameraZoom;
|
||||
uniform float uCameraRot;
|
||||
@@ -70,16 +68,19 @@ void main(){
|
||||
gl_Position = vec4(clip * vec2(1.0,-1.0),0.0,1.0);
|
||||
|
||||
vUV = aUV;
|
||||
vColor = aColor;
|
||||
}
|
||||
`;
|
||||
|
||||
const fragment_src = `
|
||||
precision mediump float;
|
||||
varying vec2 vUV;
|
||||
varying vec4 vColor;
|
||||
uniform sampler2D uTex;
|
||||
|
||||
void main(){
|
||||
gl_FragColor = texture2D(uTex,vUV);
|
||||
void main() {
|
||||
vec4 texColor = texture2D(uTex, vUV);
|
||||
gl_FragColor = texColor * vColor;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -116,6 +117,10 @@ export function init_window(canvas_element: HTMLCanvasElement) {
|
||||
gl.enableVertexAttribArray(uv_loc);
|
||||
gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, stride, 8);
|
||||
|
||||
const color_loc = gl.getAttribLocation(program, "aColor");
|
||||
gl.enableVertexAttribArray(color_loc);
|
||||
gl.vertexAttribPointer(color_loc, 4, gl.FLOAT, false, FLOATS_PER_VERT * 4, 16);
|
||||
|
||||
resolution_loc = gl.getUniformLocation(program, "uResolution");
|
||||
_texture_loc = gl.getUniformLocation(program, "uTex");
|
||||
|
||||
@@ -129,8 +134,6 @@ export function init_window(canvas_element: HTMLCanvasElement) {
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
init_font();
|
||||
}
|
||||
|
||||
function create_shader(type: number, src: string): WebGLShader {
|
||||
@@ -253,38 +256,6 @@ export function draw_texture_region(
|
||||
push_quad(dx, dy, dw, dh, u0, v0, u1, v1);
|
||||
}
|
||||
|
||||
export function draw_text(str: string, x: number, y: number) {
|
||||
if (!font_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_texture !== font_texture) {
|
||||
flush_batch();
|
||||
current_texture = font_texture;
|
||||
}
|
||||
|
||||
for (const ch of str) {
|
||||
const g = glyphs[ch];
|
||||
if (!g) {
|
||||
x += glyph_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
push_quad(
|
||||
x,
|
||||
y,
|
||||
glyph_size,
|
||||
glyph_size,
|
||||
g.u0,
|
||||
g.v0,
|
||||
g.u1,
|
||||
g.v1,
|
||||
);
|
||||
|
||||
x += glyph_size * 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
function flush_batch() {
|
||||
if (vert_index === 0 || !current_texture) {
|
||||
return;
|
||||
@@ -295,12 +266,11 @@ function flush_batch() {
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
//const posLoc = gl.getAttribLocation(program, "aPos");
|
||||
//const uvLoc = gl.getAttribLocation(program, "aUV");
|
||||
gl.enableVertexAttribArray(pos_loc);
|
||||
gl.vertexAttribPointer(pos_loc, 2, gl.FLOAT, false, 16, 0);
|
||||
gl.enableVertexAttribArray(uv_loc);
|
||||
gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, 16, 8);
|
||||
// const stride = FLOATS_PER_VERT * 4;
|
||||
// gl.enableVertexAttribArray(pos_loc);
|
||||
// gl.vertexAttribPointer(pos_loc, 2, gl.FLOAT, false, stride, 0);
|
||||
// gl.enableVertexAttribArray(uv_loc);
|
||||
// gl.vertexAttribPointer(uv_loc, 2, gl.FLOAT, false, stride, 8);
|
||||
|
||||
gl.uniform2f(camera_pos_loc, Math.floor(camera.x), Math.floor(camera.y));
|
||||
gl.uniform1f(camera_zoom_loc, camera.zoom);
|
||||
@@ -312,84 +282,39 @@ function flush_batch() {
|
||||
vert_index = 0;
|
||||
}
|
||||
|
||||
function push_quad(dx: number, dy: number, dw: number, dh: number, u0: number, v0: number, u1: number, v1: number) {
|
||||
function push_quad(
|
||||
dx: number,
|
||||
dy: number,
|
||||
dw: number,
|
||||
dh: number,
|
||||
u0: number,
|
||||
v0: number,
|
||||
u1: number,
|
||||
v1: number,
|
||||
r = 1,
|
||||
g = 1,
|
||||
b = 1,
|
||||
a = 1,
|
||||
) {
|
||||
const x2 = dx + dw;
|
||||
const y2 = dy + dh;
|
||||
|
||||
// deno-fmt-ignore
|
||||
const v = [
|
||||
dx,
|
||||
dy,
|
||||
u0,
|
||||
v0,
|
||||
x2,
|
||||
dy,
|
||||
u1,
|
||||
v0,
|
||||
dx,
|
||||
y2,
|
||||
u0,
|
||||
v1,
|
||||
dx, dy, u0, v0, r, g, b, a,
|
||||
x2, dy, u1, v0, r, g, b, a,
|
||||
dx, y2, u0, v1, r, g, b, a,
|
||||
|
||||
x2,
|
||||
dy,
|
||||
u1,
|
||||
v0,
|
||||
x2,
|
||||
y2,
|
||||
u1,
|
||||
v1,
|
||||
dx,
|
||||
y2,
|
||||
u0,
|
||||
v1,
|
||||
];
|
||||
x2, dy, u1, v0, r, g, b, a,
|
||||
x2, y2, u1, v1, r, g, b, a,
|
||||
dx, y2, u0, v1, r, g, b, a,
|
||||
];
|
||||
|
||||
for (let i = 0; i < v.length; i += 1) {
|
||||
vertex_data[vert_index++] = v[i];
|
||||
}
|
||||
}
|
||||
|
||||
function init_font() {
|
||||
const c = document.createElement("canvas");
|
||||
c.width = 512;
|
||||
c.height = 512;
|
||||
|
||||
const ctx = c.getContext("2d")!;
|
||||
ctx.fillStyle = "white";
|
||||
ctx.font = glyph_size + "px m6x11";
|
||||
|
||||
let x = 0;
|
||||
let y = glyph_size;
|
||||
|
||||
for (let i = 32; i < 127; i++) {
|
||||
const ch = String.fromCharCode(i);
|
||||
|
||||
ctx.fillText(ch, x, y);
|
||||
|
||||
glyphs[ch] = {
|
||||
u0: x / 512,
|
||||
v0: (y - glyph_size) / 512,
|
||||
u1: (x + glyph_size) / 512,
|
||||
v1: y / 512,
|
||||
};
|
||||
|
||||
x += glyph_size;
|
||||
|
||||
if (x > 512 - glyph_size) {
|
||||
x = 0;
|
||||
y += glyph_size;
|
||||
}
|
||||
}
|
||||
|
||||
font_texture = gl.createTexture()!;
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, font_texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, c);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
||||
}
|
||||
|
||||
export function resize_canvas() {
|
||||
const width = self.innerWidth;
|
||||
const height = self.innerHeight;
|
||||
@@ -415,3 +340,115 @@ export function end_mode_2d() {
|
||||
flush_batch();
|
||||
camera = default_camera;
|
||||
}
|
||||
|
||||
// font stuff
|
||||
|
||||
let font_texture: Texture;
|
||||
let font_fnt: FntFont;
|
||||
|
||||
export function init_font() {
|
||||
font_texture = AssetManager.instance.get<Texture>("bworld:m6x11");
|
||||
|
||||
font_fnt = parse_fnt(AssetManager.instance.get("bworld:m6x11_fnt"));
|
||||
}
|
||||
|
||||
interface FntChar {
|
||||
id: number;
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
xoffset: number;
|
||||
yoffset: number;
|
||||
xadvance: number;
|
||||
page: number;
|
||||
}
|
||||
|
||||
interface FntFont {
|
||||
line_height: number;
|
||||
chars: Record<number, FntChar>;
|
||||
pages: string[];
|
||||
}
|
||||
|
||||
function parse_fnt(text: string): FntFont {
|
||||
const lines = text.split(/\r?\n/);
|
||||
|
||||
const font: FntFont = {
|
||||
line_height: 0,
|
||||
chars: {},
|
||||
pages: [],
|
||||
};
|
||||
|
||||
for (const line of lines) {
|
||||
const parts = line.split(" ");
|
||||
const type = parts[0];
|
||||
|
||||
const data: Record<string, string> = {};
|
||||
|
||||
for (const part of parts.slice(1)) {
|
||||
const [k, v] = part.split("=");
|
||||
if (!k) {
|
||||
continue;
|
||||
}
|
||||
data[k] = v?.replace(/"/g, "");
|
||||
}
|
||||
|
||||
if (type === "common") {
|
||||
font.line_height = Number(data.lineHeight);
|
||||
}
|
||||
|
||||
if (type === "page") {
|
||||
font.pages.push(data.file);
|
||||
}
|
||||
|
||||
if (type === "char") {
|
||||
const char: FntChar = {
|
||||
id: Number(data.id),
|
||||
x: Number(data.x),
|
||||
y: Number(data.y),
|
||||
width: Number(data.width),
|
||||
height: Number(data.height),
|
||||
xoffset: Number(data.xoffset),
|
||||
yoffset: Number(data.yoffset),
|
||||
xadvance: Number(data.xadvance),
|
||||
page: Number(data.page),
|
||||
};
|
||||
|
||||
font.chars[char.id] = char;
|
||||
}
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
export function draw_text(str: string, x: number, y: number, scale: number = 1, color = [1, 1, 1, 1]) {
|
||||
if (!font_texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current_texture !== font_texture.tex) {
|
||||
flush_batch();
|
||||
current_texture = font_texture.tex;
|
||||
}
|
||||
|
||||
for (const ch of str) {
|
||||
const glyph = font_fnt.chars[ch.charCodeAt(0)];
|
||||
if (!glyph) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const dx = x + glyph.xoffset * scale;
|
||||
const dy = y + glyph.yoffset * scale;
|
||||
const dw = glyph.width * scale;
|
||||
const dh = glyph.height * scale;
|
||||
|
||||
const u0 = glyph.x / font_texture.width;
|
||||
const v0 = glyph.y / font_texture.height;
|
||||
const u1 = (glyph.x + glyph.width) / font_texture.width;
|
||||
const v1 = (glyph.y + glyph.height) / font_texture.height;
|
||||
|
||||
push_quad(dx, dy, dw, dh, u0, v0, u1, v1, color[0], color[1], color[2], color[3]);
|
||||
|
||||
x += glyph.xadvance * scale;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,21 +119,16 @@ export function draw_item(item: ItemStack, x: number, y: number) {
|
||||
if (item.max_amount !== 1) {
|
||||
draw_text(
|
||||
String(item.amount),
|
||||
x + SLOT_SIZE + 2 - 4,
|
||||
y + SLOT_SIZE + 2 - 4,
|
||||
//2,
|
||||
//"#3f3f3f",
|
||||
//"bottom",
|
||||
//"right",
|
||||
x + SLOT_SIZE + 2 - 11 * 2,
|
||||
y + SLOT_SIZE + 2 - 11 * 2,
|
||||
1,
|
||||
[63 / 255, 63 / 255, 63 / 255],
|
||||
);
|
||||
draw_text(
|
||||
String(item.amount),
|
||||
x + SLOT_SIZE - 4,
|
||||
y + SLOT_SIZE - 4,
|
||||
//2,
|
||||
//"white",
|
||||
//"bottom",
|
||||
//"right",
|
||||
x + SLOT_SIZE - 11 * 2,
|
||||
y + SLOT_SIZE - 11 * 2,
|
||||
1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user