view: do not split multi-frame sprites into multiple textures

This commit is contained in:
Matthias Schiffer 2018-11-11 13:58:22 +01:00
parent 4eb954e759
commit 236151ba9c
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
2 changed files with 18 additions and 31 deletions

View file

@ -10,25 +10,24 @@ export async function loadEntity(
data: EntityData, data: EntityData,
): Promise<SpriteView[]> { ): Promise<SpriteView[]> {
const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`); const tile = await loadImage(`resources/sprite/entity/${data.sprite}.png`);
const [texture, size] = mkTexture(r, tile);
const frameSize = [size[0], size[1] / data.frames];
const offset = vec2.mul(vec2.create(), frameSize, data.anchor);
r.snapToGrid(offset, offset);
const coords: SpriteCoords = [
-offset[0],
-offset[1],
-offset[0] + frameSize[0],
-offset[1] + frameSize[1],
];
const sprites: SpriteView[] = []; const sprites: SpriteView[] = [];
for (let frame = 0; frame < data.frames; frame++) { for (let frame = 0; frame < data.frames; frame++) {
const [texture, coords] = mkTexture(r, tile, frame, data.frames);
const offset = vec2.fromValues(coords[2] - coords[0], coords[3] - coords[1]);
vec2.mul(offset, offset, data.anchor);
r.snapToGrid(offset, offset);
const anchorCoords: SpriteCoords = [
coords[0] - offset[0],
coords[1] - offset[1],
coords[2] - offset[0],
coords[3] - offset[1],
];
const builder = new SpriteViewBuilder(r, texture); const builder = new SpriteViewBuilder(r, texture);
builder.addSprite(anchorCoords, [0, 0, 1, 1]); builder.addSprite(coords, [0, frame / data.frames, 1, (frame + 1) / data.frames]);
sprites.push(builder.build()); sprites.push(builder.build());
} }

View file

@ -1,4 +1,3 @@
import { nextPowerOf2 } from '../../util';
import { Renderer } from '../renderer/renderer'; import { Renderer } from '../renderer/renderer';
import { SpriteCoords } from '../sprite'; import { SpriteCoords } from '../sprite';
@ -14,33 +13,22 @@ export function loadImage(url: string): Promise<HTMLImageElement> {
export function mkTexture( export function mkTexture(
r: Renderer, r: Renderer,
src: HTMLCanvasElement|HTMLImageElement, src: HTMLCanvasElement|HTMLImageElement,
frame: number = 0, ): [WebGLTexture, [number, number]] {
total: number = 1,
): [WebGLTexture, SpriteCoords] {
const gl = r.getContext(); const gl = r.getContext();
const texture = gl.createTexture(); const texture = gl.createTexture();
if (!texture) if (!texture)
throw new Error('unable to create texture'); throw new Error('unable to create texture');
const w = src.width, h = src.height / total;
const canvas = document.createElement('canvas');
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
ctx.drawImage(src, 0, frame * h, w, h, 0, 0, w, h);
gl.bindTexture(gl.TEXTURE_2D, texture); gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
const coords: SpriteCoords = [ const size: [number, number] = [
0, 0, w / r.coordScale, h / r.coordScale, src.width / r.coordScale, src.height / r.coordScale,
]; ];
return [texture, coords]; return [texture, size];
} }