Skip to content

Commit

Permalink
WebGL rendering of font
Browse files Browse the repository at this point in the history
  • Loading branch information
jcreedcmu committed Dec 9, 2023
1 parent 44caa65 commit 44d8512
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 4 deletions.
21 changes: 20 additions & 1 deletion public/assets/frag.frag
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ const int CHUNK_SIZE = 16;
const float NUM_SPRITES_PER_SHEET = 16.; // in both directions
const float SPRITE_SIZE = 32.;

const float NUM_FONT_CELLS_PER_SHEET = 8.; // in both directions
const float FONT_CELL_SIZE = 64.;

out vec4 outputColor;

// World coordinates of the origin of the chunk
Expand All @@ -19,6 +22,9 @@ uniform mat3 u_world_from_canvas;
// Sprite sheet
uniform sampler2D u_spriteTexture;

// Font Sheet
uniform sampler2D u_fontTexture;

// Chunk data
uniform sampler2D u_chunkDataTexture;

Expand All @@ -33,6 +39,19 @@ bool less_dist(vec2 v, float d) {
return v.x * v.x + v.y * v.y < d * d;
}

// p_in_world_fp is the fractional part of p_in_world. It is in [0,1]²
// sprite_coords is actually an ivec. It is in [0,NUM_SPRITES_PER_SHEET]²
vec4 get_sprite_pixel(vec2 p_in_world_fp, vec2 sprite_coords, float sharpness) {
if (sprite_coords.x == 12. || sprite_coords.x == 13.) {
int letter = int((sprite_coords.x - 12.) * NUM_SPRITES_PER_SHEET + sprite_coords.y);
vec2 font_coords = vec2(letter / int( NUM_FONT_CELLS_PER_SHEET), letter % int(NUM_FONT_CELLS_PER_SHEET));
float sdf = texture(u_fontTexture, (p_in_world_fp + font_coords) / NUM_FONT_CELLS_PER_SHEET).r;
float amount = clamp(0.5 + sharpness * (sdf - 0.5), 0., 1.);
return vec4(amount * vec3(0.6) + (1. - amount) * vec3(1.), 1.);
}
return texture(u_spriteTexture, (p_in_world_fp + sprite_coords) / NUM_SPRITES_PER_SHEET);
}

vec4 getColor() {
vec3 p_in_canvas = vec3(gl_FragCoord.xy, 1.0);
p_in_canvas.y = u_canvasSize.y - p_in_canvas.y;
Expand All @@ -49,7 +68,7 @@ vec4 getColor() {
p_in_world_fp = clamp(p_in_world_fp, 0.5/SPRITE_SIZE, 1. - 1./SPRITE_SIZE);

vec2 sprite_coords = round(255.0 * texture(u_chunkDataTexture, (coords_within_chunk + vec2(0.5,0.5)) / float(CHUNK_SIZE) )).xy;
vec4 bgcolor = texture(u_spriteTexture, (p_in_world_fp + sprite_coords) / NUM_SPRITES_PER_SHEET);
vec4 bgcolor = get_sprite_pixel(p_in_world_fp, sprite_coords, 1. / (u_world_from_canvas[0][0] * 6.));

vec2 off = abs(p_in_world - p_in_world_r);
float ch_amount = max(crosshair(off.xy), crosshair(off.yx));
Expand Down
6 changes: 5 additions & 1 deletion src/core/assets.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { prerenderSpriteSheet } from "../ui/sprite-sheet";
import { prerenderFontSheet, prerenderSpriteSheet } from "../ui/sprite-sheet";
import { Buffer, imgProm } from "../util/dutil";
import { grab } from "../util/util";

type Assets = {
dictionary: Record<string, boolean>,
spriteSheetBuf: Buffer,
fontSheetBuf: Buffer,
vert: string,
frag: string,
};
Expand All @@ -15,12 +16,14 @@ type Assets = {
let assets: Assets = {
dictionary: { 'foo': true, 'bar': true, 'baz': true },
spriteSheetBuf: undefined as any, // cheating here and assuming tests won't use toolbarImg
fontSheetBuf: undefined as any, // cheating here and assuming tests won't use fontSheetImg
vert: '',
frag: '',
}

export async function initAssets() {
const spriteSheetImg = await imgProm('assets/toolbar.png');
const fontSheetImg = await imgProm('assets/font-sheet.png');
const vert = await grab('assets/vertex.vert');
const frag = await grab('assets/frag.frag');
const wordlist = (await (await fetch('assets/dictionary.txt')).text())
Expand All @@ -29,6 +32,7 @@ export async function initAssets() {
assets = {
dictionary,
spriteSheetBuf: prerenderSpriteSheet(spriteSheetImg),
fontSheetBuf: prerenderFontSheet(fontSheetImg),
vert,
frag,
};
Expand Down
21 changes: 19 additions & 2 deletions src/ui/gl-render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type GlEnv = {

const SPRITE_TEXTURE_UNIT = 0;
const CHUNK_DATA_TEXTURE_UNIT = 1;
const FONT_TEXTURE_UNIT = 2;

function drawChunk(gl: WebGL2RenderingContext, env: GlEnv, p_in_chunk: Point, state: GameState, chunk_from_canvas: SE2): void {
const { prog, chunkBoundsBuffer, chunkImdat } = env;
Expand All @@ -49,6 +50,9 @@ function drawChunk(gl: WebGL2RenderingContext, env: GlEnv, p_in_chunk: Point, st
const u_spriteTexture = gl.getUniformLocation(prog, 'u_spriteTexture');
gl.uniform1i(u_spriteTexture, SPRITE_TEXTURE_UNIT);

const u_fontTexture = gl.getUniformLocation(prog, 'u_fontTexture');
gl.uniform1i(u_fontTexture, FONT_TEXTURE_UNIT);

const u_chunkDataTexture = gl.getUniformLocation(prog, 'u_chunkDataTexture');
gl.uniform1i(u_chunkDataTexture, CHUNK_DATA_TEXTURE_UNIT);

Expand Down Expand Up @@ -153,8 +157,6 @@ export function renderGlPane(ci: CanvasGlInfo, env: GlEnv, state: GameState): vo
else {
actuallyRender();
}


}

export function glInitialize(ci: CanvasGlInfo, dispatch: Dispatch): GlEnv {
Expand All @@ -181,6 +183,21 @@ export function glInitialize(ci: CanvasGlInfo, dispatch: Dispatch): GlEnv {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, spriteImdat);

// Font texture
const fontTexture = gl.createTexture();
if (fontTexture == null) {
throw new Error(`couldn't create font texture`);
}
gl.activeTexture(gl.TEXTURE0 + FONT_TEXTURE_UNIT);
gl.bindTexture(gl.TEXTURE_2D, fontTexture);

const fontImdat = imageDataOfBuffer(getAssets().fontSheetBuf);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, fontImdat);

// Chunk data texture
const chunkDataTexture = gl.createTexture();
if (chunkDataTexture == null) {
Expand Down
6 changes: 6 additions & 0 deletions src/ui/sprite-sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,9 @@ export function prerenderSpriteSheet(img: HTMLImageElement): Buffer {
}
return buf;
}

export function prerenderFontSheet(img: HTMLImageElement): Buffer {
const buf = buffer({ x: img.width, y: img.height });
buf.d.drawImage(img, 0, 0);
return buf;
}

0 comments on commit 44d8512

Please sign in to comment.