diff --git a/.changeset/brave-nails-wave.md b/.changeset/brave-nails-wave.md new file mode 100644 index 00000000000..c425682cf9e --- /dev/null +++ b/.changeset/brave-nails-wave.md @@ -0,0 +1,7 @@ +--- +'@antv/l7-core': patch +'@antv/l7-renderer': patch +'@antv/l7-scene': patch +--- + +refactor: remove regl render mode diff --git a/examples/constants.ts b/examples/constants.ts index 4a917134e33..cda0cf6048b 100644 --- a/examples/constants.ts +++ b/examples/constants.ts @@ -2,7 +2,6 @@ import type { GUIOptions, TestCaseBasemap } from './types'; export const DEFAULT_GUI_OPTIONS: GUIOptions = { map: 'Map', - renderer: 'device', animate: false, enableWebGPU: false, }; diff --git a/examples/main.tsx b/examples/main.tsx index ce779b3fcdb..41b5ba627af 100644 --- a/examples/main.tsx +++ b/examples/main.tsx @@ -37,9 +37,6 @@ export const Main = () => { guiRef.current .add(inintGuiOptions, 'map', MAP_TYPES) .onChange((map: GUIOptions['map']) => onChange({ map })); - guiRef.current - .add(inintGuiOptions, 'renderer', ['regl', 'device']) - .onChange((renderer: GUIOptions['renderer']) => onChange({ renderer })); guiRef.current .add(inintGuiOptions, 'enableWebGPU') .onChange((enableWebGPU: GUIOptions['enableWebGPU']) => onChange({ enableWebGPU })); diff --git a/examples/types.ts b/examples/types.ts index 418724fe12c..e9fdd093852 100644 --- a/examples/types.ts +++ b/examples/types.ts @@ -1,10 +1,8 @@ import type { Scene } from '@antv/l7'; -import type { ISceneConfig } from '@antv/l7-core'; import type { Controller, GUI } from 'lil-gui'; export type GUIOptions = { map: TestCaseBasemap; - renderer: ISceneConfig['renderer']; animate: boolean; enableWebGPU: boolean; [keys: string]: any; diff --git a/packages/core/src/services/config/IConfigService.ts b/packages/core/src/services/config/IConfigService.ts index e53d18535d0..15887032ae9 100644 --- a/packages/core/src/services/config/IConfigService.ts +++ b/packages/core/src/services/config/IConfigService.ts @@ -16,10 +16,6 @@ export interface ISceneConfig extends IRenderConfig { // TODO: 场景是否支持 stencil mask stencil?: boolean; debug?: boolean; - /** - * Support regl & @antv/g-device-api now - */ - renderer?: 'regl' | 'device'; } export interface IGlobalConfigService { diff --git a/packages/renderer/__tests__/index.spec.ts b/packages/renderer/__tests__/index.spec.ts index 595868f8922..f13284cded6 100644 --- a/packages/renderer/__tests__/index.spec.ts +++ b/packages/renderer/__tests__/index.spec.ts @@ -1,4 +1,4 @@ -import { DeviceRendererService } from '../src/index'; +import { DeviceRendererService } from '../src'; describe('template', () => { it('DeviceRenderer', () => { diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 6391f00924a..a54c825af58 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -23,8 +23,7 @@ "@antv/g-device-api": "^1.6.4", "@antv/l7-core": "workspace:*", "@antv/l7-utils": "workspace:*", - "@babel/runtime": "^7.7.7", - "regl": "1.6.1" + "@babel/runtime": "^7.7.7" }, "devDependencies": { "@antv/l7-test-utils": "workspace:^" diff --git a/packages/renderer/src/device/DeviceAttribute.ts b/packages/renderer/src/DeviceAttribute.ts similarity index 100% rename from packages/renderer/src/device/DeviceAttribute.ts rename to packages/renderer/src/DeviceAttribute.ts diff --git a/packages/renderer/src/device/DeviceBuffer.ts b/packages/renderer/src/DeviceBuffer.ts similarity index 100% rename from packages/renderer/src/device/DeviceBuffer.ts rename to packages/renderer/src/DeviceBuffer.ts diff --git a/packages/renderer/src/device/DeviceCache.ts b/packages/renderer/src/DeviceCache.ts similarity index 100% rename from packages/renderer/src/device/DeviceCache.ts rename to packages/renderer/src/DeviceCache.ts diff --git a/packages/renderer/src/device/DeviceElements.ts b/packages/renderer/src/DeviceElements.ts similarity index 100% rename from packages/renderer/src/device/DeviceElements.ts rename to packages/renderer/src/DeviceElements.ts diff --git a/packages/renderer/src/device/DeviceFramebuffer.ts b/packages/renderer/src/DeviceFramebuffer.ts similarity index 100% rename from packages/renderer/src/device/DeviceFramebuffer.ts rename to packages/renderer/src/DeviceFramebuffer.ts diff --git a/packages/renderer/src/device/DeviceModel.ts b/packages/renderer/src/DeviceModel.ts similarity index 99% rename from packages/renderer/src/device/DeviceModel.ts rename to packages/renderer/src/DeviceModel.ts index 78c7ed5b401..b215e4dece7 100644 --- a/packages/renderer/src/device/DeviceModel.ts +++ b/packages/renderer/src/DeviceModel.ts @@ -27,11 +27,11 @@ import type { } from '@antv/l7-core'; import { gl } from '@antv/l7-core'; import { lodashUtil } from '@antv/l7-utils'; -import type DeviceRendererService from '.'; import type DeviceAttribute from './DeviceAttribute'; import type DeviceBuffer from './DeviceBuffer'; import type DeviceElements from './DeviceElements'; import DeviceFramebuffer from './DeviceFramebuffer'; +import type { DeviceRendererService } from './DeviceRendererService'; import DeviceTexture2D from './DeviceTexture2D'; import { blendEquationMap, diff --git a/packages/renderer/src/device/index.ts b/packages/renderer/src/DeviceRendererService.ts similarity index 99% rename from packages/renderer/src/device/index.ts rename to packages/renderer/src/DeviceRendererService.ts index b0e37912dc4..777a72cc98e 100644 --- a/packages/renderer/src/device/index.ts +++ b/packages/renderer/src/DeviceRendererService.ts @@ -41,7 +41,7 @@ const { isUndefined } = lodashUtil; /** * Device API renderer */ -export default class DeviceRendererService implements IRendererService { +export class DeviceRendererService implements IRendererService { uniformBuffers: IBuffer[] = []; extensionObject: IExtensions; private device: Device; diff --git a/packages/renderer/src/device/DeviceTexture2D.ts b/packages/renderer/src/DeviceTexture2D.ts similarity index 100% rename from packages/renderer/src/device/DeviceTexture2D.ts rename to packages/renderer/src/DeviceTexture2D.ts diff --git a/packages/renderer/src/device/constants.ts b/packages/renderer/src/constants.ts similarity index 100% rename from packages/renderer/src/device/constants.ts rename to packages/renderer/src/constants.ts diff --git a/packages/renderer/src/index.ts b/packages/renderer/src/index.ts index 6c33f312633..2f88eaecad5 100644 --- a/packages/renderer/src/index.ts +++ b/packages/renderer/src/index.ts @@ -1,4 +1 @@ -import DeviceRendererService from './device'; -import ReglRendererService from './regl'; - -export { DeviceRendererService, ReglRendererService }; +export { DeviceRendererService } from './DeviceRendererService'; diff --git a/packages/renderer/src/regl/ReglAttribute.ts b/packages/renderer/src/regl/ReglAttribute.ts deleted file mode 100644 index 686987bd089..00000000000 --- a/packages/renderer/src/regl/ReglAttribute.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { IAttribute, IAttributeInitializationOptions, IBuffer } from '@antv/l7-core'; -import type regl from 'regl'; -import type ReglBuffer from './ReglBuffer'; - -/** - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#attributes - */ -export default class ReglAttribute implements IAttribute { - private attribute: regl.Attribute; - private buffer: IBuffer; - - constructor(gl: regl.Regl, options: IAttributeInitializationOptions) { - const { buffer, offset, stride, normalized, size, divisor } = options; - this.buffer = buffer; - this.attribute = { - buffer: (buffer as ReglBuffer).get(), - offset: offset || 0, - stride: stride || 0, - normalized: normalized || false, - divisor: divisor || 0, - }; - - if (size) { - this.attribute.size = size; - } - } - - public get() { - return this.attribute; - } - - public updateBuffer(options: { - // 用于替换的数据 - data: number[] | number[][] | Uint8Array | Uint16Array | Uint32Array; - // 原 Buffer 替换位置,单位为 byte - offset: number; - }) { - this.buffer.subData(options); - } - - public destroy() { - this.buffer.destroy(); - } -} diff --git a/packages/renderer/src/regl/ReglBuffer.ts b/packages/renderer/src/regl/ReglBuffer.ts deleted file mode 100644 index 7b23b8bf412..00000000000 --- a/packages/renderer/src/regl/ReglBuffer.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { IBuffer, IBufferInitializationOptions } from '@antv/l7-core'; -import { gl } from '@antv/l7-core'; -import type regl from 'regl'; -import { dataTypeMap, usageMap } from './constants'; - -/** - * adaptor for regl.Buffer - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#buffers - */ -export default class ReglBuffer implements IBuffer { - private buffer: regl.Buffer; - - private isDestroyed: boolean = false; - - constructor(reGl: regl.Regl, options: IBufferInitializationOptions) { - const { data, usage, type } = options; - this.buffer = reGl.buffer({ - data, - usage: usageMap[usage || gl.STATIC_DRAW], - type: dataTypeMap[type || gl.UNSIGNED_BYTE], - // length: 0, - }); - } - - public get() { - return this.buffer; - } - - public destroy() { - if (!this.isDestroyed) { - this.buffer.destroy(); - } - this.isDestroyed = true; - } - - public subData({ - data, - offset, - }: { - data: number[] | number[][] | Uint8Array | Uint16Array | Uint32Array; - offset: number; - }) { - this.buffer.subdata(data, offset); - } -} diff --git a/packages/renderer/src/regl/ReglElements.ts b/packages/renderer/src/regl/ReglElements.ts deleted file mode 100644 index 541b282b9c3..00000000000 --- a/packages/renderer/src/regl/ReglElements.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { IElements, IElementsInitializationOptions } from '@antv/l7-core'; -import { gl } from '@antv/l7-core'; -import type regl from 'regl'; -import { dataTypeMap, usageMap } from './constants'; - -/** - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#elements - */ -export default class ReglElements implements IElements { - private elements: regl.Elements; - - constructor(reGl: regl.Regl, options: IElementsInitializationOptions) { - const { data, usage, type, count } = options; - this.elements = reGl.elements({ - data, - usage: usageMap[usage || gl.STATIC_DRAW], - type: dataTypeMap[type || gl.UNSIGNED_BYTE] as 'uint8' | 'uint16' | 'uint32', - count, - }); - } - - public get() { - return this.elements; - } - - public subData({ - data, - }: { - data: number[] | number[][] | Uint8Array | Uint16Array | Uint32Array; - }) { - this.elements.subdata(data); - } - - public destroy() { - // this.elements.destroy(); - } -} diff --git a/packages/renderer/src/regl/ReglFramebuffer.ts b/packages/renderer/src/regl/ReglFramebuffer.ts deleted file mode 100644 index 8e1cc69d4ad..00000000000 --- a/packages/renderer/src/regl/ReglFramebuffer.ts +++ /dev/null @@ -1,51 +0,0 @@ -import type { - IFramebuffer, - IFramebufferInitializationOptions, - IRenderbuffer, - ITexture2D, -} from '@antv/l7-core'; -import type regl from 'regl'; -import type ReglTexture2D from './ReglTexture2D'; - -/** - * adaptor for regl.Framebuffer - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#framebuffers - */ -export default class ReglFramebuffer implements IFramebuffer { - private framebuffer: regl.Framebuffer; - - constructor(reGl: regl.Regl, options: IFramebufferInitializationOptions) { - const { width, height, color, colors } = options; - - const framebufferOptions: regl.FramebufferOptions = { - width, - height, - }; - - if (Array.isArray(colors)) { - framebufferOptions.colors = colors.map((c: ITexture2D | IRenderbuffer) => - (c as ReglTexture2D).get(), - ); - } - - if (color && typeof color !== 'boolean') { - framebufferOptions.color = (color as ReglTexture2D).get(); - } - - // TODO: depth & stencil - - this.framebuffer = reGl.framebuffer(framebufferOptions); - } - - public get() { - return this.framebuffer; - } - - public destroy() { - this.framebuffer.destroy(); - } - - public resize({ width, height }: { width: number; height: number }) { - this.framebuffer.resize(width, height); - } -} diff --git a/packages/renderer/src/regl/ReglModel.ts b/packages/renderer/src/regl/ReglModel.ts deleted file mode 100644 index 4c6777093b9..00000000000 --- a/packages/renderer/src/regl/ReglModel.ts +++ /dev/null @@ -1,404 +0,0 @@ -import { ClipSpaceNearZ, preprocessShader_GLSL, ViewportOrigin } from '@antv/g-device-api'; -import type { - IAttribute, - IBlendOptions, - IElements, - IModel, - IModelDrawOptions, - IModelInitializationOptions, - IUniform, -} from '@antv/l7-core'; -import { gl, removeDuplicateUniforms } from '@antv/l7-core'; -import { lodashUtil } from '@antv/l7-utils'; -import type regl from 'regl'; -import { - blendEquationMap, - blendFuncMap, - cullFaceMap, - depthFuncMap, - primitiveMap, - stencilFuncMap, - stencilOpMap, -} from './constants'; -import type ReglAttribute from './ReglAttribute'; -import type ReglElements from './ReglElements'; -import type ReglFramebuffer from './ReglFramebuffer'; -import type ReglTexture2D from './ReglTexture2D'; -const { isPlainObject, isTypedArray } = lodashUtil; - -/** - * adaptor for regl.DrawCommand - */ -export default class ReglModel implements IModel { - private reGl: regl.Regl; - private destroyed: boolean = false; - private drawCommand: regl.DrawCommand; - private drawParams: regl.DrawConfig; - private options: IModelInitializationOptions; - private uniforms: { - [key: string]: IUniform; - } = {}; - - constructor(reGl: regl.Regl, options: IModelInitializationOptions) { - this.reGl = reGl; - const { vs, fs, attributes, uniforms, primitive, count, elements, depth, cull, instances } = - options; - - /** - * try to compile GLSL 300 to 100 - */ - const vendorInfo = { - platformString: 'WebGL1', - glslVersion: '#version 100', - explicitBindingLocations: false, - separateSamplerTextures: false, - viewportOrigin: ViewportOrigin.LOWER_LEFT, - clipSpaceNearZ: ClipSpaceNearZ.NEGATIVE_ONE, - supportMRT: false, - }; - - const reglUniforms: { [key: string]: IUniform } = {}; - this.options = options; - if (uniforms) { - this.uniforms = this.extractUniforms(uniforms); - Object.keys(uniforms).forEach((uniformName) => { - // use regl prop API - // @ts-ignore - reglUniforms[uniformName] = reGl.prop(uniformName); - }); - } - - const reglAttributes: { [key: string]: regl.Attribute } = {}; - Object.keys(attributes).forEach((name: string) => { - reglAttributes[name] = (attributes[name] as ReglAttribute).get(); - }); - const frag = removeDuplicateUniforms( - preprocessShader_GLSL(vendorInfo, 'frag', fs, null, false), - ); - - const vert = removeDuplicateUniforms( - preprocessShader_GLSL(vendorInfo, 'vert', vs, null, false), - ); - - const drawParams: regl.DrawConfig = { - attributes: reglAttributes, - frag, - uniforms: reglUniforms, - vert, - // @ts-ignore - colorMask: reGl.prop('colorMask'), - lineWidth: 1, - blend: { - // @ts-ignore - enable: reGl.prop('blend.enable'), - // @ts-ignore - func: reGl.prop('blend.func'), - // @ts-ignore - equation: reGl.prop('blend.equation'), - // @ts-ignore - color: reGl.prop('blend.color'), - }, - stencil: { - // @ts-ignore - enable: reGl.prop('stencil.enable'), - // @ts-ignore - mask: reGl.prop('stencil.mask'), - // @ts-ignore - func: reGl.prop('stencil.func'), - // @ts-ignore - opFront: reGl.prop('stencil.opFront'), - // @ts-ignore - opBack: reGl.prop('stencil.opBack'), - }, - primitive: primitiveMap[primitive === undefined ? gl.TRIANGLES : primitive], - }; - if (instances) { - drawParams.instances = instances; - } - - // Tip: - // elements 中可能包含 count,此时不应传入 - // count 和 elements 相比、count 优先 - if (count) { - drawParams.count = count; - } else if (elements) { - drawParams.elements = (elements as ReglElements).get(); - } - - this.initDepthDrawParams({ depth }, drawParams); - // this.initBlendDrawParams({ blend }, drawParams); - // this.initStencilDrawParams({ stencil }, drawParams); - this.initCullDrawParams({ cull }, drawParams); - this.drawCommand = reGl(drawParams); - this.drawParams = drawParams; - } - - public updateAttributesAndElements( - attributes: { [key: string]: IAttribute }, - elements: IElements, - ) { - const reglAttributes: { [key: string]: regl.Attribute } = {}; - Object.keys(attributes).forEach((name: string) => { - reglAttributes[name] = (attributes[name] as ReglAttribute).get(); - }); - this.drawParams.attributes = reglAttributes; - this.drawParams.elements = (elements as ReglElements).get(); - - this.drawCommand = this.reGl(this.drawParams); - } - - public updateAttributes(attributes: { [key: string]: IAttribute }) { - const reglAttributes: { [key: string]: regl.Attribute } = {}; - Object.keys(attributes).forEach((name: string) => { - reglAttributes[name] = (attributes[name] as ReglAttribute).get(); - }); - this.drawParams.attributes = reglAttributes; - this.drawCommand = this.reGl(this.drawParams); - } - - public addUniforms(uniforms: { [key: string]: IUniform }) { - this.uniforms = { - ...this.uniforms, - ...this.extractUniforms(uniforms), - }; - } - - public draw(options: IModelDrawOptions, pick?: boolean) { - if (this.drawParams.attributes && Object.keys(this.drawParams.attributes).length === 0) { - return; - } - const uniforms: { - [key: string]: IUniform; - } = { - ...this.uniforms, - ...this.extractUniforms(options.uniforms || {}), - }; - const reglDrawProps: { - [key: string]: - | regl.Framebuffer - | regl.Texture2D - | number - | number[] - | Partial - | boolean; - } = {}; - Object.keys(uniforms).forEach((uniformName: string) => { - const type = typeof uniforms[uniformName]; - if ( - type === 'boolean' || - type === 'number' || - Array.isArray(uniforms[uniformName]) || - // @ts-ignore - uniforms[uniformName].BYTES_PER_ELEMENT - ) { - reglDrawProps[uniformName] = uniforms[uniformName] as number | number[] | boolean; - } else { - reglDrawProps[uniformName] = ( - uniforms[uniformName] as ReglFramebuffer | ReglTexture2D - ).get(); - } - }); - // 更新 blend - // @ts-ignore - reglDrawProps.blend = pick // picking 操作不应该使用 blend - ? this.getBlendDrawParams({ - blend: { enable: false }, - }) - : this.getBlendDrawParams(options); - - // 更新stentil 配置 - // @ts-ignore - reglDrawProps.stencil = this.getStencilDrawParams(options); - // @ts-ignore - reglDrawProps.colorMask = this.getColorMaskDrawParams(options, pick); - - // 在进行拾取操作的绘制中,不应该使用叠加模式 - picking 根据拾取的颜色作为判断的输入,而叠加模式会产生新的,在 id 序列中不存在的颜色 - this.drawCommand(reglDrawProps); - } - - public destroy() { - // @ts-ignore - this.drawParams?.elements?.destroy(); - if (this.options.attributes) { - Object.values(this.options.attributes).forEach((attr: any) => { - // @ts-ignore - (attr as ReglAttribute)?.destroy(); - }); - } - this.destroyed = true; - } - - /** - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#depth-buffer - */ - private initDepthDrawParams( - { depth }: Pick, - drawParams: regl.DrawConfig, - ) { - if (depth) { - drawParams.depth = { - enable: depth.enable === undefined ? true : !!depth.enable, - mask: depth.mask === undefined ? true : !!depth.mask, - func: depthFuncMap[depth.func || gl.LESS], - range: depth.range || [0, 1], - }; - } - } - - private getBlendDrawParams({ blend }: Pick) { - const { enable, func, equation, color = [0, 0, 0, 0] } = blend || {}; - // @ts-ignore - return { - enable: !!enable, - func: { - srcRGB: blendFuncMap[(func && func.srcRGB) || gl.SRC_ALPHA], - srcAlpha: blendFuncMap[(func && func.srcAlpha) || gl.SRC_ALPHA], - dstRGB: blendFuncMap[(func && func.dstRGB) || gl.ONE_MINUS_SRC_ALPHA], - dstAlpha: blendFuncMap[(func && func.dstAlpha) || gl.ONE_MINUS_SRC_ALPHA], - }, - equation: { - rgb: blendEquationMap[(equation && equation.rgb) || gl.FUNC_ADD], - alpha: blendEquationMap[(equation && equation.alpha) || gl.FUNC_ADD], - }, - color, - }; - } - /** - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#stencil - */ - private getStencilDrawParams({ stencil }: Pick) { - const { - enable, - mask = -1, - func = { - cmp: gl.ALWAYS, - ref: 0, - mask: -1, - }, - opFront = { - fail: gl.KEEP, - zfail: gl.KEEP, - zpass: gl.KEEP, - }, - opBack = { - fail: gl.KEEP, - zfail: gl.KEEP, - zpass: gl.KEEP, - }, - } = stencil || {}; - return { - enable: !!enable, - mask, - func: { - ...func, - cmp: stencilFuncMap[func.cmp], - }, - opFront: { - fail: stencilOpMap[opFront.fail], - zfail: stencilOpMap[opFront.zfail], - zpass: stencilOpMap[opFront.zpass], - }, - opBack: { - fail: stencilOpMap[opBack.fail], - zfail: stencilOpMap[opBack.zfail], - zpass: stencilOpMap[opBack.zpass], - }, - }; - } - - private getColorMaskDrawParams( - { stencil }: Pick, - pick: boolean, - ) { - // TODO: 重构相关参数 - // 掩模模式下,颜色通道全部关闭 - const colorMask = - stencil?.enable && stencil.opFront && !pick - ? [false, false, false, false] - : [true, true, true, true]; // 非掩码模式下,颜色通道全部开启 - return colorMask; - } - - /** - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#culling - */ - private initCullDrawParams( - { cull }: Pick, - drawParams: regl.DrawConfig, - ) { - if (cull) { - const { enable, face = gl.BACK } = cull; - drawParams.cull = { - enable: !!enable, - face: cullFaceMap[face], - }; - } - } - - /** - * 考虑结构体命名, eg: - * a: { b: 1 } -> 'a.b' - * a: [ { b: 1 } ] -> 'a[0].b' - */ - private extractUniforms(uniforms: { [key: string]: IUniform }): { - [key: string]: IUniform; - } { - const extractedUniforms = {}; - Object.keys(uniforms).forEach((uniformName) => { - this.extractUniformsRecursively(uniformName, uniforms[uniformName], extractedUniforms, ''); - }); - - return extractedUniforms; - } - - private extractUniformsRecursively( - uniformName: string, - uniformValue: IUniform, - uniforms: { - [key: string]: IUniform; - }, - prefix: string, - ) { - if ( - uniformValue === null || - typeof uniformValue === 'number' || // u_A: 1 - typeof uniformValue === 'boolean' || // u_A: false - (Array.isArray(uniformValue) && typeof uniformValue[0] === 'number') || // u_A: [1, 2, 3] - isTypedArray(uniformValue) || // u_A: Float32Array - // @ts-ignore - uniformValue === '' || - 'resize' in uniformValue - ) { - uniforms[`${prefix && prefix + '.'}${uniformName}`] = uniformValue; - return; - } - - // u_Struct.a.b.c - if (isPlainObject(uniformValue)) { - Object.keys(uniformValue).forEach((childName) => { - this.extractUniformsRecursively( - childName, - // @ts-ignore - uniformValue[childName], - uniforms, - `${prefix && prefix + '.'}${uniformName}`, - ); - }); - } - - // u_Struct[0].a - if (Array.isArray(uniformValue)) { - uniformValue.forEach((child, idx) => { - Object.keys(child).forEach((childName) => { - this.extractUniformsRecursively( - childName, - // @ts-ignore - child[childName], - uniforms, - `${prefix && prefix + '.'}${uniformName}[${idx}]`, - ); - }); - }); - } - } -} diff --git a/packages/renderer/src/regl/ReglRenderbuffer.ts b/packages/renderer/src/regl/ReglRenderbuffer.ts deleted file mode 100644 index b56eb2f71e0..00000000000 --- a/packages/renderer/src/regl/ReglRenderbuffer.ts +++ /dev/null @@ -1,32 +0,0 @@ -import type { IRenderbuffer, IRenderbufferInitializationOptions } from '@antv/l7-core'; -import type regl from 'regl'; -import { formatMap } from './constants'; - -/** - * adaptor for regl.Renderbuffer - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#renderbuffers - */ -export default class ReglRenderbuffer implements IRenderbuffer { - private renderbuffer: regl.Renderbuffer; - - constructor(reGl: regl.Regl, options: IRenderbufferInitializationOptions) { - const { width, height, format } = options; - this.renderbuffer = reGl.renderbuffer({ - width, - height, - format: formatMap[format] as regl.RenderbufferFormat, - }); - } - - public get() { - return this.renderbuffer; - } - - public destroy() { - this.renderbuffer.destroy(); - } - - public resize({ width, height }: { width: number; height: number }) { - this.renderbuffer.resize(width, height); - } -} diff --git a/packages/renderer/src/regl/ReglTexture2D.ts b/packages/renderer/src/regl/ReglTexture2D.ts deleted file mode 100644 index 5e8408e88cc..00000000000 --- a/packages/renderer/src/regl/ReglTexture2D.ts +++ /dev/null @@ -1,112 +0,0 @@ -import type { ITexture2D, ITexture2DInitializationOptions } from '@antv/l7-core'; -import { gl } from '@antv/l7-core'; -import type regl from 'regl'; -import { - colorSpaceMap, - dataTypeMap, - filterMap, - formatMap, - mipmapMap, - wrapModeMap, -} from './constants'; - -/** - * adaptor for regl.Buffer - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md#buffers - */ -export default class ReglTexture2D implements ITexture2D { - private texture: regl.Texture2D; - private width: number; - private height: number; - private isDestroy: boolean = false; - - constructor(reGl: regl.Regl, options: ITexture2DInitializationOptions) { - const { - data, - type = gl.UNSIGNED_BYTE, - width, - height, - flipY = false, - format = gl.RGBA, - mipmap = false, - wrapS = gl.CLAMP_TO_EDGE, - wrapT = gl.CLAMP_TO_EDGE, - aniso = 0, - alignment = 1, - premultiplyAlpha = false, - mag = gl.NEAREST, - min = gl.NEAREST, - colorSpace = gl.BROWSER_DEFAULT_WEBGL, - x = 0, - y = 0, - copy = false, - } = options; - this.width = width; - this.height = height; - - const textureOptions: regl.Texture2DOptions = { - width, - height, - // @ts-ignore - type: dataTypeMap[type], - format: formatMap[format], - wrapS: wrapModeMap[wrapS], - wrapT: wrapModeMap[wrapT], - // @ts-ignore - mag: filterMap[mag], - min: filterMap[min], - alignment, - flipY, - colorSpace: colorSpaceMap[colorSpace], - premultiplyAlpha, - aniso, - - // copy pixels from current bind framebuffer - x, - y, - copy, - }; - - if (data) { - // @ts-ignore - textureOptions.data = data; - } - - if (typeof mipmap === 'number') { - textureOptions.mipmap = mipmapMap[mipmap]; - } else if (typeof mipmap === 'boolean') { - textureOptions.mipmap = mipmap; - } - - this.texture = reGl.texture(textureOptions); - } - - public get() { - return this.texture; - } - public update(props: regl.Texture2DOptions = {}) { - this.texture(props); - } - - public bind() { - // @ts-ignore - this.texture._texture.bind(); - } - - public resize({ width, height }: { width: number; height: number }): void { - this.texture.resize(width, height); - this.width = width; - this.height = height; - } - - public getSize(): [number, number] { - return [this.width, this.height]; - } - - public destroy() { - if (!this.isDestroy) { - this.texture?.destroy(); - } - this.isDestroy = true; - } -} diff --git a/packages/renderer/src/regl/constants.ts b/packages/renderer/src/regl/constants.ts deleted file mode 100644 index a7623c1c48e..00000000000 --- a/packages/renderer/src/regl/constants.ts +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @desc 由于 regl 使用大量字符串而非 WebGL 常量,因此需要映射 - */ -import { gl } from '@antv/l7-core'; -import type regl from 'regl'; - -// @see https://github.com/regl-project/regl/blob/gh-pages/lib/constants/primitives.json -export const primitiveMap: { - [key: string]: - | 'points' - | 'lines' - | 'line loop' - | 'line strip' - | 'triangles' - | 'triangle strip' - | 'triangle fan'; -} = { - [gl.POINTS]: 'points', - [gl.LINES]: 'lines', - [gl.LINE_LOOP]: 'line loop', - [gl.LINE_STRIP]: 'line strip', - [gl.TRIANGLES]: 'triangles', - [gl.TRIANGLE_FAN]: 'triangle fan', - [gl.TRIANGLE_STRIP]: 'triangle strip', -}; - -export const usageMap: { - [key: string]: 'static' | 'dynamic' | 'stream'; -} = { - [gl.STATIC_DRAW]: 'static', - [gl.DYNAMIC_DRAW]: 'dynamic', - [gl.STREAM_DRAW]: 'stream', -}; - -export const dataTypeMap: { - [key: string]: 'int8' | 'int16' | 'int32' | 'uint8' | 'uint16' | 'uint32' | 'float'; -} = { - [gl.BYTE]: 'int8', - // [gl.UNSIGNED_INT]: 'int16', - [gl.INT]: 'int32', - [gl.UNSIGNED_BYTE]: 'uint8', - [gl.UNSIGNED_SHORT]: 'uint16', - [gl.UNSIGNED_INT]: 'uint32', - [gl.FLOAT]: 'float', -}; - -export const formatMap: { - [key: string]: - | 'alpha' - | 'luminance' - | 'luminance alpha' - | 'rgb' - | 'rgba' - | 'rgba4' - | 'rgb5 a1' - | 'rgb565' - | 'depth' - | 'depth stencil'; -} = { - [gl.ALPHA]: 'alpha', - [gl.LUMINANCE]: 'luminance', - [gl.LUMINANCE_ALPHA]: 'luminance alpha', - [gl.RGB]: 'rgb', - [gl.RGBA]: 'rgba', - [gl.RGBA4]: 'rgba4', - [gl.RGB5_A1]: 'rgb5 a1', - [gl.RGB565]: 'rgb565', - [gl.DEPTH_COMPONENT]: 'depth', - [gl.DEPTH_STENCIL]: 'depth stencil', -}; - -export const mipmapMap: { - [key: string]: 'dont care' | 'nice' | 'fast'; -} = { - [gl.DONT_CARE]: 'dont care', - [gl.NICEST]: 'nice', - [gl.FASTEST]: 'fast', -}; - -export const filterMap: { - [key: string]: - | 'nearest' - | 'linear' - | 'mipmap' - | 'nearest mipmap linear' - | 'linear mipmap nearest' - | 'nearest mipmap nearest'; -} = { - [gl.NEAREST]: 'nearest', - [gl.LINEAR]: 'linear', - [gl.LINEAR_MIPMAP_LINEAR]: 'mipmap', - [gl.NEAREST_MIPMAP_LINEAR]: 'nearest mipmap linear', - [gl.LINEAR_MIPMAP_NEAREST]: 'linear mipmap nearest', - [gl.NEAREST_MIPMAP_NEAREST]: 'nearest mipmap nearest', -}; - -export const wrapModeMap: { - [key: string]: 'repeat' | 'clamp' | 'mirror'; -} = { - [gl.REPEAT]: 'repeat', - [gl.CLAMP_TO_EDGE]: 'clamp', - [gl.MIRRORED_REPEAT]: 'mirror', -}; - -export const colorSpaceMap: { - [key: string]: 'none' | 'browser'; -} = { - [gl.NONE]: 'none', - [gl.BROWSER_DEFAULT_WEBGL]: 'browser', -}; - -export const depthFuncMap: { - [key: string]: - | 'never' - | 'always' - | 'less' - | 'lequal' - | 'greater' - | 'gequal' - | 'equal' - | 'notequal'; -} = { - [gl.NEVER]: 'never', - [gl.ALWAYS]: 'always', - [gl.LESS]: 'less', - [gl.LEQUAL]: 'lequal', - [gl.GREATER]: 'greater', - [gl.GEQUAL]: 'gequal', - [gl.EQUAL]: 'equal', - [gl.NOTEQUAL]: 'notequal', -}; - -export const blendEquationMap: { - [key: string]: regl.BlendingEquation; -} = { - [gl.FUNC_ADD]: 'add', - [gl.MIN_EXT]: 'min', - [gl.MAX_EXT]: 'max', - [gl.FUNC_SUBTRACT]: 'subtract', - [gl.FUNC_REVERSE_SUBTRACT]: 'reverse subtract', -}; - -export const blendFuncMap: { - [key: string]: regl.BlendingFunction; -} = { - [gl.ZERO]: 'zero', - [gl.ONE]: 'one', - [gl.SRC_COLOR]: 'src color', - [gl.ONE_MINUS_SRC_COLOR]: 'one minus src color', - [gl.SRC_ALPHA]: 'src alpha', - [gl.ONE_MINUS_SRC_ALPHA]: 'one minus src alpha', - [gl.DST_COLOR]: 'dst color', - [gl.ONE_MINUS_DST_COLOR]: 'one minus dst color', - [gl.DST_ALPHA]: 'dst alpha', - [gl.ONE_MINUS_DST_ALPHA]: 'one minus dst alpha', - [gl.CONSTANT_COLOR]: 'constant color', - [gl.ONE_MINUS_CONSTANT_COLOR]: 'one minus constant color', - [gl.CONSTANT_ALPHA]: 'constant alpha', - [gl.ONE_MINUS_CONSTANT_ALPHA]: 'one minus constant alpha', - [gl.SRC_ALPHA_SATURATE]: 'src alpha saturate', -}; - -export const stencilFuncMap: { - [key: string]: regl.ComparisonOperatorType; -} = { - [gl.NEVER]: 'never', - [gl.ALWAYS]: 'always', - [gl.LESS]: 'less', - [gl.LEQUAL]: 'lequal', - [gl.GREATER]: 'greater', - [gl.GEQUAL]: 'gequal', - [gl.EQUAL]: 'equal', - [gl.NOTEQUAL]: 'notequal', -}; - -export const stencilOpMap: { - [key: string]: regl.StencilOperationType; -} = { - [gl.ZERO]: 'zero', - [gl.KEEP]: 'keep', - [gl.REPLACE]: 'replace', - [gl.INVERT]: 'invert', - [gl.INCR]: 'increment', - [gl.DECR]: 'decrement', - [gl.INCR_WRAP]: 'increment wrap', - [gl.DECR_WRAP]: 'decrement wrap', -}; - -export const cullFaceMap: { - [key: string]: regl.FaceOrientationType; -} = { - [gl.FRONT]: 'front', - [gl.BACK]: 'back', -}; diff --git a/packages/renderer/src/regl/index.ts b/packages/renderer/src/regl/index.ts deleted file mode 100644 index e19a7a94db0..00000000000 --- a/packages/renderer/src/regl/index.ts +++ /dev/null @@ -1,286 +0,0 @@ -/** - * render w/ regl - * @see https://github.com/regl-project/regl/blob/gh-pages/API.md - */ -import type { - IAttribute, - IAttributeInitializationOptions, - IBuffer, - IBufferInitializationOptions, - IClearOptions, - IElements, - IElementsInitializationOptions, - IExtensions, - IFramebuffer, - IFramebufferInitializationOptions, - IModel, - IModelInitializationOptions, - IReadPixelsOptions, - IRenderConfig, - IRendererService, - ITexture2D, - ITexture2DInitializationOptions, -} from '@antv/l7-core'; -import regl from 'regl'; -import ReglAttribute from './ReglAttribute'; -import ReglBuffer from './ReglBuffer'; -import ReglElements from './ReglElements'; -import ReglFramebuffer from './ReglFramebuffer'; -import ReglModel from './ReglModel'; -import ReglTexture2D from './ReglTexture2D'; - -/** - * regl renderer - */ -export default class ReglRendererService implements IRendererService { - uniformBuffers: IBuffer[] = []; - public extensionObject: IExtensions; - private gl: regl.Regl; - private $container: HTMLDivElement | null; - private canvas: HTMLCanvasElement; - private width: number; - private height: number; - private isDirty: boolean; - - queryVerdorInfo = () => { - return 'WebGL1'; - }; - - public async init(canvas: HTMLCanvasElement, cfg: IRenderConfig, gl?: regl.Regl): Promise { - // this.$container = $container; - this.canvas = canvas; - if (gl) { - this.gl = gl; - } else { - // tslint:disable-next-line:typedef - this.gl = await new Promise((resolve, reject) => { - regl({ - canvas: this.canvas, - attributes: { - alpha: true, - // use TAA instead of MSAA - // @see https://www.khronos.org/registry/webgl/specs/1.0/#5.2.1 - antialias: cfg.antialias, - premultipliedAlpha: true, - preserveDrawingBuffer: cfg.preserveDrawingBuffer, - - stencil: cfg.stencil, - }, - // TODO: use extensions - extensions: [ - 'OES_element_index_uint', - 'OES_standard_derivatives', // wireframe - 'ANGLE_instanced_arrays', // VSM shadow map - ], - optionalExtensions: [ - 'oes_texture_float_linear', - 'OES_texture_float', - 'EXT_texture_filter_anisotropic', - 'EXT_blend_minmax', - 'WEBGL_depth_texture', - 'WEBGL_lose_context', - ], - profile: true, - onDone: (err: Error | null, r?: regl.Regl | undefined): void => { - if (err || !r) { - reject(err); - } - // @ts-ignore - resolve(r); - }, - }); - }); - } - - this.extensionObject = { - OES_texture_float: this.testExtension('OES_texture_float'), - }; - } - - public getPointSizeRange() { - return this.gl._gl.getParameter(this.gl._gl.ALIASED_POINT_SIZE_RANGE); - } - - public testExtension(name: string) { - // OES_texture_float - return !!this.getGLContext().getExtension(name); - } - - public createModel = (options: IModelInitializationOptions): IModel => - new ReglModel(this.gl, options); - - public createAttribute = (options: IAttributeInitializationOptions): IAttribute => - new ReglAttribute(this.gl, options); - - public createBuffer = (options: IBufferInitializationOptions): IBuffer => - new ReglBuffer(this.gl, options); - - public createElements = (options: IElementsInitializationOptions): IElements => - new ReglElements(this.gl, options); - - public createTexture2D = (options: ITexture2DInitializationOptions): ITexture2D => - new ReglTexture2D(this.gl, options); - - public createFramebuffer = (options: IFramebufferInitializationOptions) => - new ReglFramebuffer(this.gl, options); - - public useFramebuffer = (framebuffer: IFramebuffer | null, drawCommands: () => void) => { - this.gl({ - framebuffer: framebuffer ? (framebuffer as ReglFramebuffer).get() : null, - })(drawCommands); - }; - - public useFramebufferAsync = async ( - framebuffer: IFramebuffer | null, - drawCommands: () => Promise, - ) => { - this.gl({ - framebuffer: framebuffer ? (framebuffer as ReglFramebuffer).get() : null, - })(drawCommands); - }; - - public clear = (options: IClearOptions) => { - // @see https://github.com/regl-project/regl/blob/gh-pages/API.md#clear-the-draw-buffer - const { color, depth, stencil, framebuffer = null } = options; - const reglClearOptions: regl.ClearOptions = { - color, - depth, - stencil, - }; - - reglClearOptions.framebuffer = - framebuffer === null ? framebuffer : (framebuffer as ReglFramebuffer).get(); - - this.gl?.clear(reglClearOptions); - }; - - public viewport = ({ - x, - y, - width, - height, - }: { - x: number; - y: number; - width: number; - height: number; - }) => { - // use WebGL context directly - // @see https://github.com/regl-project/regl/blob/gh-pages/API.md#unsafe-escape-hatch - this.gl._gl.viewport(x, y, width, height); - this.width = width; - this.height = height; - this.gl._refresh(); - }; - - public readPixels = (options: IReadPixelsOptions) => { - const { framebuffer, x, y, width, height } = options; - const readPixelsOptions: regl.ReadOptions = { - x, - y, - width, - height, - }; - if (framebuffer) { - readPixelsOptions.framebuffer = (framebuffer as ReglFramebuffer).get(); - } - return this.gl.read(readPixelsOptions); - }; - - public readPixelsAsync = async (options: IReadPixelsOptions) => { - return this.readPixels(options); - }; - - public getViewportSize = () => { - return { - width: this.gl._gl.drawingBufferWidth, - height: this.gl._gl.drawingBufferHeight, - }; - }; - - public getContainer = () => { - return this.canvas?.parentElement; - }; - - public getCanvas = () => { - // return this.$container?.getElementsByTagName('canvas')[0] || null; - return this.canvas; - }; - - public getGLContext = () => { - return this.gl._gl; - }; - - // TODO: 临时方法 - public setState() { - this.gl({ - cull: { - enable: false, - face: 'back', - }, - viewport: { - x: 0, - y: 0, - height: this.width, - width: this.height, - }, - blend: { - enable: true, - equation: 'add', - }, - framebuffer: null, - }); - this.gl._refresh(); - } - - public setBaseState() { - this.gl({ - cull: { - enable: false, - face: 'back', - }, - viewport: { - x: 0, - y: 0, - height: this.width, - width: this.height, - }, - blend: { - enable: false, - equation: 'add', - }, - framebuffer: null, - }); - this.gl._refresh(); - } - public setCustomLayerDefaults() { - const gl = this.getGLContext(); - gl.disable(gl.CULL_FACE); - } - - public setDirty(flag: boolean): void { - this.isDirty = flag; - } - - public getDirty(): boolean { - return this.isDirty; - } - - public destroy = () => { - // this.canvas = null 清除对 webgl 实例的引用 - // @ts-ignore - this.canvas = null; - - // make sure release webgl context - this.gl?._gl?.getExtension('WEBGL_lose_context')?.loseContext(); - - // @see https://github.com/regl-project/regl/blob/gh-pages/API.md#clean-up - this.gl.destroy(); - - // @ts-ignore - this.gl = null; - }; - - beginFrame(): void {} - endFrame(): void {} -} diff --git a/packages/renderer/src/device/utils/HashMap.ts b/packages/renderer/src/utils/HashMap.ts similarity index 100% rename from packages/renderer/src/device/utils/HashMap.ts rename to packages/renderer/src/utils/HashMap.ts diff --git a/packages/renderer/src/device/utils/pipeline.ts b/packages/renderer/src/utils/pipeline.ts similarity index 100% rename from packages/renderer/src/device/utils/pipeline.ts rename to packages/renderer/src/utils/pipeline.ts diff --git a/packages/renderer/src/device/utils/typedarray.ts b/packages/renderer/src/utils/typedarray.ts similarity index 100% rename from packages/renderer/src/device/utils/typedarray.ts rename to packages/renderer/src/utils/typedarray.ts diff --git a/packages/renderer/src/device/utils/webgl.ts b/packages/renderer/src/utils/webgl.ts similarity index 100% rename from packages/renderer/src/device/utils/webgl.ts rename to packages/renderer/src/utils/webgl.ts diff --git a/packages/scene/src/index.ts b/packages/scene/src/index.ts index 97215b0f540..2b7c50d5b42 100644 --- a/packages/scene/src/index.ts +++ b/packages/scene/src/index.ts @@ -29,7 +29,7 @@ import type { } from '@antv/l7-core'; import { SceneEventList, createLayerContainer, createSceneContainer } from '@antv/l7-core'; import { MaskLayer, TileLayer } from '@antv/l7-layers'; -import { DeviceRendererService, ReglRendererService } from '@antv/l7-renderer'; +import { DeviceRendererService } from '@antv/l7-renderer'; import type { IProtocolHandler } from '@antv/l7-utils'; import { DOM, SceneConifg } from '@antv/l7-utils'; import type ILayerManager from './ILayerManager'; @@ -64,17 +64,13 @@ class Scene implements IPostProcessingPassPluggable, IMapController, ILayerManag private container: L7Container; public constructor(config: ISceneConfig) { - const { id, map, renderer = 'device' } = config; + const { id, map } = config; // 创建场景容器 const sceneContainer = createSceneContainer(); this.container = sceneContainer; // 绑定地图服务 map.setContainer(sceneContainer, id); - if (renderer === 'regl') { - sceneContainer.rendererService = new ReglRendererService(); - } else { - sceneContainer.rendererService = new DeviceRendererService(); - } + sceneContainer.rendererService = new DeviceRendererService(); // 依赖注入 this.sceneService = sceneContainer.sceneService;