Merge branch 'archive' into archive-update-v0.53.2

This commit is contained in:
Eliot Partridge
2019-09-17 22:20:48 -05:00
113 changed files with 3698 additions and 3719 deletions
+15 -12
View File
@@ -15,6 +15,7 @@ export interface Contributors {
contributors: Contributor[];
}
// The Team
export const CREDITS: Credit[] = [
// example:
// {
@@ -81,28 +82,30 @@ export const CREDITS: Credit[] = [
export const CONTRIBUTORS: Contributors[] = [
{
group: 'Musicians',
group: 'Music Composers',
contributors: [
{ name: 'Wandering Artist', links: ['https://wanderingartist.bandcamp.com/', 'https://www.youtube.com/user/WanderingArtistMusic'] }
]
{ name: 'Wandering Artist', links: ['https://wanderingartist.bandcamp.com/', 'https://www.youtube.com/user/WanderingArtistMusic'] },
],
},
{
group: 'Artists & Animators',
group: 'Programmers',
contributors: [
{ name: 'Industrialice' },
],
},
{
group: 'Artists',
contributors: [
{ name: 'Shino', links: ['https://www.deviantart.com/shinodage'] },
{ name: 'ChiraChan', links: ['https://www.deviantart.com/chiramii-chan', 'https://chirachan-art.tumblr.com/'] },
{ name: 'Goodly', links: ['https://www.deviantart.com/goodlyay'] },
{ name: 'TioRafaJP', links: ['https://www.deviantart.com/tiorafajp', 'https://www.youtube.com/user/RafaelJP2'] },
{ name: 'ShareMyShipment', links: ['https://www.deviantart.com/sharemyshipment'] },
{ name: 'Velenor', links: ['https://www.deviantart.com/velenor'] },
{ name: 'Velenor' },
{ name: 'Meno', links: ['https://twitter.com/menojar', 'https://www.deviantart.com/menojar'] },
{ name: 'OtakuAP', links: ['https://www.deviantart.com/otakuap'] },
],
},
{
group: 'Artists',
contributors: [
{ name: 'Disastral' },
{ name: 'Meno', links: ['https://www.deviantart.com/menojar'] },
{ name: 'CyberPon3', links: ['https://twitter.com/CyberPon3'] },
{ name: 'Paulpeoples', links: ['https://www.deviantart.com/paulpeopless'] },
{ name: 'Velvet-Frost', links: ['https://www.deviantart.com/velvet-frost'] },
{ name: 'Jet7Wave', links: ['https://www.deviantart.com/jetwave'] },
@@ -119,7 +122,7 @@ export const CONTRIBUTORS: Contributors[] = [
{ name: 'Towmacow Waffles', links: ['https://www.deviantart.com/towmacowwaffles'] },
{ name: 'OrchidPony', links: ['https://www.deviantart.com/orchidpony'] },
{ name: 'Cherry Cerise', links: ['https://www.deviantart.com/cherryceriseart'] },
{ name: 'Radio' },
{ name: 'RADIOstations', links: ['https://twitter.com/stagbeeble'] },
{ name: 'Ultimate Fluff' },
{ name: 'SC', links: ['https://0somecunt0.tumblr.com/tagged/sfw'] },
{ name: 'SailorDolpin', links: ['https://vk.com/id324582699'] },
+22 -6
View File
@@ -18,9 +18,14 @@ const SELECTED_ENTITY_BOUNDS = withAlphaFloat(ORANGE, 0.5);
function drawEntities(batch: PaletteSpriteBatch, entities: Entity[], camera: Camera, options: DrawOptions) {
const drawHidden = options.drawHidden;
let entitiesDrawn = 0;
let depthStep = 1.0 / entities.length;
for (let entity of entities) {
if (isBoundsVisible(camera, entity.bounds, entity.x, entity.y) && (!isHidden(entity) || drawHidden)) {
const depth = depthStep * entitiesDrawn;
entity.depth = depth;
batch.depth = depth;
for (const entity of entities) {
if ((!isHidden(entity) || drawHidden) && isBoundsVisible(camera, entity.bounds, entity.x, entity.y)) {
if (entity.type === PONY_TYPE) {
drawPonyEntity(batch, entity as Pony, options);
entitiesDrawn++;
@@ -45,38 +50,47 @@ function drawEntities(batch: PaletteSpriteBatch, entities: Entity[], camera: Cam
export function drawEntityLights(batch: SpriteBatch, entities: Entity[], camera: Camera, options: DrawOptions) {
const drawHidden = options.drawHidden;
let drawn = 0;
for (const entity of entities) {
if (DEVELOPMENT && (entity.type !== PONY_TYPE && !entity.drawLight)) {
console.error('Cannot draw entity light', entity);
}
if ((!isHidden(entity) || drawHidden) && isBoundsVisible(camera, entity.lightBounds, entity.x, entity.y)) {
if (isBoundsVisible(camera, entity.lightBounds, entity.x, entity.y) && (!isHidden(entity) || drawHidden)) {
if (entity.type === PONY_TYPE) {
drawPonyEntityLight(batch, entity as Pony, options);
} else {
entity.drawLight!(batch, options);
}
++drawn;
}
}
return drawn;
}
export function drawEntityLightSprites(batch: SpriteBatch, entities: Entity[], camera: Camera, options: DrawOptions) {
const drawHidden = options.drawHidden;
let drawn = 0;
for (const entity of entities) {
if (DEVELOPMENT && (entity.type !== PONY_TYPE && !entity.drawLightSprite)) {
console.error('Cannot draw entity light sprite', entity);
}
if ((!isHidden(entity) || drawHidden) && isBoundsVisible(camera, entity.lightSpriteBounds, entity.x, entity.y)) {
if (isBoundsVisible(camera, entity.lightSpriteBounds, entity.x, entity.y) && (!isHidden(entity) || drawHidden)) {
batch.depth = entity.depth;
if (entity.type === PONY_TYPE) {
drawPonyEntityLightSprite(batch, entity as Pony, options);
} else {
entity.drawLightSprite!(batch, options);
}
++drawn;
}
}
return drawn;
}
export function hasDrawLight(entity: Entity) {
@@ -99,10 +113,11 @@ export function hasLightSprite(entity: Entity) {
}
export function drawMap(
batch: PaletteSpriteBatch, map: WorldMap, camera: Camera, player: Pony, options: DrawOptions,
tileSets: TileSets, selectedEntities: Entity[],
batch: PaletteSpriteBatch, map: WorldMap, camera: Camera, player: Pony,
options: DrawOptions, tileSets: TileSets, selectedEntities: Entity[],
) {
TIMING && timeStart('forEachRegion');
batch.depth = 1.0;
if (BETA && options.engine === Engine.Whiteness) {
batch.drawRect(WHITE, 0, 0, toScreenX(map.width), toScreenY(map.height));
} else if (BETA && options.engine === Engine.LayeredTiles) {
@@ -118,6 +133,7 @@ export function drawMap(
TIMING && timeStart('drawEntities');
const entitiesDrawn = drawEntities(batch, map.entitiesDrawable, camera, options);
batch.depth = 1.0;
TIMING && timeEnd();
if (BETA || TOOLS) {
+218 -166
View File
@@ -5,7 +5,7 @@ import {
EntityState, Pony, Notification, TileType, Action, IServerActions, Season, WorldState, Holiday,
TileSets, ChatMessage, PartyInfo, Entity, DrawOptions, Engine, defaultDrawOptions, PonyStateFlags,
DoAction, ChatType, WorldStateFlags, DebugFlags, MessageType, AccountSettings, Matrix4,
FakeEntity, SelectFlags, WorldMap, MapType, MapFlags, EntityFlags, houseTiles, isValidTile
FakeEntity, SelectFlags, WorldMap, MapType, MapFlags, EntityFlags, houseTiles, isValidTile, GraphicsQuality
} from '../common/interfaces';
import {
clamp, lengthOfXY, setFlag, hasFlag, boundsIntersect, point, toInt, lerpColor, distanceXY
@@ -27,7 +27,7 @@ import { toggleWalls } from '../common/mixins';
import { getEntityTypeName, hammer, broom, createAnEntity, saw, placeableEntities, shovel } from '../common/entities';
import { hasExtendedInfo, setHeadAnimation, createPony } from '../common/pony';
import { PaletteManager } from '../graphics/paletteManager';
import { getRenderTargetSize, isWebGL2 } from '../graphics/webgl/webglUtils';
import { isWebGL2 } from '../graphics/webgl/webglUtils';
import { drawFullScreenMessage, drawNames, drawChat } from '../graphics/graphicsUtils';
import { Key } from './input/input';
import { loadAndInitSpriteSheets } from './spriteUtils';
@@ -62,7 +62,7 @@ import { initializeToys } from './ponyDraw';
import { ErrorReporter } from '../components/services/errorReporter';
import { mockPaletteManager } from '../common/ponyInfo';
import { timeStart, timeEnd, timingCollate, timeReset } from './timing';
import { bindFrameBuffer, unbindFrameBuffer, resizeFrameBuffer } from '../graphics/webgl/frameBuffer';
import { createFrameBuffer, bindFrameBuffer, unbindFrameBuffer, disposeFrameBuffer } from '../graphics/webgl/frameBuffer';
import { WebGL, initWebGL, disposeWebGL, initWebGLResources } from './webgl';
import { bindTexture } from '../graphics/webgl/texture2d';
import {
@@ -208,7 +208,6 @@ export class PonyTownGame implements Game {
supporterPony = createPony(0, 0, SUPPORTER_PONY, mockPaletteManager.addArray(defaultPalette), mockPaletteManager);
discordPony = createPony(0, 0, DISCORD_PONY, mockPaletteManager.addArray(defaultPalette), mockPaletteManager);
scale: number;
failedFBO = false;
rightOverride?: boolean;
headTurnedOverride?: boolean;
stateOverride?: EntityState;
@@ -248,6 +247,8 @@ export class PonyTownGame implements Game {
private deltaMultiplier = 1;
private lastDraw = 0;
private entitiesDrawn = 0;
private lightEntitiesDrawn = 0;
private lightSpriteEntitiesDrawn = 0;
private lastFps = performance.now();
private frames = 0;
private drawFps = 0;
@@ -274,6 +275,16 @@ export class PonyTownGame implements Game {
private errorReporter: ErrorReporter,
private zone: NgZone,
) {
if (settings.browser.lowGraphicsMode !== undefined) {
settings.browser.graphicsQuality = (settings.browser.lowGraphicsMode === true ? GraphicsQuality.Low : GraphicsQuality.High);
settings.browser.lowGraphicsMode = undefined;
settings.saveBrowserSettings();
}
if (settings.browser.graphicsQuality === undefined) {
settings.browser.graphicsQuality = GraphicsQuality.High;
settings.saveBrowserSettings();
}
this.scale = this.getScale();
this.audio.initTracks(this.season, this.holiday, this.map.type);
this.audio.setVolume(this.volume);
@@ -290,7 +301,22 @@ export class PonyTownGame implements Game {
return this.settings.browser.volume || 0;
}
get disableLighting() {
return !!this.settings.browser.lowGraphicsMode || this.failedFBO;
if (this.settings.browser.graphicsQuality === GraphicsQuality.Low) {
return true;
}
if (this.webgl) {
return this.webgl.failedFBO;
}
return false;
}
get disableLightMasksFixing() {
if (this.settings.browser.graphicsQuality !== GraphicsQuality.High) {
return true;
}
if (this.webgl) {
return this.webgl.failedDepthBuffer;
}
return false;
}
get frameDelay() {
return (this.settings.browser.powerSaving || this.editingActions) ? (1000 / 45) : 0;
@@ -325,8 +351,16 @@ export class PonyTownGame implements Game {
}
}
private toggleDisableLighting() {
if (!this.failedFBO) {
this.settings.browser.lowGraphicsMode = !this.settings.browser.lowGraphicsMode;
if (!this.webgl) {
return;
}
if (!this.webgl.failedFBO) {
if (this.settings.browser.graphicsQuality === GraphicsQuality.Low) {
this.settings.browser.graphicsQuality = GraphicsQuality.High;
}
else {
this.settings.browser.graphicsQuality = GraphicsQuality.Low;
}
this.settings.saveBrowserSettings();
}
}
@@ -1198,10 +1232,8 @@ export class PonyTownGame implements Game {
this.lastDraw = now;
// draw
const {
gl, frameBuffer, frameBufferSheet, spriteShader, spriteBatch, lightShader, paletteBatch, paletteShader,
palettes,
} = this.webgl;
const { gl, frameBuffer, frameBuffer2, spriteBatch, paletteBatch, palettes, failedFBO,
mergeShader, paletteShader, spriteShader, spriteShaderWithColor, lightShader } = this.webgl;
TIMING && timeStart('draw');
@@ -1246,7 +1278,7 @@ export class PonyTownGame implements Game {
drawOptions.engine = this.engine;
}
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / actualScale, gl.drawingBufferHeight / actualScale, 0, 0, 1000);
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / actualScale, gl.drawingBufferHeight / actualScale, 0, 0, 1000, false);
TIMING && timeEnd();
TIMING && timeStart('ensureAllVisiblePon...');
@@ -1263,132 +1295,134 @@ export class PonyTownGame implements Game {
lerpColor(light, white, 0.3);
}
if (this.engine === Engine.NewLighting) {
// ...
} else if (this.disableLighting) {
ortho(this.viewMatrix, camera.x, camera.x + camera.w, camera.actualY + camera.h, camera.actualY, 0, 1000);
lerpColor(light, white, 0.1); // adjust lighting for missing lights
// you'd draw directly onto the screen only when there's no framebuffer
// or the graphics is low and framebuffer size matches screen size
// color -> screen
gl.clearColor(bg[0], bg[1], bg[2], bg[3]);
gl.clear(gl.COLOR_BUFFER_BIT);
TIMING && timeStart('initializeFrameBuffers');
this.initializeFrameBuffers(this.webgl, width, height, this.settings.browser.graphicsQuality === GraphicsQuality.High);
TIMING && timeEnd();
const useDepthBuffer =
!failedFBO && (this.settings.browser.graphicsQuality === GraphicsQuality.High) && !!frameBuffer!.depthStencilRenderbuffer;
const useLighting = !failedFBO && (this.settings.browser.graphicsQuality !== GraphicsQuality.Low);
const drawSceneDirectlyOntoScreen =
failedFBO || (useLighting === false);
drawOptions.useDepthBuffer = useDepthBuffer;
let matrixTop = camera.actualY;
let matrixBottom = camera.actualY + camera.h;
if (!drawSceneDirectlyOntoScreen) {
[matrixTop, matrixBottom] = [matrixBottom, matrixTop];
}
ortho(this.viewMatrix, camera.x, camera.x + camera.w, matrixBottom, matrixTop, 0, 1000, false);
let mapDrawingColor = white;
if (!useLighting) {
mapDrawingColor = light;
lerpColor(mapDrawingColor, white, 0.1); // adjust lighting for missing lights
}
gl.clearColor(bg[0], bg[1], bg[2], bg[3]);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.depthFunc(gl.ALWAYS);
if (drawSceneDirectlyOntoScreen) {
TIMING && timeStart('color -> screen');
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.disable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
this.drawMap(this.webgl, this.map, this.viewMatrix, light, drawOptions);
} else {
ortho(this.viewMatrix, camera.x, camera.x + camera.w, camera.actualY, camera.actualY + camera.h, 0, 1000);
TIMING && timeStart('initializeFrameBuffer');
this.initializeFrameBuffer(this.webgl, width, height);
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
TIMING && timeEnd();
}
else {
// if (!isWebGL2(gl)) {
// gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
// gl.clear(gl.COLOR_BUFFER_BIT); // hack, doing this clear fixes black screen issues for some older devices
// }
if (!frameBuffer) {
DEVELOPMENT && console.warn('No frame buffer');
return;
let clearMask = gl.COLOR_BUFFER_BIT;
if (useDepthBuffer) {
gl.depthMask(true);
clearMask |= gl.DEPTH_BUFFER_BIT;
}
// color -> fbo
TIMING && timeStart('color -> fbo');
// gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer.handle);
bindFrameBuffer(gl, frameBuffer);
gl.viewport(0, 0, frameBuffer.width, frameBuffer.height);
gl.clearColor(bg[0], bg[1], bg[2], bg[3]);
gl.clear(gl.COLOR_BUFFER_BIT); // | gl.DEPTH_BUFFER_BIT);
TIMING && timeStart('color -> framebuffer');
bindFrameBuffer(gl, frameBuffer!);
gl.viewport(0, 0, frameBuffer!.width, frameBuffer!.height); // clearing the whole surface is preferable for most GPUs
gl.clear(clearMask);
gl.viewport(0, 0, width, height);
gl.disable(gl.DEPTH_TEST);
//gl.depthFunc(gl.LEQUAL);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
this.drawMap(this.webgl, this.map, this.viewMatrix, white, drawOptions);
this.drawMap(this.webgl, this.map, this.viewMatrix, mapDrawingColor, drawOptions);
gl.depthMask(false);
TIMING && timeEnd();
// color -> screen
TIMING && timeStart('color -> screen');
// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
unbindFrameBuffer(gl);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
if (useLighting) {
TIMING && timeStart('light -> fbo');
bindFrameBuffer(gl, frameBuffer2!);
gl.viewport(0, 0, frameBuffer2!.width, frameBuffer2!.height); // clearing the whole surface is preferable for most GPUs
gl.clearColor(light[0], light[1], light[2], light[3]);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, width, height);
gl.blendFunc(gl.ONE, gl.ONE);
gl.useProgram(spriteShader.program);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(spriteShader.uniforms.lighting, white);
gl.uniform1f(spriteShader.uniforms.textureSize, frameBufferSheet.texture!.width);
bindTexture(gl, 0, frameBufferSheet.texture);
spriteBatch.begin();
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
spriteBatch.end();
TIMING && timeEnd();
gl.useProgram(lightShader.program);
gl.uniformMatrix4fv(lightShader.uniforms.transform, false, this.viewMatrix);
gl.uniform4fv(lightShader.uniforms.lighting, white);
spriteBatch.begin();
this.lightEntitiesDrawn = drawEntityLights(spriteBatch, this.map.entitiesLight, this.camera, drawOptions);
spriteBatch.end();
// light -> fbo
TIMING && timeStart('light -> fbo');
// gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer.handle);
bindFrameBuffer(gl, frameBuffer);
gl.viewport(0, 0, frameBuffer.width, frameBuffer.height);
gl.clearColor(light[0], light[1], light[2], light[3]);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.viewport(0, 0, width, height);
//gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.blendFunc(gl.ONE, gl.ONE);
TIMING && timeEnd();
if (useDepthBuffer) {
gl.depthFunc(gl.GEQUAL);
}
gl.useProgram(spriteShaderWithColor.program);
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.viewMatrix);
gl.uniform4fv(spriteShaderWithColor.uniforms.lighting, white);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize,
normalSpriteSheet.texture!.width, normalSpriteSheet.texture!.height);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
this.lightSpriteEntitiesDrawn = drawEntityLightSprites(spriteBatch, this.map.entitiesLightSprite, this.camera, drawOptions);
spriteBatch.end();
gl.depthFunc(gl.ALWAYS);
if (isWebGL2(gl)) {
(gl as WebGL2RenderingContext).invalidateFramebuffer(gl.FRAMEBUFFER, [gl.DEPTH_ATTACHMENT]);
}
TIMING && timeEnd();
// shadows
//for (const e of map.entities) {
// if (e.drawShadow && camera.isBoundVisible(e.shadowBounds || e.bounds, e.x, e.y)) {
// this.spriteBatch.depth = camera.mapDepth(e.y);
// e.drawShadow(this.spriteBatch);
// }
//}
TIMING && timeStart('color + lights -> screen');
unbindFrameBuffer(gl);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.disable(gl.BLEND);
// soft lights
TIMING && timeStart('drawEntityLights');
gl.useProgram(lightShader.program);
gl.uniformMatrix4fv(lightShader.uniforms.transform, false, this.viewMatrix);
gl.uniform4fv(lightShader.uniforms.lighting, white);
spriteBatch.begin();
drawEntityLights(spriteBatch, this.map.entitiesLight, this.camera, drawOptions);
spriteBatch.end();
TIMING && timeEnd();
gl.useProgram(mergeShader.program);
gl.uniformMatrix4fv(mergeShader.uniforms.transform, false, this.fboMatrix);
gl.uniform2f(mergeShader.uniforms.textureSize, frameBuffer!.colorTexture.width, frameBuffer!.colorTexture.height);
bindTexture(gl, 0, frameBuffer!.colorTexture);
bindTexture(gl, 1, frameBuffer2!.colorTexture);
spriteBatch.begin();
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
spriteBatch.end();
TIMING && timeEnd();
}
else {
TIMING && timeStart('color framebuffer -> screen');
unbindFrameBuffer(gl);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.disable(gl.BLEND);
// light sprites
TIMING && timeStart('drawEntityLightSprites');
gl.useProgram(spriteShader.program);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.viewMatrix);
gl.uniform4fv(spriteShader.uniforms.lighting, white);
gl.uniform1f(spriteShader.uniforms.textureSize, normalSpriteSheet.texture!.width);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
drawEntityLightSprites(spriteBatch, this.map.entitiesLightSprite, this.camera, drawOptions);
spriteBatch.end();
TIMING && timeEnd();
// light -> screen
TIMING && timeStart('light -> screen');
// gl.bindFramebuffer(gl.FRAMEBUFFER, null);
unbindFrameBuffer(gl);
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.enable(gl.BLEND);
gl.blendEquation(gl.FUNC_ADD);
gl.blendFunc(gl.DST_COLOR, gl.ZERO);
gl.useProgram(spriteShader.program);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(spriteShader.uniforms.lighting, white);
gl.uniform1f(spriteShader.uniforms.textureSize, frameBufferSheet.texture!.width);
bindTexture(gl, 0, frameBufferSheet.texture);
spriteBatch.begin();
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
spriteBatch.end();
TIMING && timeEnd();
gl.useProgram(spriteShader.program);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(spriteShader.uniforms.lighting, white);
gl.uniform2f(spriteShader.uniforms.textureSize, frameBuffer!.colorTexture.width, frameBuffer!.colorTexture.height);
bindTexture(gl, 0, frameBuffer!.colorTexture);
spriteBatch.begin();
spriteBatch.drawImage(WHITE, 0, 0, width, height, 0, 0, width, height);
spriteBatch.end();
TIMING && timeEnd();
}
}
// ui -> screen
@@ -1401,7 +1435,7 @@ export class PonyTownGame implements Game {
gl.uniformMatrix4fv(paletteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(paletteShader.uniforms.lighting, white);
gl.uniform1f(paletteShader.uniforms.pixelSize, this.paletteManager.pixelSize);
gl.uniform1f(paletteShader.uniforms.textureSize, paletteSpriteSheet.texture!.width);
gl.uniform1f(paletteShader.uniforms.textureSize, 1.0 / paletteSpriteSheet.texture!.width);
bindTexture(gl, 0, paletteSpriteSheet.texture);
bindTexture(gl, 1, this.paletteManager.texture);
paletteBatch.begin();
@@ -1467,12 +1501,13 @@ export class PonyTownGame implements Game {
paletteBatch.end();
TIMING && timeEnd();
gl.useProgram(spriteShader.program);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(spriteShader.uniforms.lighting, white);
gl.useProgram(spriteShaderWithColor.program);
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
gl.uniform4fv(spriteShaderWithColor.uniforms.lighting, white);
if (BETA && this.showMinimap && this.minimap) {
gl.uniform1f(spriteShader.uniforms.textureSize, normalSpriteSheet.texture!.width);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize,
normalSpriteSheet.texture!.width, normalSpriteSheet.texture!.height);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
spriteBatch.save();
@@ -1500,7 +1535,8 @@ export class PonyTownGame implements Game {
}
if (BETA && this.debug.showRegions && this.player) {
gl.uniform1f(spriteShader.uniforms.textureSize, normalSpriteSheet.texture!.width);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize,
normalSpriteSheet.texture!.width, normalSpriteSheet.texture!.height);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
drawDebugRegions(spriteBatch, this.map, this.player, this.camera);
@@ -1510,22 +1546,23 @@ export class PonyTownGame implements Game {
const showFPS = !!this.settings.browser.showFps;
const showHelp = BETA && this.input.isPressed(Key.F1);
const showPalette = DEVELOPMENT && this.debug.showPalette;
const showAdditionalStats = false;
if (showFPS || showHelp || showPalette) {
if (showFPS || showHelp || showPalette || showAdditionalStats) {
// 1 to 1 pixel scale drawing
TIMING && timeStart('showFps');
const scale = 2;
// const height = gl.drawingBufferHeight / (ratio * scale);
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / ratio, gl.drawingBufferHeight / ratio, 0, 0, 1000);
gl.uniformMatrix4fv(spriteShader.uniforms.transform, false, this.fboMatrix);
gl.uniform1f(spriteShader.uniforms.textureSize, normalSpriteSheet.texture!.width);
ortho(this.fboMatrix, 0, gl.drawingBufferWidth / ratio, gl.drawingBufferHeight / ratio, 0, 0, 1000, false);
gl.uniformMatrix4fv(spriteShaderWithColor.uniforms.transform, false, this.fboMatrix);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize,
normalSpriteSheet.texture!.width, normalSpriteSheet.texture!.height);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
spriteBatch.save();
spriteBatch.scale(scale, scale);
if (showFPS) {
drawText(spriteBatch, this.drawFps.toFixed(), fontSmall, BLACK, 2, 2);
drawOutlinedText(spriteBatch, this.drawFps.toFixed(), fontSmall, WHITE, BLACK, 2, 2);
if (this.timingsText) {
const size = measureText(this.timingsText, fontMono);
@@ -1543,19 +1580,18 @@ export class PonyTownGame implements Game {
}
}
// if (DEVELOPMENT) {
// const width = gl.drawingBufferWidth / (ratio * scale);
// const { isCollidingCount, isCollidingObjectCount } = getCollisionStats();
// const text =
// `${isCollidingCount.toString().padStart(7)} calls\n` +
// `${isCollidingObjectCount.toString().padStart(7)} total checks\n` +
// `${this.markedColliding.toString().padStart(7)} player checks`;
// const size = measureText(text, fontMono);
// const x = width - 160;
// const y = 26;
// spriteBatch.drawRect(0x000000aa, x, y, 150, size.h + 10);
// drawText(spriteBatch, text, fontMono, WHITE, x + 5, y + 5);
// }
if (showAdditionalStats) {
const width = gl.drawingBufferWidth / (ratio * scale);
const text =
`entities ${this.entitiesDrawn}/${this.map.entitiesDrawable.length}\n` +
`light enitities ${this.lightEntitiesDrawn}/${this.map.entitiesLight.length}\n` +
`light sprite entities ${this.lightSpriteEntitiesDrawn}/${this.map.entitiesLightSprite.length}`;
const size = measureText(text, fontMono);
const x = width - Math.max(160, size.w);
const y = 26;
spriteBatch.drawRect(0x000000aa, x, y, 150, size.h + 10);
drawText(spriteBatch, text, fontMono, WHITE, x + 5, y + 5);
}
spriteBatch.restore();
spriteBatch.end();
@@ -1564,13 +1600,14 @@ export class PonyTownGame implements Game {
const paletteTexture = this.paletteManager.texture!;
const { width, height } = paletteTexture;
gl.uniform1f(spriteShader.uniforms.textureSize, normalSpriteSheet.texture!.width);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize,
normalSpriteSheet.texture!.width, normalSpriteSheet.texture!.height);
bindTexture(gl, 0, normalSpriteSheet.texture);
spriteBatch.begin();
spriteBatch.drawRect(0x00000066, 20, 20, width, height);
spriteBatch.end();
gl.uniform1f(spriteShader.uniforms.textureSize, width);
gl.uniform2f(spriteShaderWithColor.uniforms.textureSize, width, height);
bindTexture(gl, 0, paletteTexture);
spriteBatch.begin();
spriteBatch.drawImage(WHITE, 0, 0, width, height, 20, 20, width, height);
@@ -1601,15 +1638,17 @@ export class PonyTownGame implements Game {
drawFullScreenMessage(paletteBatch, this.camera, message, palettes.mainFont.white);
}
private drawMap(webgl: WebGL, map: WorldMap, viewMatrix: Matrix4, lighting: Float32Array, options: DrawOptions) {
const { gl, paletteBatch, paletteShader } = webgl;
const { gl, paletteBatch, paletteShader, paletteShaderWithDepth } = webgl;
const mapPaletteShader = options.useDepthBuffer ? paletteShaderWithDepth : paletteShader;
TIMING && timeStart('drawMap');
if (this.tileSets && this.player) {
gl.useProgram(paletteShader.program);
gl.uniformMatrix4fv(paletteShader.uniforms.transform, false, viewMatrix);
gl.uniform4fv(paletteShader.uniforms.lighting, lighting);
gl.uniform1f(paletteShader.uniforms.pixelSize, this.paletteManager.pixelSize);
gl.uniform1f(paletteShader.uniforms.textureSize, paletteSpriteSheet.texture!.width);
gl.useProgram(mapPaletteShader.program);
gl.uniformMatrix4fv(mapPaletteShader.uniforms.transform, false, viewMatrix);
gl.uniform4fv(mapPaletteShader.uniforms.lighting, lighting);
gl.uniform1f(mapPaletteShader.uniforms.pixelSize, this.paletteManager.pixelSize);
gl.uniform1f(mapPaletteShader.uniforms.textureSize, 1.0 / paletteSpriteSheet.texture!.width);
bindTexture(gl, 0, paletteSpriteSheet.texture);
bindTexture(gl, 1, this.paletteManager.texture);
paletteBatch.begin();
@@ -1618,7 +1657,7 @@ export class PonyTownGame implements Game {
paletteBatch.end();
if (this.highlightEntity && this.highlightEntity.draw) {
gl.uniform4fv(paletteShader.uniforms.lighting, highlightColor);
gl.uniform4fv(mapPaletteShader.uniforms.lighting, highlightColor);
paletteBatch.begin();
this.highlightEntity.draw(paletteBatch, this.drawOptions);
paletteBatch.end();
@@ -1680,16 +1719,29 @@ export class PonyTownGame implements Game {
DEVELOPMENT && log(`scrollY: ${window.scrollY}`);
}
}
private initializeFrameBuffer({ gl, frameBuffer }: WebGL, width: number, height: number) {
const targetSize = getRenderTargetSize(width, height);
private initializeFrameBuffers(
{ gl, frameBuffer, frameBuffer2 }: WebGL, width: number, height: number, useDepthBuffer: boolean
) {
if (!frameBuffer || !frameBuffer2) {
return;
}
if (frameBuffer && targetSize !== frameBuffer.width) {
const hasDepth = frameBuffer.depthStencilRenderbuffer !== null;
const isSizeChanged = width !== frameBuffer.width || height !== frameBuffer.height;
const isDepthChanged = hasDepth !== useDepthBuffer;
if (isSizeChanged || isDepthChanged) {
const maxSize = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
const isSizeTooBig = maxSize != null && (width > maxSize || height > maxSize);
if (maxSize != null && targetSize > maxSize) {
this.setScale(this.scale + 1);
if (isSizeTooBig) {
this.setScale(this.scale + 1); // should not happen, useDepthBuffer is also ignored if it does
DEVELOPMENT && console.warn('Cannot resize framebuffer');
} else {
resizeFrameBuffer(gl, frameBuffer, targetSize, targetSize);
disposeFrameBuffer(gl, frameBuffer);
disposeFrameBuffer(gl, frameBuffer2);
createFrameBuffer(gl, frameBuffer, width, height, false, useDepthBuffer, null);
createFrameBuffer(gl, frameBuffer2, width, height, false, false, frameBuffer.depthStencilRenderbuffer);
}
}
}
@@ -1742,7 +1794,7 @@ export class PonyTownGame implements Game {
let value = '';
if (this.settings.browser.showStats) {
const tris = spriteBatch.tris + paletteBatch.tris;
const tris = spriteBatch.drawnTrisStats + paletteBatch.drawnTrisStats;
const flush = paletteBatch.flushes;
const sent = this.sent.toFixed();
const recv = this.recv.toFixed();
@@ -1772,9 +1824,9 @@ export class PonyTownGame implements Game {
TIMING && timeReset();
spriteBatch!.tris = 0;
spriteBatch!.drawnTrisStats = 0;
spriteBatch!.flushes = 0;
paletteBatch!.tris = 0;
paletteBatch!.drawnTrisStats = 0;
paletteBatch!.flushes = 0;
}
}
+24
View File
@@ -522,6 +522,12 @@ export const excite = createHeadAnimation('excite', 8, false, [
...repeat(10, [0, 0, 1, 1, 5]),
]);
export const excite_meno = createHeadAnimation('excite_meno', 8, false, [
...repeat(2, [0, 0, 2, 2, 0]),
[0, 1, 6, 6, 0],
...repeat(10, [0, 0, 1, 1, 5])
]);
export const surpriseSad = createHeadAnimation('surpriseSad', 8, false, [
[0, 1, 15, 15, 8],
...repeat(8, [0, 0, 15, 15, 8]),
@@ -534,6 +540,24 @@ export const sneeze = createHeadAnimation('sneeze', 12, false, [
...repeat(4, [0, 0, 18, 18, 7]),
]);
export const happy_tongue = createHeadAnimation('happy_tongue', 12, false, [
...repeat(3, [0, 0, 1, 1, 0]),
[0, 1, 6, 6, 0],
...repeat(8, [0, 0, 14, 14, 4]),
]);
export const happy_tongue_meno = createHeadAnimation('happy_tongue_meno', 12, false, [
...repeat(3, [0, 0, 2, 2, 0]),
[0, 1, 6, 6, 0],
...repeat(8, [0, 0, 12, 12, 4]),
]);
export const happy_tongue_meno_2 = createHeadAnimation('happy_tongue_meno_2', 12, false, [
...repeat(3, [0, 0, 2, 2, 0]),
[0, 1, 6, 6, 0],
...repeat(8, [0, 0, 11, 11, 4]),
]);
export const headAnimations = [
smile, nom, laugh, yawn, surprise, surpriseSad, sneeze, excite,
];
+10 -7
View File
@@ -214,13 +214,14 @@ export function initializeToys(paletteManager: PaletteManager) {
}
}
const zeroPoint = point(0, 0);
// const zeroPoint = point(0, 0);
const wakes = [
{ ox: 21, oy: 60, behind: sprites.pony_wake_4, front: sprites.pony_wake_3 },
{ ox: 24, oy: 60, behind: sprites.pony_wake_6, front: sprites.pony_wake_5 },
{ ox: 18, oy: 51, behind: sprites.pony_wake_2, front: sprites.pony_wake_1 },
];
// swimming effects of different size; add value per tail
const wakeIndices = [0, 2, 1, 0, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1];
function getWakeIndex(info: Info) {
@@ -292,9 +293,10 @@ export function drawPony(batch: Batch, info: Info, state: State, ponyX: number,
let hatOffset = at(HEAD_ACCESSORY_OFFSETS, info.mane ? info.mane.type : 0)!;
const noMane = !info.mane || hasNoMane(info.mane.type);
if (info.headAccessory !== undefined && info.headAccessory.type === 20) {
hatOffset = zeroPoint;
}
// temp front layer hat test
// if (info.headAccessory !== undefined && info.headAccessory.type === 20) {
// hatOffset = zeroPoint;
//}
if (draw(options, NoDraw.Behind)) {
// far wing
@@ -639,13 +641,14 @@ export function drawHead(
drawSet(batch, sprites.facialHair, info.facialHair, x, y, WHITE);
}
const skipTopAndFrontMane = info.headAccessory !== undefined && info.headAccessory.type === 20;
// temp front layer hat test
// const skipTopAndFrontMane = info.headAccessory !== undefined && info.headAccessory.type === 20;
if (draw(options, NoDraw.FrontMane)) {
drawSet(batch, sprites.backFrontManes, info.backMane, x, y + maneOffsetY, WHITE);
}
if (draw(options, NoDraw.TopMane) && !skipTopAndFrontMane) {
if (draw(options, NoDraw.TopMane) /* && !skipTopAndFrontMane*/ ) {
drawSet(batch, sprites.topManes, info.mane, x, y, WHITE);
}
@@ -682,7 +685,7 @@ export function drawHead(
drawSet(batch, sprites.earAccessories, info.earAccessory, x + earAccessoryOffset.x, y + earAccessoryOffset.y, WHITE);
}
if (draw(options, NoDraw.FrontMane) && !skipTopAndFrontMane) {
if (draw(options, NoDraw.FrontMane) /* && !skipTopAndFrontMane */) {
drawSet(batch, sprites.frontManes, info.mane, x, y + maneOffsetY, WHITE);
}
-5
View File
@@ -39,7 +39,6 @@ export const tails = createCompleteSets(sprites.tails, 3);
export const chest = createCompleteSets(sprites.chestAccessories, bodyFrames);
export const chestBehind = createCompleteSets(sprites.chestAccessoriesBehind, bodyFrames);
export const backAccessories = createCompleteSets(sprites.backAccessories, bodyFrames);
sprites.neckAccessories.forEach(f => f && f.pop()); // TEMP: remove headphones
export const neckAccessories = createCompleteSets(sprites.neckAccessories, bodyFrames);
export const waistAccessories = createCompleteSets(sprites.waistAccessories, bodyFrames + 1);
@@ -145,10 +144,6 @@ function mergeSpriteSets(...sets: ColorExtraSets[]): ColorExtraSets {
export const backLegSleeves: Sets = sprites.backLegSleeves
.map(sets => sets && [undefined, undefined, undefined, undefined, undefined, ...sets]);
// TEMP: remove summer hat
sprites.headAccessoriesBehind.pop();
sprites.headAccessories.pop();
export const mergedManes = mergeSpriteSets(sprites.behindManes, sprites.topManes, sprites.frontManes)!;
export const mergedBackManes = mergeSpriteSets(sprites.backBehindManes, sprites.backFrontManes)!;
export const mergedFacialHair = mergeSpriteSets(sprites.facialHairBehind, sprites.facialHair)!;
+57 -54
View File
@@ -1,35 +1,41 @@
import { spriteShader, paletteLayersShader, lightShader } from '../generated/shaders';
import { FrameBuffer, createFrameBuffer, disposeFrameBuffer } from '../graphics/webgl/frameBuffer';
import { SpriteSheet, CommonPalettes, PaletteManager, Camera } from '../common/interfaces';
import { Shader, createShader, disposeShader } from '../graphics/webgl/shader';
import { PaletteSpriteBatch, PALETTE_BATCH_BYTES_PER_VERTEX } from '../graphics/paletteSpriteBatch';
import { getWebGLContext, getRenderTargetSize, unbindAllTexturesAndBuffers } from '../graphics/webgl/webglUtils';
import { mergeShader, spriteShader, paletteLayersShader, lightShader } from '../generated/shaders';
import { FrameBuffer, disposeFrameBuffer, createFrameBuffer } from '../graphics/webgl/frameBuffer';
import { CommonPalettes, PaletteManager, Camera } from '../common/interfaces';
import { Shader, ShaderProgramData, disposeShaderProgramData } from '../graphics/webgl/shader';
import { PaletteSpriteBatch } from '../graphics/paletteSpriteBatch';
import { getWebGLContext, unbindAllTexturesAndBuffers } from '../graphics/webgl/webglUtils';
import { createCommonPalettes } from '../graphics/graphicsUtils';
import { createTexturesForSpriteSheets, disposeTexturesForSpriteSheets } from '../graphics/spriteSheetUtils';
import * as sprites from '../generated/sprites';
import { SpriteBatch } from '../graphics/spriteBatch';
import { BATCH_SIZE_MAX } from '../common/constants';
import { BATCH_VERTEX_CAPACITY_MAX } from '../common/constants';
export interface WebGL {
gl: WebGLRenderingContext;
frameBuffer: FrameBuffer | undefined;
frameBufferSheet: SpriteSheet;
spriteShader: Shader;
lightShader: Shader;
paletteShader: Shader;
frameBuffer?: FrameBuffer;
frameBuffer2?: FrameBuffer;
mergeShader: ShaderProgramData;
paletteShader: ShaderProgramData;
paletteShaderWithDepth: ShaderProgramData;
spriteShader: ShaderProgramData;
spriteShaderWithColor: ShaderProgramData;
lightShader: ShaderProgramData;
spriteBatch: SpriteBatch;
paletteBatch: PaletteSpriteBatch;
palettes: CommonPalettes;
failedFBO: boolean;
failedDepthBuffer: boolean;
renderer: string;
indexBuffer: WebGLBuffer;
}
const mergeShaderSource = mergeShader;
const spriteShaderSource = spriteShader;
const paletteShaderSource = paletteLayersShader;
const lightShaderSource = lightShader;
function createIndices(capacity: number) {
const numIndices = (capacity * 6) | 0;
function createIndices(vertexCount: number) {
const numIndices = (vertexCount * 6 / 4) | 0;
const indices = new Uint16Array(numIndices);
for (let i = 0, j = 0; i < numIndices; j = (j + 4) | 0) {
@@ -52,62 +58,48 @@ export function initWebGL(canvas: HTMLCanvasElement, paletteManager: PaletteMana
export function initWebGLResources(gl: WebGLRenderingContext, paletteManager: PaletteManager, camera: Camera): WebGL {
let renderer = '';
let failedFBO = false;
let frameBuffer: FrameBuffer | undefined;
let frameBufferSheet: SpriteSheet = { texture: undefined, sprites: [], palette: false };
let failedDepthBuffer = false;
let frameBuffer = {} as FrameBuffer;
let frameBuffer2 = {} as FrameBuffer;
gl.enable(gl.DEPTH_TEST); // no reason to not have it enabled at all times, depth reads/writes are controlled by other parameters
gl.disable(gl.DITHER);
try {
const size = getRenderTargetSize(camera.w, camera.h);
frameBuffer = createFrameBuffer(gl, size, size);
frameBufferSheet.texture = frameBuffer.texture;
createFrameBuffer(gl, frameBuffer, camera.w, camera.h, false, true, null);
createFrameBuffer(gl, frameBuffer2, camera.w, camera.h, true, false, frameBuffer.depthStencilRenderbuffer);
} catch (e) {
DEVELOPMENT && console.warn(e);
failedFBO = true;
failedDepthBuffer = true;
}
if (!failedFBO) {
failedDepthBuffer = frameBuffer!.depthStencilRenderbuffer === null;
}
createTexturesForSpriteSheets(gl, sprites.spriteSheets);
const palettes = createCommonPalettes(paletteManager);
const paletteShader = createShader(gl, paletteShaderSource);
const spriteShader = createShader(gl, spriteShaderSource);
const lightShader = createShader(gl, lightShaderSource);
const VERTICES_PER_SPRITE = 4;
const buffer = new ArrayBuffer(BATCH_SIZE_MAX * VERTICES_PER_SPRITE * PALETTE_BATCH_BYTES_PER_VERTEX);
const vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new Error(`Failed to allocate vertex buffer`);
}
const mergeShaderRaw = new Shader(mergeShaderSource);
const paletteShaderRaw = new Shader(paletteShaderSource);
const spriteShaderRaw = new Shader(spriteShaderSource);
const lightShaderRaw = new Shader(lightShaderSource);
const indexBuffer = gl.createBuffer();
if (!indexBuffer) {
throw new Error(`Failed to allocate index buffer`);
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, buffer, gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, createIndices(BATCH_SIZE_MAX), gl.STATIC_DRAW);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, createIndices(BATCH_VERTEX_CAPACITY_MAX), gl.STATIC_DRAW);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
const vertexBuffer2 = gl.createBuffer();
if (!vertexBuffer2) {
throw new Error(`Failed to allocate vertex buffer (2)`);
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer2);
gl.bufferData(gl.ARRAY_BUFFER, buffer, gl.STATIC_DRAW);
const spriteBatch = new SpriteBatch(gl, BATCH_SIZE_MAX, buffer, vertexBuffer2, indexBuffer);
const paletteBatch = new PaletteSpriteBatch(gl, BATCH_SIZE_MAX, buffer, vertexBuffer, indexBuffer);
const spriteBatch = new SpriteBatch(gl, BATCH_VERTEX_CAPACITY_MAX, indexBuffer);
const paletteBatch = new PaletteSpriteBatch(gl, BATCH_VERTEX_CAPACITY_MAX, indexBuffer);
spriteBatch.rectSprite = sprites.pixel;
paletteBatch.rectSprite = sprites.pixel2;
paletteBatch.defaultPalette = palettes.defaultPalette;
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
paletteManager.init(gl);
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
@@ -116,9 +108,17 @@ export function initWebGLResources(gl: WebGLRenderingContext, paletteManager: Pa
renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL);
}
const mergeShader = mergeShaderRaw.compile(gl, []);
const paletteShader = paletteShaderRaw.compile(gl, []);
const paletteShaderWithDepth = paletteShaderRaw.compile(gl, ['DEPTH_BUFFERED']);
const spriteShader = spriteShaderRaw.compile(gl, []);
const spriteShaderWithColor = spriteShaderRaw.compile(gl, ['USE_COLOR']);
const lightShader = lightShaderRaw.compile(gl, []);
return {
gl, paletteShader, spriteShader, lightShader, spriteBatch, paletteBatch,
frameBuffer, frameBufferSheet, palettes, failedFBO, renderer,
gl, mergeShader: mergeShader, paletteShader: paletteShader, paletteShaderWithDepth: paletteShaderWithDepth,
spriteShader: spriteShader, spriteShaderWithColor: spriteShaderWithColor, lightShader: lightShader,
spriteBatch, paletteBatch, frameBuffer, frameBuffer2, palettes, failedFBO, failedDepthBuffer, renderer, indexBuffer
};
}
@@ -128,9 +128,12 @@ export function disposeWebGL(webgl: WebGL) {
unbindAllTexturesAndBuffers(gl);
disposeTexturesForSpriteSheets(gl, sprites.spriteSheets);
disposeFrameBuffer(gl, webgl.frameBuffer);
disposeShader(gl, webgl.lightShader);
disposeShader(gl, webgl.spriteShader);
disposeShader(gl, webgl.paletteShader);
disposeShaderProgramData(gl, webgl.paletteShader);
disposeShaderProgramData(gl, webgl.paletteShaderWithDepth);
disposeShaderProgramData(gl, webgl.spriteShader);
disposeShaderProgramData(gl, webgl.spriteShaderWithColor);
disposeShaderProgramData(gl, webgl.lightShader);
webgl.spriteBatch.dispose();
webgl.paletteBatch.dispose();
gl.deleteBuffer(webgl.indexBuffer);
}