mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-11-27 22:03:00 +08:00
feat: 地图渲染后处理
This commit is contained in:
parent
42a7e15ed8
commit
3372337fdf
@ -15,10 +15,9 @@ export class MapRender extends RenderItem {
|
|||||||
) {
|
) {
|
||||||
super('static', false, false);
|
super('static', false, false);
|
||||||
|
|
||||||
this.renderer.setLayerState(layerState);
|
renderer.setLayerState(layerState);
|
||||||
this.renderer.setCanvasSize(this.width, this.height);
|
renderer.setCellSize(CELL_WIDTH, CELL_HEIGHT);
|
||||||
this.renderer.setCellSize(CELL_WIDTH, CELL_HEIGHT);
|
renderer.setRenderSize(MAP_WIDTH, MAP_HEIGHT);
|
||||||
this.renderer.setRenderSize(MAP_WIDTH, MAP_HEIGHT);
|
|
||||||
|
|
||||||
this.delegateTicker(time => {
|
this.delegateTicker(time => {
|
||||||
this.renderer.tick(time);
|
this.renderer.tick(time);
|
||||||
|
|||||||
@ -188,6 +188,15 @@ export class MapRenderer
|
|||||||
/** 图块动画器 */
|
/** 图块动画器 */
|
||||||
private readonly tileAnimater: ITextureAnimater<number>;
|
private readonly tileAnimater: ITextureAnimater<number>;
|
||||||
|
|
||||||
|
/** `gl.viewport` 横坐标 */
|
||||||
|
private viewportX: number = 0;
|
||||||
|
/** `gl.viewport` 纵坐标 */
|
||||||
|
private viewportY: number = 0;
|
||||||
|
/** `gl.viewport` 宽度 */
|
||||||
|
private viewportWidth: number = 0;
|
||||||
|
/** `gl.viewport` 高度 */
|
||||||
|
private viewportHeight: number = 0;
|
||||||
|
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region 初始化
|
//#region 初始化
|
||||||
@ -227,6 +236,7 @@ export class MapRenderer
|
|||||||
this.viewport = new MapViewport(this);
|
this.viewport = new MapViewport(this);
|
||||||
this.tileAnimater = new TextureColumnAnimater();
|
this.tileAnimater = new TextureColumnAnimater();
|
||||||
this.initVertexPointer(this.gl, data);
|
this.initVertexPointer(this.gl, data);
|
||||||
|
this.setViewport(0, 0, this.canvas.width, this.canvas.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -348,11 +358,43 @@ export class MapRenderer
|
|||||||
setCanvasSize(width: number, height: number): void {
|
setCanvasSize(width: number, height: number): void {
|
||||||
this.canvas.width = width;
|
this.canvas.width = width;
|
||||||
this.canvas.height = height;
|
this.canvas.height = height;
|
||||||
|
// 更新 FBO 的纹理尺寸信息
|
||||||
|
const gl = this.gl;
|
||||||
|
const { pingTexture2D, pongTexture2D } = this.contextData;
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, pingTexture2D);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.UNSIGNED_BYTE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, pongTexture2D);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.UNSIGNED_BYTE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
this.updateRequired = true;
|
this.updateRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setViewport(x: number, y: number, width: number, height: number): void {
|
setViewport(x: number, y: number, width: number, height: number): void {
|
||||||
this.gl.viewport(x, y, width, height);
|
this.viewportX = x;
|
||||||
|
this.viewportY = y;
|
||||||
|
this.viewportWidth = width;
|
||||||
|
this.viewportHeight = height;
|
||||||
|
this.updateRequired = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear(color: boolean, depth: boolean): void {
|
clear(color: boolean, depth: boolean): void {
|
||||||
@ -674,6 +716,57 @@ export class MapRenderer
|
|||||||
const tileVAO = gl.createVertexArray();
|
const tileVAO = gl.createVertexArray();
|
||||||
const backVAO = gl.createVertexArray();
|
const backVAO = gl.createVertexArray();
|
||||||
|
|
||||||
|
// Post effect
|
||||||
|
const pingFramebuffer = gl.createFramebuffer();
|
||||||
|
const pongFramebuffer = gl.createFramebuffer();
|
||||||
|
const pingTexture2D = gl.createTexture();
|
||||||
|
const pongTexture2D = gl.createTexture();
|
||||||
|
|
||||||
|
// 初始化 Post effect FBO 和 Texture
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, pongTexture2D);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
this.canvas.width,
|
||||||
|
this.canvas.height,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.UNSIGNED_BYTE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, pingFramebuffer);
|
||||||
|
gl.framebufferTexture2D(
|
||||||
|
gl.FRAMEBUFFER,
|
||||||
|
gl.COLOR_ATTACHMENT0,
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
pongTexture2D,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, pingTexture2D);
|
||||||
|
gl.texImage2D(
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
this.canvas.width,
|
||||||
|
this.canvas.height,
|
||||||
|
0,
|
||||||
|
gl.RGBA,
|
||||||
|
gl.UNSIGNED_BYTE,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, pongFramebuffer);
|
||||||
|
gl.framebufferTexture2D(
|
||||||
|
gl.FRAMEBUFFER,
|
||||||
|
gl.COLOR_ATTACHMENT0,
|
||||||
|
gl.TEXTURE_2D,
|
||||||
|
pingTexture2D,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||||
|
|
||||||
|
// 初始化图块纹理
|
||||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tileTexture);
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, tileTexture);
|
||||||
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 4096, 4096, 1);
|
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, 4096, 4096, 1);
|
||||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
||||||
@ -717,6 +810,12 @@ export class MapRenderer
|
|||||||
backVAO,
|
backVAO,
|
||||||
tileTexture,
|
tileTexture,
|
||||||
backgroundTexture,
|
backgroundTexture,
|
||||||
|
|
||||||
|
pingFramebuffer,
|
||||||
|
pongFramebuffer,
|
||||||
|
pingTexture2D,
|
||||||
|
pongTexture2D,
|
||||||
|
|
||||||
tileTextureWidth: 4096,
|
tileTextureWidth: 4096,
|
||||||
tileTextureHeight: 4096,
|
tileTextureHeight: 4096,
|
||||||
tileTextureDepth: 1,
|
tileTextureDepth: 1,
|
||||||
@ -1273,7 +1372,11 @@ export class MapRenderer
|
|||||||
insTilePosAttribLocation: tilePos,
|
insTilePosAttribLocation: tilePos,
|
||||||
insTexCoordAttribLocation: texCoord,
|
insTexCoordAttribLocation: texCoord,
|
||||||
insTileDataAttribLocation: tileData,
|
insTileDataAttribLocation: tileData,
|
||||||
insTexDataAttribLocation: texData
|
insTexDataAttribLocation: texData,
|
||||||
|
pingFramebuffer,
|
||||||
|
pongFramebuffer,
|
||||||
|
pingTexture2D,
|
||||||
|
pongTexture2D
|
||||||
} = data;
|
} = data;
|
||||||
|
|
||||||
// 图层检查
|
// 图层检查
|
||||||
@ -1311,6 +1414,19 @@ export class MapRenderer
|
|||||||
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.viewport(
|
||||||
|
this.viewportX,
|
||||||
|
this.viewportY,
|
||||||
|
this.viewportWidth,
|
||||||
|
this.viewportHeight
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this.postEffects.length > 1) {
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, pingFramebuffer);
|
||||||
|
} else {
|
||||||
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||||
|
}
|
||||||
|
|
||||||
// 背景
|
// 背景
|
||||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||||
gl.useProgram(backProgram);
|
gl.useProgram(backProgram);
|
||||||
@ -1365,6 +1481,28 @@ export class MapRenderer
|
|||||||
gl.bindVertexArray(null);
|
gl.bindVertexArray(null);
|
||||||
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
|
||||||
|
|
||||||
|
// Post effects
|
||||||
|
let inputTextrue = pongTexture2D;
|
||||||
|
let outputFBO: WebGLFramebuffer | null = pingFramebuffer;
|
||||||
|
|
||||||
|
this.postEffects.forEach((v, i, a) => {
|
||||||
|
v.render(gl, inputTextrue, outputFBO, data);
|
||||||
|
if (inputTextrue === pongTexture2D) {
|
||||||
|
inputTextrue = pingTexture2D;
|
||||||
|
} else {
|
||||||
|
inputTextrue = pongTexture2D;
|
||||||
|
}
|
||||||
|
if (i === a.length - 2) {
|
||||||
|
outputFBO = null;
|
||||||
|
} else {
|
||||||
|
if (outputFBO === pingFramebuffer) {
|
||||||
|
outputFBO = pongFramebuffer;
|
||||||
|
} else {
|
||||||
|
outputFBO = pingFramebuffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 清空更新状态标识
|
// 清空更新状态标识
|
||||||
this.updateRequired = false;
|
this.updateRequired = false;
|
||||||
this.needUpdateFrameCounter = false;
|
this.needUpdateFrameCounter = false;
|
||||||
|
|||||||
@ -131,6 +131,15 @@ export interface IContextData {
|
|||||||
/** 背景程序的 VAO */
|
/** 背景程序的 VAO */
|
||||||
readonly backVAO: WebGLVertexArrayObject;
|
readonly backVAO: WebGLVertexArrayObject;
|
||||||
|
|
||||||
|
/** 第一个 framebuffer */
|
||||||
|
readonly pingFramebuffer: WebGLFramebuffer;
|
||||||
|
/** 第二个 framebuffer */
|
||||||
|
readonly pongFramebuffer: WebGLFramebuffer;
|
||||||
|
/** 第一个 texture2D */
|
||||||
|
readonly pingTexture2D: WebGLTexture;
|
||||||
|
/** 第二个 texture2D */
|
||||||
|
readonly pongTexture2D: WebGLTexture;
|
||||||
|
|
||||||
/** 当前画布的图块纹理宽度 */
|
/** 当前画布的图块纹理宽度 */
|
||||||
tileTextureWidth: number;
|
tileTextureWidth: number;
|
||||||
/** 当前画布的图块纹理高度 */
|
/** 当前画布的图块纹理高度 */
|
||||||
@ -280,17 +289,18 @@ export interface IMapRendererPostEffect {
|
|||||||
init(gl: WebGL2RenderingContext, data: IContextData): void;
|
init(gl: WebGL2RenderingContext, data: IContextData): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染效果对象,将内容渲染到输出 FBO 上
|
* 渲染效果对象,将内容渲染到输出 FBO 上,不建议使用 `gl.viewport` 切换渲染区域,因为在调用此方法时已经处理完毕了。
|
||||||
|
* 需要自行绑定输出 FBO 和输入纹理、缓冲区清空等内容。
|
||||||
* @param gl WebGL2 画布上下文
|
* @param gl WebGL2 画布上下文
|
||||||
|
* @param input 输入的 Texture2D
|
||||||
|
* @param output 输出 FBO,内容要画到这个 FBO 上,如果是 `null` 的话说明本次绘制会直接推送到画布
|
||||||
* @param data 地图渲染的上下文数据
|
* @param data 地图渲染的上下文数据
|
||||||
* @param input 输入 FBO
|
|
||||||
* @param output 输出 FBO,内容要画到这个 FBO 上
|
|
||||||
*/
|
*/
|
||||||
render(
|
render(
|
||||||
gl: WebGL2RenderingContext,
|
gl: WebGL2RenderingContext,
|
||||||
data: IContextData,
|
input: WebGLTexture,
|
||||||
input: WebGLFramebuffer,
|
output: WebGLFramebuffer | null,
|
||||||
output: WebGLFramebuffer
|
data: IContextData
|
||||||
): void;
|
): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user