bg2e-js 2.3.11 → 2.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bg2e-js.js +356 -326
- package/dist/bg2e-js.js.map +1 -1
- package/package.json +56 -56
- package/src/app/AppController.ts +39 -39
- package/src/app/Bg2KeyboardEvent.ts +54 -54
- package/src/app/Bg2MouseEvent.ts +82 -82
- package/src/app/Bg2TouchEvent.ts +18 -18
- package/src/app/Canvas.ts +108 -108
- package/src/app/EventBase.ts +10 -10
- package/src/app/MainLoop.ts +273 -273
- package/src/app/index.ts +24 -24
- package/src/base/Color.ts +134 -134
- package/src/base/Environment.ts +183 -183
- package/src/base/Light.ts +192 -192
- package/src/base/Material.ts +620 -620
- package/src/base/PolyList.ts +365 -365
- package/src/base/Texture.ts +620 -620
- package/src/base/index.ts +81 -81
- package/src/db/Bg2LoaderPlugin.ts +143 -143
- package/src/db/DBPluginApi.ts +48 -48
- package/src/db/Loader.ts +116 -116
- package/src/db/LoaderPlugin.ts +34 -34
- package/src/db/MtlParser.ts +7 -7
- package/src/db/ObjLoaderPlugin.ts +54 -54
- package/src/db/ObjParser.ts +252 -252
- package/src/db/ObjWriterPlugin.ts +18 -18
- package/src/db/VitscnjLoaderPlugin.ts +112 -112
- package/src/db/Writer.ts +52 -52
- package/src/db/WriterPlugin.ts +22 -22
- package/src/db/index.ts +44 -44
- package/src/debug/DebugRenderer.ts +173 -173
- package/src/debug/WebGLTextureViewer.ts +75 -75
- package/src/debug/index.ts +6 -6
- package/src/index.html +11 -11
- package/src/index.ts +33 -33
- package/src/manipulation/SelectionBuffer.ts +81 -81
- package/src/manipulation/SelectionHighlight.ts +105 -84
- package/src/manipulation/SelectionIdAssignVisitor.ts +96 -96
- package/src/manipulation/SelectionManager.ts +196 -188
- package/src/manipulation/SelectionMode.ts +6 -6
- package/src/math/Mat3.ts +259 -259
- package/src/math/Mat4.ts +710 -710
- package/src/math/MatrixStrategy.ts +25 -25
- package/src/math/Quat.ts +65 -65
- package/src/math/Vec.ts +753 -753
- package/src/math/constants.ts +46 -46
- package/src/math/functions.ts +103 -103
- package/src/math/index.ts +74 -74
- package/src/phsics/joint.ts +137 -137
- package/src/primitives/arrow.ts +57 -57
- package/src/primitives/cone.ts +138 -138
- package/src/primitives/cube.ts +60 -60
- package/src/primitives/cylinder.ts +216 -216
- package/src/primitives/index.ts +13 -13
- package/src/primitives/plane.ts +31 -31
- package/src/primitives/sphere.ts +809 -809
- package/src/react/useBg2e.ts +69 -69
- package/src/render/BRDFIntegrationMap.ts +4 -4
- package/src/render/Environment.ts +135 -135
- package/src/render/FrameBuffer.ts +35 -35
- package/src/render/MaterialRenderer.ts +34 -34
- package/src/render/Pipeline.ts +108 -108
- package/src/render/PolyListRenderer.ts +47 -47
- package/src/render/RenderBuffer.ts +197 -197
- package/src/render/RenderQueue.ts +198 -198
- package/src/render/RenderState.ts +116 -116
- package/src/render/Renderer.ts +248 -248
- package/src/render/SceneAppController.ts +250 -250
- package/src/render/SceneRenderer.ts +387 -387
- package/src/render/Shader.ts +32 -32
- package/src/render/ShadowRenderer.ts +176 -176
- package/src/render/SkyCube.ts +105 -105
- package/src/render/SkySphere.ts +117 -117
- package/src/render/TextureMergerRenderer.ts +70 -70
- package/src/render/TextureRenderer.ts +34 -34
- package/src/render/index.ts +67 -67
- package/src/render/webgl/FrameBuffer.ts +9 -9
- package/src/render/webgl/MaterialRenderer.ts +112 -112
- package/src/render/webgl/Pipeline.ts +88 -88
- package/src/render/webgl/PolyListRenderer.ts +260 -260
- package/src/render/webgl/RenderBuffer.ts +226 -226
- package/src/render/webgl/Renderer.ts +262 -262
- package/src/render/webgl/SceneRenderer.ts +67 -67
- package/src/render/webgl/ShaderProgram.ts +424 -424
- package/src/render/webgl/ShadowRenderer.ts +6 -6
- package/src/render/webgl/SkyCube.ts +15 -15
- package/src/render/webgl/SkySphere.ts +15 -15
- package/src/render/webgl/State.ts +152 -152
- package/src/render/webgl/TextureRenderer.ts +167 -167
- package/src/render/webgl/VertexBuffer.ts +137 -137
- package/src/render/webgl/index.ts +35 -35
- package/src/scene/Camera.ts +458 -458
- package/src/scene/Chain.ts +44 -44
- package/src/scene/ChainJoint.ts +58 -58
- package/src/scene/Component.ts +177 -177
- package/src/scene/ComponentMap.ts +106 -106
- package/src/scene/Drawable.ts +154 -154
- package/src/scene/EnvironmentComponent.ts +141 -141
- package/src/scene/FindNodeVisitor.ts +59 -59
- package/src/scene/LightComponent.ts +154 -154
- package/src/scene/MatrixState.ts +46 -46
- package/src/scene/Node.ts +328 -328
- package/src/scene/NodeVisitor.ts +15 -15
- package/src/scene/OrbitCameraController.ts +450 -450
- package/src/scene/SmoothOrbitCameraController.ts +99 -99
- package/src/scene/Transform.ts +73 -73
- package/src/scene/index.ts +60 -60
- package/src/shaders/BasicDiffuseColorShader.ts +111 -111
- package/src/shaders/BasicPBRLightShader.ts +276 -276
- package/src/shaders/DebugRenderShader.ts +97 -97
- package/src/shaders/DepthRenderShader.ts +127 -127
- package/src/shaders/IrradianceMapCubeShader.ts +115 -115
- package/src/shaders/PBRLightIBLShader.ts +486 -486
- package/src/shaders/PickSelectionShader.ts +101 -101
- package/src/shaders/PresentDebugFramebufferShader.ts +118 -118
- package/src/shaders/PresentTextureShader.ts +99 -99
- package/src/shaders/SelectionHighlightShader.ts +143 -127
- package/src/shaders/ShaderFunction.ts +318 -318
- package/src/shaders/SkyCubeShader.ts +93 -93
- package/src/shaders/SkySphereShader.ts +102 -102
- package/src/shaders/SpecularMapCubeShader.ts +164 -164
- package/src/shaders/TextureMergerShader.ts +171 -171
- package/src/shaders/index.ts +36 -36
- package/src/shaders/webgl/color_correction.glsl +47 -47
- package/src/shaders/webgl/constants.glsl +6 -6
- package/src/shaders/webgl/index.ts +70 -70
- package/src/shaders/webgl/normal_map.glsl +9 -9
- package/src/shaders/webgl/pbr.glsl +173 -173
- package/src/shaders/webgl/uniforms.glsl +91 -91
- package/src/shaders/webgl_shader_lib.ts +213 -213
- package/src/tools/BinaryResourceProvider.ts +14 -14
- package/src/tools/ImageResourceProvider.ts +66 -66
- package/src/tools/MaterialModifier.ts +446 -446
- package/src/tools/Resource.ts +203 -203
- package/src/tools/ResourceProvider.ts +69 -69
- package/src/tools/TextResourceProvider.ts +24 -24
- package/src/tools/TextureCache.ts +51 -51
- package/src/tools/TextureResourceDatabase.ts +100 -100
- package/src/tools/UserAgent.ts +362 -362
- package/src/tools/VideoResourceProvider.ts +50 -50
- package/src/tools/WriteStrategy.ts +22 -22
- package/src/tools/base64.ts +11 -11
- package/src/tools/crypto.ts +19 -19
- package/src/tools/endiantess.ts +13 -13
- package/src/tools/image.ts +18 -18
- package/src/tools/index.ts +41 -41
- package/src/tools/processType.ts +39 -39
- package/src/vite-env.d.ts +12 -12
|
@@ -1,227 +1,227 @@
|
|
|
1
|
-
|
|
2
|
-
import { TextureRenderTargetAttachment, TextureTargetName } from "../../base/Texture";
|
|
3
|
-
import Vec from "../../math/Vec";
|
|
4
|
-
import RenderBuffer, { RenderBufferType, CubeMapFace } from "../RenderBuffer";
|
|
5
|
-
import Texture from "../../base/Texture";
|
|
6
|
-
|
|
7
|
-
function glEnumToString(gl: WebGLRenderingContext, value: number): string {
|
|
8
|
-
for(var key in gl) {
|
|
9
|
-
if (gl[key as keyof WebGLRenderingContext] === value) {
|
|
10
|
-
return key;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
return "0x" + value.toString(16);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function getAttachmentPoint(gl: WebGLRenderingContext, att: number | string): number {
|
|
17
|
-
switch (Number(att)) {
|
|
18
|
-
case TextureRenderTargetAttachment.COLOR_ATTACHMENT_0:
|
|
19
|
-
return gl.COLOR_ATTACHMENT0;
|
|
20
|
-
case TextureRenderTargetAttachment.DEPTH_ATTACHMENT:
|
|
21
|
-
return gl.DEPTH_ATTACHMENT;
|
|
22
|
-
case TextureRenderTargetAttachment.STENCIL_ATTACHMENT:
|
|
23
|
-
return gl.STENCIL_ATTACHMENT;
|
|
24
|
-
default:
|
|
25
|
-
throw new Error(`RenderBuffer.beginUpdate() Error creating render buffer. Invalid attachment ${att}.`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function getTextureTarget(gl: WebGLRenderingContext, texture: Texture): number {
|
|
30
|
-
return gl[TextureTargetName[texture.target] as keyof WebGLRenderingContext] as number;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default class WebGLRenderBuffer extends RenderBuffer {
|
|
34
|
-
private _framebuffer?: WebGLFramebuffer | null;
|
|
35
|
-
private _depthBuffer?: WebGLRenderbuffer | null;
|
|
36
|
-
private _framebuffers?: WebGLFramebuffer[] | null;
|
|
37
|
-
private _depthBuffers?: WebGLRenderbuffer[] | null;
|
|
38
|
-
private _screenViewport?: Vec;
|
|
39
|
-
private _prevArrayBufferBinding?: WebGLBuffer | null;
|
|
40
|
-
private _prevElementBufferBinding?: WebGLBuffer | null;
|
|
41
|
-
constructor(renderer: any) {
|
|
42
|
-
super(renderer);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
get frameBuffer(): any {
|
|
46
|
-
return this.renderer.frameBuffer;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
saveVertexBufferState(): void {
|
|
50
|
-
const { gl } = this.renderer;
|
|
51
|
-
this._prevArrayBufferBinding = gl.getParameter(gl.ARRAY_BUFFER_BINDING);
|
|
52
|
-
this._prevElementBufferBinding = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
restoreVertexBufferState(): void {
|
|
56
|
-
const { gl } = this.renderer;
|
|
57
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, this._prevArrayBufferBinding);
|
|
58
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._prevElementBufferBinding);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
beginUpdate(textureFace: CubeMapFace = CubeMapFace.NONE): void {
|
|
62
|
-
if (this.type === RenderBufferType.TEXTURE) {
|
|
63
|
-
this.beginUpdateTexture();
|
|
64
|
-
}
|
|
65
|
-
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
66
|
-
this.beginUpdateCubemap(textureFace);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
throw new Error("The render buffer is not initialized");
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
endUpdate(textureFace: CubeMapFace = CubeMapFace.NONE): void {
|
|
74
|
-
if (this.type === RenderBufferType.TEXTURE) {
|
|
75
|
-
this.endUpdateTexture();
|
|
76
|
-
}
|
|
77
|
-
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
78
|
-
this.endUpdateCubemap();
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
throw new Error("The render buffer is not initialized");
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
destroy(): void {
|
|
86
|
-
const { gl } = this.renderer;
|
|
87
|
-
if (this.type === RenderBufferType.TEXTURE) {
|
|
88
|
-
if (this._framebuffer) {
|
|
89
|
-
gl.deleteFramebuffer(this._framebuffer);
|
|
90
|
-
this._framebuffer = null;
|
|
91
|
-
}
|
|
92
|
-
if (this._depthBuffer) {
|
|
93
|
-
gl.deleteRenderbuffer(this._depthBuffer);
|
|
94
|
-
this._depthBuffer = null;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
98
|
-
if (this._framebuffers?.length) {
|
|
99
|
-
this._framebuffers.forEach(fb => gl.deleteFramebuffer(fb));
|
|
100
|
-
}
|
|
101
|
-
if (this._depthBuffers?.length) {
|
|
102
|
-
this._depthBuffers.forEach(db => gl.deleteRenderbuffer(db));
|
|
103
|
-
}
|
|
104
|
-
this._framebuffers = null;
|
|
105
|
-
this._depthBuffers = null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
readPixels(x: number, y: number, width: number, height: number): Uint8Array | undefined {
|
|
110
|
-
const textureRenderer = this.attachments[0];
|
|
111
|
-
const texture = textureRenderer?.texture;
|
|
112
|
-
if (texture) {
|
|
113
|
-
const { gl } = this.renderer;
|
|
114
|
-
const data = new Uint8Array(width * height * 4);
|
|
115
|
-
gl.readPixels(x, texture.size.height - y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
|
116
|
-
return data;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
private beginUpdateTexture(): void {
|
|
122
|
-
const { gl } = this.renderer;
|
|
123
|
-
|
|
124
|
-
if (this.dirty) {
|
|
125
|
-
if (this._framebuffer) {
|
|
126
|
-
gl.deleteFramebuffer(this._framebuffer);
|
|
127
|
-
}
|
|
128
|
-
this._framebuffer = gl.createFramebuffer();
|
|
129
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer);
|
|
130
|
-
|
|
131
|
-
let depthBufferPresent = false;
|
|
132
|
-
for (const attachment in this.attachments) {
|
|
133
|
-
const textureRenderer = this.attachments[attachment];
|
|
134
|
-
const textureApi = textureRenderer.getApiObject();
|
|
135
|
-
const attachmentPoint = getAttachmentPoint(gl,attachment);
|
|
136
|
-
const textureTarget = getTextureTarget(gl,textureRenderer.texture);
|
|
137
|
-
const level = 0;
|
|
138
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, textureTarget, textureApi, level);
|
|
139
|
-
depthBufferPresent = depthBufferPresent || Number(attachment) === TextureRenderTargetAttachment.DEPTH_ATTACHMENT;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!depthBufferPresent) {
|
|
143
|
-
this._depthBuffer = gl.createRenderbuffer();
|
|
144
|
-
gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthBuffer);
|
|
145
|
-
|
|
146
|
-
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.width, this.size.height);
|
|
147
|
-
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthBuffer);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
this.setUpdated(true);
|
|
151
|
-
|
|
152
|
-
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
|
|
153
|
-
throw new Error("Error initializing render buffer: the framebuffer is not complete");
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer);
|
|
158
|
-
|
|
159
|
-
this._screenViewport = this.renderer.state.viewport;
|
|
160
|
-
this.renderer.state.viewport = this.size;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
private endUpdateTexture(): void {
|
|
164
|
-
const { gl } = this.renderer;
|
|
165
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
166
|
-
this.renderer.state.viewport = this._screenViewport;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private beginUpdateCubemap(face: CubeMapFace): void {
|
|
170
|
-
const { gl } = this.renderer;
|
|
171
|
-
const textureRenderer = this.attachments[0];
|
|
172
|
-
const textureApi = textureRenderer?.getApiObject();
|
|
173
|
-
const texture = textureRenderer?.texture;
|
|
174
|
-
|
|
175
|
-
if (this.dirty) {
|
|
176
|
-
// Cubemap render only supports ONE texture target
|
|
177
|
-
// to COLOR_ATTACHMENT_0, check this and throw an exception
|
|
178
|
-
// if there are more attachments
|
|
179
|
-
if (Object.keys(this.attachments).length !== 1) {
|
|
180
|
-
throw new Error(`Unexpected number of texture attachments rendering cube map. The cube map renderer supports only one color attachment.`);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
this.destroy();
|
|
184
|
-
this._framebuffers = [];
|
|
185
|
-
this._depthBuffers = [];
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
const { width, height } = texture.size;
|
|
189
|
-
for (let i = 0; i < 6; ++i) {
|
|
190
|
-
const fb = gl.createFramebuffer();
|
|
191
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
|
192
|
-
this._framebuffers.push(fb);
|
|
193
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, textureApi, 0);
|
|
194
|
-
|
|
195
|
-
const rb = gl.createRenderbuffer();
|
|
196
|
-
this._depthBuffers.push(rb);
|
|
197
|
-
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
|
|
198
|
-
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
|
|
199
|
-
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
|
|
200
|
-
|
|
201
|
-
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
|
202
|
-
const statusCode = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
203
|
-
throw new Error(`Cubemap frame buffer not complete in cube side #${i}: ${glEnumToString(gl, statusCode)}`);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
this.setUpdated(true);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// bind face
|
|
211
|
-
// CubeMapFace.POSITIVE_X === 1, see CubeMapFace definition at render/RenderBuffer.js
|
|
212
|
-
const faceIndex = face - 1;
|
|
213
|
-
if (!this._framebuffers || faceIndex < 0 || faceIndex >= this._framebuffers.length) {
|
|
214
|
-
throw new Error(`RenderBuffer.beginUpdateCubemap(): invalid cube map face index ${faceIndex}`);
|
|
215
|
-
}
|
|
216
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffers[faceIndex]);
|
|
217
|
-
|
|
218
|
-
this._screenViewport = this.renderer.state.viewport;
|
|
219
|
-
this.renderer.state.viewport = texture.size;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
private endUpdateCubemap(): void {
|
|
223
|
-
const { gl } = this.renderer;
|
|
224
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
225
|
-
this.renderer.state.viewport = this._screenViewport;
|
|
226
|
-
}
|
|
1
|
+
|
|
2
|
+
import { TextureRenderTargetAttachment, TextureTargetName } from "../../base/Texture";
|
|
3
|
+
import Vec from "../../math/Vec";
|
|
4
|
+
import RenderBuffer, { RenderBufferType, CubeMapFace } from "../RenderBuffer";
|
|
5
|
+
import Texture from "../../base/Texture";
|
|
6
|
+
|
|
7
|
+
function glEnumToString(gl: WebGLRenderingContext, value: number): string {
|
|
8
|
+
for(var key in gl) {
|
|
9
|
+
if (gl[key as keyof WebGLRenderingContext] === value) {
|
|
10
|
+
return key;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return "0x" + value.toString(16);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function getAttachmentPoint(gl: WebGLRenderingContext, att: number | string): number {
|
|
17
|
+
switch (Number(att)) {
|
|
18
|
+
case TextureRenderTargetAttachment.COLOR_ATTACHMENT_0:
|
|
19
|
+
return gl.COLOR_ATTACHMENT0;
|
|
20
|
+
case TextureRenderTargetAttachment.DEPTH_ATTACHMENT:
|
|
21
|
+
return gl.DEPTH_ATTACHMENT;
|
|
22
|
+
case TextureRenderTargetAttachment.STENCIL_ATTACHMENT:
|
|
23
|
+
return gl.STENCIL_ATTACHMENT;
|
|
24
|
+
default:
|
|
25
|
+
throw new Error(`RenderBuffer.beginUpdate() Error creating render buffer. Invalid attachment ${att}.`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function getTextureTarget(gl: WebGLRenderingContext, texture: Texture): number {
|
|
30
|
+
return gl[TextureTargetName[texture.target] as keyof WebGLRenderingContext] as number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default class WebGLRenderBuffer extends RenderBuffer {
|
|
34
|
+
private _framebuffer?: WebGLFramebuffer | null;
|
|
35
|
+
private _depthBuffer?: WebGLRenderbuffer | null;
|
|
36
|
+
private _framebuffers?: WebGLFramebuffer[] | null;
|
|
37
|
+
private _depthBuffers?: WebGLRenderbuffer[] | null;
|
|
38
|
+
private _screenViewport?: Vec;
|
|
39
|
+
private _prevArrayBufferBinding?: WebGLBuffer | null;
|
|
40
|
+
private _prevElementBufferBinding?: WebGLBuffer | null;
|
|
41
|
+
constructor(renderer: any) {
|
|
42
|
+
super(renderer);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
get frameBuffer(): any {
|
|
46
|
+
return this.renderer.frameBuffer;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
saveVertexBufferState(): void {
|
|
50
|
+
const { gl } = this.renderer;
|
|
51
|
+
this._prevArrayBufferBinding = gl.getParameter(gl.ARRAY_BUFFER_BINDING);
|
|
52
|
+
this._prevElementBufferBinding = gl.getParameter(gl.ELEMENT_ARRAY_BUFFER_BINDING);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
restoreVertexBufferState(): void {
|
|
56
|
+
const { gl } = this.renderer;
|
|
57
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._prevArrayBufferBinding);
|
|
58
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._prevElementBufferBinding);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
beginUpdate(textureFace: CubeMapFace = CubeMapFace.NONE): void {
|
|
62
|
+
if (this.type === RenderBufferType.TEXTURE) {
|
|
63
|
+
this.beginUpdateTexture();
|
|
64
|
+
}
|
|
65
|
+
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
66
|
+
this.beginUpdateCubemap(textureFace);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
throw new Error("The render buffer is not initialized");
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
endUpdate(textureFace: CubeMapFace = CubeMapFace.NONE): void {
|
|
74
|
+
if (this.type === RenderBufferType.TEXTURE) {
|
|
75
|
+
this.endUpdateTexture();
|
|
76
|
+
}
|
|
77
|
+
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
78
|
+
this.endUpdateCubemap();
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
throw new Error("The render buffer is not initialized");
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
destroy(): void {
|
|
86
|
+
const { gl } = this.renderer;
|
|
87
|
+
if (this.type === RenderBufferType.TEXTURE) {
|
|
88
|
+
if (this._framebuffer) {
|
|
89
|
+
gl.deleteFramebuffer(this._framebuffer);
|
|
90
|
+
this._framebuffer = null;
|
|
91
|
+
}
|
|
92
|
+
if (this._depthBuffer) {
|
|
93
|
+
gl.deleteRenderbuffer(this._depthBuffer);
|
|
94
|
+
this._depthBuffer = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else if (this.type === RenderBufferType.CUBE_MAP) {
|
|
98
|
+
if (this._framebuffers?.length) {
|
|
99
|
+
this._framebuffers.forEach(fb => gl.deleteFramebuffer(fb));
|
|
100
|
+
}
|
|
101
|
+
if (this._depthBuffers?.length) {
|
|
102
|
+
this._depthBuffers.forEach(db => gl.deleteRenderbuffer(db));
|
|
103
|
+
}
|
|
104
|
+
this._framebuffers = null;
|
|
105
|
+
this._depthBuffers = null;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
readPixels(x: number, y: number, width: number, height: number): Uint8Array | undefined {
|
|
110
|
+
const textureRenderer = this.attachments[0];
|
|
111
|
+
const texture = textureRenderer?.texture;
|
|
112
|
+
if (texture) {
|
|
113
|
+
const { gl } = this.renderer;
|
|
114
|
+
const data = new Uint8Array(width * height * 4);
|
|
115
|
+
gl.readPixels(x, texture.size.height - y, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
|
116
|
+
return data;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
private beginUpdateTexture(): void {
|
|
122
|
+
const { gl } = this.renderer;
|
|
123
|
+
|
|
124
|
+
if (this.dirty) {
|
|
125
|
+
if (this._framebuffer) {
|
|
126
|
+
gl.deleteFramebuffer(this._framebuffer);
|
|
127
|
+
}
|
|
128
|
+
this._framebuffer = gl.createFramebuffer();
|
|
129
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer);
|
|
130
|
+
|
|
131
|
+
let depthBufferPresent = false;
|
|
132
|
+
for (const attachment in this.attachments) {
|
|
133
|
+
const textureRenderer = this.attachments[attachment];
|
|
134
|
+
const textureApi = textureRenderer.getApiObject();
|
|
135
|
+
const attachmentPoint = getAttachmentPoint(gl,attachment);
|
|
136
|
+
const textureTarget = getTextureTarget(gl,textureRenderer.texture);
|
|
137
|
+
const level = 0;
|
|
138
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, textureTarget, textureApi, level);
|
|
139
|
+
depthBufferPresent = depthBufferPresent || Number(attachment) === TextureRenderTargetAttachment.DEPTH_ATTACHMENT;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!depthBufferPresent) {
|
|
143
|
+
this._depthBuffer = gl.createRenderbuffer();
|
|
144
|
+
gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthBuffer);
|
|
145
|
+
|
|
146
|
+
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.size.width, this.size.height);
|
|
147
|
+
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this._depthBuffer);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
this.setUpdated(true);
|
|
151
|
+
|
|
152
|
+
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
|
|
153
|
+
throw new Error("Error initializing render buffer: the framebuffer is not complete");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer);
|
|
158
|
+
|
|
159
|
+
this._screenViewport = this.renderer.state.viewport;
|
|
160
|
+
this.renderer.state.viewport = this.size;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
private endUpdateTexture(): void {
|
|
164
|
+
const { gl } = this.renderer;
|
|
165
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
166
|
+
this.renderer.state.viewport = this._screenViewport;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private beginUpdateCubemap(face: CubeMapFace): void {
|
|
170
|
+
const { gl } = this.renderer;
|
|
171
|
+
const textureRenderer = this.attachments[0];
|
|
172
|
+
const textureApi = textureRenderer?.getApiObject();
|
|
173
|
+
const texture = textureRenderer?.texture;
|
|
174
|
+
|
|
175
|
+
if (this.dirty) {
|
|
176
|
+
// Cubemap render only supports ONE texture target
|
|
177
|
+
// to COLOR_ATTACHMENT_0, check this and throw an exception
|
|
178
|
+
// if there are more attachments
|
|
179
|
+
if (Object.keys(this.attachments).length !== 1) {
|
|
180
|
+
throw new Error(`Unexpected number of texture attachments rendering cube map. The cube map renderer supports only one color attachment.`);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
this.destroy();
|
|
184
|
+
this._framebuffers = [];
|
|
185
|
+
this._depthBuffers = [];
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
const { width, height } = texture.size;
|
|
189
|
+
for (let i = 0; i < 6; ++i) {
|
|
190
|
+
const fb = gl.createFramebuffer();
|
|
191
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
|
192
|
+
this._framebuffers.push(fb);
|
|
193
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, textureApi, 0);
|
|
194
|
+
|
|
195
|
+
const rb = gl.createRenderbuffer();
|
|
196
|
+
this._depthBuffers.push(rb);
|
|
197
|
+
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
|
|
198
|
+
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
|
|
199
|
+
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, rb);
|
|
200
|
+
|
|
201
|
+
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
|
|
202
|
+
const statusCode = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
203
|
+
throw new Error(`Cubemap frame buffer not complete in cube side #${i}: ${glEnumToString(gl, statusCode)}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.setUpdated(true);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// bind face
|
|
211
|
+
// CubeMapFace.POSITIVE_X === 1, see CubeMapFace definition at render/RenderBuffer.js
|
|
212
|
+
const faceIndex = face - 1;
|
|
213
|
+
if (!this._framebuffers || faceIndex < 0 || faceIndex >= this._framebuffers.length) {
|
|
214
|
+
throw new Error(`RenderBuffer.beginUpdateCubemap(): invalid cube map face index ${faceIndex}`);
|
|
215
|
+
}
|
|
216
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffers[faceIndex]);
|
|
217
|
+
|
|
218
|
+
this._screenViewport = this.renderer.state.viewport;
|
|
219
|
+
this.renderer.state.viewport = texture.size;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private endUpdateCubemap(): void {
|
|
223
|
+
const { gl } = this.renderer;
|
|
224
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
225
|
+
this.renderer.state.viewport = this._screenViewport;
|
|
226
|
+
}
|
|
227
227
|
}
|