refactor: gl2 & shader

This commit is contained in:
unanmed 2024-11-18 22:16:29 +08:00
parent 83a60c5018
commit 711c4c2264
7 changed files with 2237 additions and 1924 deletions

1753
src/core/render/gl2.ts Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,10 @@
import {
IShaderUniform,
Shader,
ShaderProgram,
UniformType
} from '@/core/render/shader';
import { Shader, ShaderProgram } from '@/core/render/shader';
import { IWeather, WeatherController } from './weather';
import { MotaRenderer } from '@/core/render/render';
import { Container } from '@/core/render/container';
import { GL2Program, IShaderUniform, UniformType } from '@/core/render/gl2';
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
import { Transform } from '@/core/render/transform';
const rainVs = /* glsl */ `
in vec2 a_rainVertex;
@ -87,13 +85,12 @@ Mota.require('var', 'loading').once('coreInit', () => {
const gl = shader.gl;
shader.size(480, 480);
shader.setHD(true);
shader.setZIndex(100);
RainWeather.shader = shader;
const program = shader.createProgram();
program.setVersion(shader.VERSION_ES_300);
const program = shader.createProgram(ShaderProgram);
program.fs(rainFs);
program.vs(rainVs);
program.requestCompile();
program.useDefault(false);
const pos = program.defineAttribArray('a_rainVertex');
program.defineAttribArray('a_offset');
program.defineAttribArray('a_data');
@ -108,13 +105,6 @@ Mota.require('var', 'loading').once('coreInit', () => {
pos.pointer(2, gl.FLOAT, false, 0, 0);
pos.enable();
}
const back = shader.createProgram();
back.requestCompile();
back.modified = true;
back.useDefault(false);
RainShader.backProgram = back;
shader.useProgram(back);
});
export class RainWeather implements IWeather {
@ -129,10 +119,8 @@ export class RainWeather implements IWeather {
activate(): void {
const render = MotaRenderer.get('render-main');
const draw = render?.getElementById('map-draw') as Container;
const layer = draw.children;
if (!layer || !draw) return;
if (!draw) return;
const shader = RainWeather.shader;
shader.appendChild(...layer);
shader.append(draw);
const gl = shader.gl;
@ -222,20 +210,4 @@ class RainShader extends Shader {
program.paramArraysInstanced(gl.TRIANGLE_STRIP, 0, 4, num);
color?.set(1, 1, 1, 0.1);
}
protected override preDraw(gl: WebGL2RenderingContext): boolean {
const back = RainShader.backProgram;
const rain = RainShader.rainProgram;
this.useProgram(back);
const ready = this.defaultReady();
const param = back.getDrawParams(this.DRAW_ELEMENTS);
const rainParam = rain.getDrawParams(this.DRAW_ARRAYS_INSTANCED);
if (!ready || !param || !rainParam) return false;
this.draw(gl, back, param, back.usingIndices);
this.useProgram(rain);
if (this.defaultReady()) this.draw(gl, rain, rainParam, null);
return false;
}
}

View File

@ -1,12 +1,10 @@
import {
IShaderUniform,
Shader,
ShaderProgram,
UniformType
} from '@/core/render/shader';
import { Shader, ShaderProgram } from '@/core/render/shader';
import { IWeather, WeatherController } from './weather';
import { MotaRenderer } from '@/core/render/render';
import { Container } from '@/core/render/container';
import { GL2Program, IShaderUniform, UniformType } from '@/core/render/gl2';
import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
import { Transform } from '@/core/render/transform';
const snowVs = /* glsl */ `
in vec2 a_snowVertex;
@ -108,12 +106,10 @@ Mota.require('var', 'loading').once('coreInit', () => {
shader.size(480, 480);
shader.setHD(true);
SnowWeather.shader = shader;
const program = shader.createProgram();
program.setVersion(shader.VERSION_ES_300);
const program = shader.createProgram(ShaderProgram);
program.fs(snowFs);
program.vs(snowVs);
program.requestCompile();
program.useDefault(false);
const pos = program.defineAttribArray('a_snowVertex');
program.defineAttribArray('a_offset');
program.defineAttribArray('a_data');
@ -128,13 +124,6 @@ Mota.require('var', 'loading').once('coreInit', () => {
pos.pointer(2, gl.FLOAT, false, 0, 0);
pos.enable();
}
const back = shader.createProgram();
back.requestCompile();
back.modified = true;
back.useDefault(false);
SnowShader.backProgram = back;
shader.useProgram(back);
});
export class SnowWeather implements IWeather {
@ -148,11 +137,9 @@ export class SnowWeather implements IWeather {
activate(): void {
const render = MotaRenderer.get('render-main');
const layer = render?.getElementById('layer-main');
const draw = render?.getElementById('map-draw') as Container;
if (!layer || !draw) return;
if (!draw) return;
const shader = SnowWeather.shader;
layer.append(shader);
shader.append(draw);
const gl = shader.gl;
@ -243,19 +230,18 @@ class SnowShader extends Shader {
color?.set(1, 1, 1, 0.1);
}
protected override preDraw(gl: WebGL2RenderingContext): boolean {
const back = SnowShader.backProgram;
protected preDraw(
canvas: MotaOffscreenCanvas2D,
transform: Transform,
gl: WebGL2RenderingContext,
program: GL2Program
): boolean {
const snow = SnowShader.snowProgram;
this.useProgram(back);
const ready = this.defaultReady();
const param = back.getDrawParams(this.DRAW_ELEMENTS);
const snowParam = snow.getDrawParams(this.DRAW_ARRAYS_INSTANCED);
if (!ready || !param || !snowParam) return false;
this.draw(gl, back, param, back.usingIndices);
if (!snowParam) return false;
this.useProgram(snow);
this.draw(gl, snow, snowParam, null);
if (!snow.ready()) return false;
this.draw(gl, snow);
return false;
}
}

View File

@ -28,6 +28,7 @@ Mota.require('var', 'loading').once('coreInit', () => {
const shader = new Shader();
shader.size(480, 480);
shader.setHD(true);
shader.setZIndex(120);
TowerBoss.shader = shader;
TowerBoss.effect.create(shader, 40);
});
@ -151,8 +152,6 @@ export class TowerBoss extends BarrageBoss {
override start() {
super.start();
this.group.remove();
this.group.append(TowerBoss.shader);
TowerBoss.shader.append(this.mapDraw);
this.healthBar.append(this.group);
this.word.append(this.group);
@ -177,7 +176,6 @@ export class TowerBoss extends BarrageBoss {
override end() {
super.end();
TowerBoss.shader.remove();
this.group.append(this.mapDraw);
this.healthBar.remove();
this.word.remove();
this.main.remove();

View File

@ -1,5 +1,6 @@
import { logger } from '@/core/common/logger';
import { Shader, ShaderProgram, UniformType } from '@/core/render/shader';
import { UniformType } from '@/core/render/gl2';
import { Shader, ShaderProgram } from '@/core/render/shader';
import { Transform } from '@/core/render/transform';
export const enum PointEffectType {
@ -118,8 +119,7 @@ export class PointEffect {
*/
create(shader: Shader, itemCount: number) {
if (this.program || this.shader || this.started) return;
const program = shader.createProgram();
program.setVersion(shader.VERSION_ES_300);
const program = shader.createProgram(ShaderProgram);
program.fs(generateFragment(itemCount));
program.requestCompile();

View File

@ -7,7 +7,12 @@ import type {
import type { HeroRenderer } from '@/core/render/preset/hero';
import type { Layer, LayerGroup } from '@/core/render/preset/layer';
import type { TimingFn } from 'mutate-animate';
import { BlockMover, heroMoveCollection, MoveStep } from '@/game/state/move';
import {
BlockMover,
heroMoveCollection,
IMoveController,
MoveStep
} from '@/game/state/move';
import type { FloorViewport } from '@/core/render/preset/viewport';
// 向后兼容用,会充当两个版本间过渡的作用
@ -647,26 +652,30 @@ export function init() {
}
});
const moveAction = new Set<string>(['up', 'down', 'left', 'right']);
let controller: IMoveController | null = null;
// 复写录像的移动
core.registerReplayAction('move', action => {
if (
action === 'up' ||
action === 'down' ||
action === 'left' ||
action === 'right'
) {
// const { noPass, canMove } = checkCanMove();
// const { nx, ny } = getNextLoc();
// if (noPass || !canMove) {
// if (canMove) core.trigger(nx, ny);
// } else {
// core.setHeroLoc('x', nx);
// core.setHeroLoc('y', ny);
// core.setHeroLoc('direction', action);
// }
// setTimeout(core.replay, 100);
if (moveAction.has(action)) {
const next = core.status.replay.toReplay[1];
if (!heroMover.moving) {
controller = heroMover.startMove();
}
if (!controller) {
return false;
}
controller.push({
type: 'dir',
value: action as Dir
});
if (moveAction.has(next)) {
core.replay();
} else {
controller.onEnd.then(() => {
core.replay();
controller = null;
});
}
return true;
} else {
return false;