diff --git a/src/mol-gl/scene.ts b/src/mol-gl/scene.ts index 2f84b7541b13697eca009b64ae3f34500583f018..841242b30ea716e721147d0af98758bcf1157368 100644 --- a/src/mol-gl/scene.ts +++ b/src/mol-gl/scene.ts @@ -8,7 +8,7 @@ import { WebGLContext } from './webgl/context'; import { GraphicsRenderObject, createRenderable } from './render-object'; import { Object3D } from './object3d'; -import { Sphere3D } from '../mol-math/geometry'; +import { Sphere3D } from '../mol-math/geometry/primitives/sphere3d'; import { CommitQueue } from './commit-queue'; import { now } from '../mol-util/now'; import { arraySetRemove } from '../mol-util/array'; @@ -129,10 +129,8 @@ namespace Scene { renderableMap.set(o, renderable); boundingSphereDirty = true; boundingSphereVisibleDirty = true; - return renderable; } else { console.warn(`RenderObject with id '${o.id}' already present`); - return renderableMap.get(o)!; } } diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts index c4067b013a6217dca126bb2983011c5ca0069e42..943bf0b1a8702ef4d0eb60b31b970f68b7bdc28a 100644 --- a/src/mol-gl/webgl/program.ts +++ b/src/mol-gl/webgl/program.ts @@ -1,5 +1,5 @@ /** - * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ @@ -30,6 +30,8 @@ export interface Program { destroy: () => void } +export type Programs = { [k: string]: Program } + type Locations = { [k: string]: number } function getLocations(gl: GLRenderingContext, program: WebGLProgram, schema: RenderableSchema) { diff --git a/src/mol-gl/webgl/render-item.ts b/src/mol-gl/webgl/render-item.ts index b3d74edc8efc9c7b96bf961a55bdb182587bcc12..03f99fb5f0e6c9311f49f024468fbb2f17f4dda5 100644 --- a/src/mol-gl/webgl/render-item.ts +++ b/src/mol-gl/webgl/render-item.ts @@ -9,7 +9,7 @@ import { createAttributeBuffers, ElementsBuffer, AttributeKind } from './buffer' import { createTextures, Texture } from './texture'; import { WebGLContext, checkError } from './context'; import { ShaderCode, DefineValues } from '../shader-code'; -import { Program } from './program'; +import { Program, Programs } from './program'; import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, DefineSpec } from '../renderable/schema'; import { idFactory } from '../../mol-util/id-factory'; import { ValueCell } from '../../mol-util'; @@ -44,7 +44,7 @@ export interface RenderItem<T extends string> { getProgram: (variant: T) => Program render: (variant: T, sharedTexturesCount: number) => void - update: () => Readonly<ValueChanges> + update: () => void destroy: () => void } @@ -71,9 +71,6 @@ function createProgramVariant(ctx: WebGLContext, variant: string, defineValues: // -type ProgramVariants = Record<string, Program> -type VertexArrayVariants = Record<string, VertexArray | null> - function createValueChanges() { return { attributes: false, @@ -132,7 +129,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: const glDrawMode = getDrawMode(ctx, drawMode); - const programs: ProgramVariants = {}; + const programs: Programs = {}; for (const k of renderVariants) { programs[k] = createProgramVariant(ctx, k, defineValues, shaderCode, schema); } @@ -147,10 +144,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: elementsBuffer = resources.elements(elements.ref.value); } - const vertexArrays: VertexArrayVariants = {}; - for (const k of renderVariants) { - vertexArrays[k] = vertexArrayObject ? resources.vertexArray(programs[k], attributeBuffers, elementsBuffer) : null; - } + let vertexArray: VertexArray | null = vertexArrayObject ? resources.vertexArray(programs, attributeBuffers, elementsBuffer) : null; let drawCount: number = values.drawCount.ref.value; let instanceCount: number = values.instanceCount.ref.value; @@ -176,7 +170,6 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: program.setUniforms(uniformValueEntries); program.bindTextures(textures, sharedTexturesCount); } else { - const vertexArray = vertexArrays[variant]; if (program.id !== state.currentProgramId || program.id !== currentProgramId || materialId === -1 || materialId !== state.currentMaterialId ) { @@ -298,12 +291,9 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: } if (valueChanges.attributes || valueChanges.defines || valueChanges.elements) { - // console.log('program/defines or buffers changed, update vaos'); - for (const k of renderVariants) { - const vertexArray = vertexArrays[k]; - if (vertexArray) vertexArray.destroy(); - vertexArrays[k] = vertexArrayObject ? resources.vertexArray(programs[k], attributeBuffers, elementsBuffer) : null; - } + // console.log('program/defines or buffers changed, update vao'); + if (vertexArray) vertexArray.destroy(); + vertexArray = vertexArrayObject ? resources.vertexArray(programs, attributeBuffers, elementsBuffer) : null; } for (let i = 0, il = textures.length; i < il; ++i) { @@ -328,7 +318,7 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: if (value.ref.version !== versions[k]) { // update of textures with kind 'texture' is done externally if (schema[k].kind !== 'texture') { - // console.log('texture version changed, uploading image', k); + // console.log('materialTexture version changed, uploading image', k); texture.load(value.ref.value as TextureImage<any> | TextureVolume<any>); valueChanges.textures = true; } else { @@ -346,21 +336,20 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode: versions[k] = uniform.ref.version; } } - - return valueChanges; }, destroy: () => { if (!destroyed) { for (const k of renderVariants) { programs[k].destroy(); - const vertexArray = vertexArrays[k]; - if (vertexArray) vertexArray.destroy(); } + if (vertexArray) vertexArray.destroy(); textures.forEach(([k, texture]) => { // lifetime of textures with kind 'texture' is defined externally - if (schema[k].kind !== 'texture') { - texture.destroy(); - } + if (schema[k].kind !== 'texture') texture.destroy(); + }); + materialTextures.forEach(([k, texture]) => { + // lifetime of textures with kind 'texture' is defined externally + if (schema[k].kind !== 'texture') texture.destroy(); }); attributeBuffers.forEach(([_, buffer]) => buffer.destroy()); if (elementsBuffer) elementsBuffer.destroy(); diff --git a/src/mol-gl/webgl/resources.ts b/src/mol-gl/webgl/resources.ts index 3e2e2d370bfc771499cf8b5b7641f5ab25b2ce52..ae036cd3812072870c6d32ed930dc201b9699904 100644 --- a/src/mol-gl/webgl/resources.ts +++ b/src/mol-gl/webgl/resources.ts @@ -1,10 +1,10 @@ /** - * Copyright (c) 2020-2022 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2020-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { ProgramProps, createProgram, Program } from './program'; +import { ProgramProps, createProgram, Program, Programs } from './program'; import { ShaderType, createShader, Shader, ShaderProps } from './shader'; import { GLRenderingContext } from './compat'; import { Framebuffer, createFramebuffer } from './framebuffer'; @@ -59,8 +59,8 @@ export interface WebGLResources { renderbuffer: (format: RenderbufferFormat, attachment: RenderbufferAttachment, width: number, height: number) => Renderbuffer shader: (type: ShaderType, source: string) => Shader texture: (kind: TextureKind, format: TextureFormat, type: TextureType, filter: TextureFilter) => Texture, - cubeTexture: (faces: CubeFaces, mipaps: boolean, onload?: () => void) => Texture, - vertexArray: (program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => VertexArray, + cubeTexture: (faces: CubeFaces, mipmaps: boolean, onload?: () => void) => Texture, + vertexArray: (programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => VertexArray, getByteCounts: () => ByteCounts @@ -142,8 +142,8 @@ export function createResources(gl: GLRenderingContext, state: WebGLState, stats cubeTexture: (faces: CubeFaces, mipmaps: boolean, onload?: () => void) => { return wrap('cubeTexture', createCubeTexture(gl, faces, mipmaps, onload)); }, - vertexArray: (program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => { - return wrap('vertexArray', createVertexArray(gl, extensions, program, attributeBuffers, elementsBuffer)); + vertexArray: (programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => { + return wrap('vertexArray', createVertexArray(gl, extensions, programs, attributeBuffers, elementsBuffer)); }, getByteCounts: () => { diff --git a/src/mol-gl/webgl/vertex-array.ts b/src/mol-gl/webgl/vertex-array.ts index f7fe247e7ed4a0be2c1ac4db6b9c54cfc8570deb..966bb4d92ecff088d90cb95ff040d1f92fd67599 100644 --- a/src/mol-gl/webgl/vertex-array.ts +++ b/src/mol-gl/webgl/vertex-array.ts @@ -1,10 +1,10 @@ /** - * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info. + * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ -import { Program } from './program'; +import { Programs } from './program'; import { ElementsBuffer, AttributeBuffers } from './buffer'; import { WebGLExtensions } from './extensions'; import { idFactory } from '../../mol-util/id-factory'; @@ -41,7 +41,7 @@ export interface VertexArray { destroy: () => void } -export function createVertexArray(gl: GLRenderingContext, extensions: WebGLExtensions, program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer): VertexArray { +export function createVertexArray(gl: GLRenderingContext, extensions: WebGLExtensions, programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer): VertexArray { const id = getNextVertexArrayId(); let vertexArray = getVertexArray(extensions); let vertexArrayObject = getVertexArrayObject(extensions); @@ -49,7 +49,7 @@ export function createVertexArray(gl: GLRenderingContext, extensions: WebGLExten function update() { vertexArrayObject.bindVertexArray(vertexArray); if (elementsBuffer) elementsBuffer.bind(); - program.bindAttributes(attributeBuffers); + for (const p of Object.values(programs)) p.bindAttributes(attributeBuffers); vertexArrayObject.bindVertexArray(null); }