diff --git a/src/mol-canvas3d/passes/draw.ts b/src/mol-canvas3d/passes/draw.ts index 3c72b628ba228a6d54d79da031bf33c30c81e571..65ebcee450ad0b4036dcdda273e344f0a282b029 100644 --- a/src/mol-canvas3d/passes/draw.ts +++ b/src/mol-canvas3d/passes/draw.ts @@ -62,8 +62,6 @@ export class DrawPass { private depthTextureVolumes: Texture private depthMerge: DepthMergeRenderable - private readonly dummyDepthTexture: Texture - constructor(private webgl: WebGLContext, width: number, height: number) { const { extensions, resources } = webgl; @@ -86,9 +84,6 @@ export class DrawPass { this.depthTextureVolumes.define(width, height); } this.depthMerge = getDepthMergeRenderable(webgl, this.depthTexturePrimitives, this.depthTextureVolumes, this.packedDepth); - - this.dummyDepthTexture = resources.texture('image-depth', 'depth', 'ushort', 'nearest'); - this.dummyDepthTexture.define(2, 2); } setSize(width: number, height: number) { @@ -126,11 +121,6 @@ export class DrawPass { // console.log('toDrawingBuffer', toDrawingBuffer); - for (let i = 0; i < this.webgl.maxTextureImageUnits; i++) { - this.webgl.gl.activeTexture(this.webgl.gl.TEXTURE0 + i); - this.webgl.gl.bindTexture(this.webgl.gl.TEXTURE_2D, null); - } - let renderTarget; if (toDrawingBuffer) { renderTarget = null; @@ -149,7 +139,7 @@ export class DrawPass { } // render opaque color - renderer.render(renderTarget, scene.primitives, camera, 'color', true, transparentBackground, 1, this.dummyDepthTexture, false); + renderer.render(renderTarget, scene.primitives, camera, 'color', true, transparentBackground, 1, null, false); if (helper.debug.isEnabled) { helper.debug.syncVisibility(); diff --git a/src/mol-gl/renderer.ts b/src/mol-gl/renderer.ts index 1fc80a22abe8f9b03487f2fe51f42377130542c9..524175141d6c1cd9acc5bacf6aca04f245ef610b 100644 --- a/src/mol-gl/renderer.ts +++ b/src/mol-gl/renderer.ts @@ -19,13 +19,14 @@ import { Clipping } from '../mol-theme/clipping'; import { stringToWords } from '../mol-util/string'; import { Transparency } from '../mol-theme/transparency'; import { degToRad } from '../mol-math/misc'; -import { Texture, Textures } from './webgl/texture'; +import { createNullTexture, Texture, Textures } from './webgl/texture'; import { RenderTarget } from './webgl/render-target'; import { QuadSchema, QuadValues } from './compute/util'; import quad_vert from '../mol-gl/shader/quad.vert'; import evaluate_wboit_frag from '../mol-gl/shader/evaluate-wboit.frag'; import { ShaderCode } from './shader-code'; +import { arrayMapUpsert } from '../mol-util/array'; export interface RendererStats { programCount: number @@ -175,7 +176,10 @@ namespace Renderer { const drawingBufferSize = Vec2.create(gl.drawingBufferWidth, gl.drawingBufferHeight); const bgColor = Color.toVec3Normalized(Vec3(), p.backgroundColor); - const sharedTexturesList: Textures = []; + const nullDepthTexture = createNullTexture(gl, 'image-depth'); + const sharedTexturesList: Textures = [ + ['tDepth', nullDepthTexture] + ]; const enableWboit = textureFloat && colorBufferFloat && depthTexture && drawBuffers; @@ -266,7 +270,7 @@ namespace Renderer { let globalUniformsNeedUpdate = true; - const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant, sharedTexturesList?: Textures) => { + const renderObject = (r: Renderable<RenderableValues & BaseValues>, variant: GraphicsRenderVariant) => { if (!r.state.visible || (!r.state.pickable && variant[0] === 'p')) { return; } @@ -348,10 +352,7 @@ namespace Renderer { }; const render = (renderTarget: RenderTarget | null, group: Scene.Group, camera: ICamera, variant: GraphicsRenderVariant, clear: boolean, transparentBackground: boolean, drawingBufferScale: number, depthTexture: Texture | null, renderTransparent: boolean) => { - let localSharedTexturesList = sharedTexturesList; - if (depthTexture) { - localSharedTexturesList = [...localSharedTexturesList, ['tDepth', depthTexture]]; - } + arrayMapUpsert(sharedTexturesList, 'tDepth', depthTexture || nullDepthTexture); ValueCell.update(globalUniforms.uModel, group.view); ValueCell.update(globalUniforms.uView, camera.view); @@ -425,7 +426,7 @@ namespace Renderer { for (let i = 0, il = renderables.length; i < il; ++i) { const r = renderables[i]; if (r.values.uAlpha.ref.value === 1 && r.values.transparencyAverage.ref.value !== 1 && r.values?.dRenderMode?.ref.value !== 'volume') { - renderObject(r, variant, localSharedTexturesList); + renderObject(r, variant); } } } else { @@ -445,7 +446,7 @@ namespace Renderer { for (let i = 0, il = renderables.length; i < il; ++i) { const r = renderables[i]; if (r.values.uAlpha.ref.value < 1 || r.values.transparencyAverage.ref.value !== 0) { - renderObject(r, variant, localSharedTexturesList); + renderObject(r, variant); } } @@ -470,7 +471,7 @@ namespace Renderer { for (let i = 0, il = renderables.length; i < il; ++i) { const r = renderables[i]; if (r.state.opaque) { - renderObject(r, variant, localSharedTexturesList); + renderObject(r, variant); } } @@ -479,13 +480,13 @@ namespace Renderer { for (let i = 0, il = renderables.length; i < il; ++i) { const r = renderables[i]; if (!r.state.opaque && r.state.writeDepth) { - renderObject(r, variant, localSharedTexturesList); + renderObject(r, variant); } } for (let i = 0, il = renderables.length; i < il; ++i) { const r = renderables[i]; if (!r.state.opaque && !r.state.writeDepth) { - renderObject(r, variant, localSharedTexturesList); + renderObject(r, variant); } } } @@ -493,7 +494,7 @@ namespace Renderer { if (!renderTransparent) { for (let i = 0, il = renderables.length; i < il; ++i) { if (!renderables[i].state.colorOnly) { - renderObject(renderables[i], variant, localSharedTexturesList); + renderObject(renderables[i], variant); } } } diff --git a/src/mol-gl/webgl/program.ts b/src/mol-gl/webgl/program.ts index 0fdfc6c2b83e4a3c81785412c0ed0ffc67c8de2e..fcf40dca8c20951fa830531758181285c44c0f57 100644 --- a/src/mol-gl/webgl/program.ts +++ b/src/mol-gl/webgl/program.ts @@ -205,8 +205,6 @@ export function createProgram(gl: GLRenderingContext, state: WebGLState, extensi const [k, texture] = textures[i]; const l = locations[k]; if (l !== null && l !== undefined) { - // TODO if the order and count of textures in a material can be made invariant - // bind needs to be called only when the material changes texture.bind((i + startingTargetUnit) as TextureId); uniformSetters[k](gl, l, (i + startingTargetUnit) as TextureId); } diff --git a/src/mol-gl/webgl/texture.ts b/src/mol-gl/webgl/texture.ts index 3ccd3093cec7727c13e42966478edd75f2ba64a7..11eb2404657c148591954952e9145eaafc8824e0 100644 --- a/src/mol-gl/webgl/texture.ts +++ b/src/mol-gl/webgl/texture.ts @@ -312,4 +312,37 @@ export function createTextures(ctx: WebGLContext, schema: RenderableSchema, valu } }); return textures; +} + +// + +export function createNullTexture(gl: GLRenderingContext, kind: TextureKind): Texture { + const target = getTarget(gl, kind); + return { + id: getNextTextureId(), + target, + format: 0, + internalFormat: 0, + type: 0, + + getWidth: () => 0, + getHeight: () => 0, + getDepth: () => 0, + + define: () => {}, + load: () => {}, + bind: (id: TextureId) => { + gl.activeTexture(gl.TEXTURE0 + id); + gl.bindTexture(target, null); + }, + unbind: (id: TextureId) => { + gl.activeTexture(gl.TEXTURE0 + id); + gl.bindTexture(target, null); + }, + attachFramebuffer: () => {}, + detachFramebuffer: () => {}, + + reset: () => {}, + destroy: () => {}, + }; } \ No newline at end of file diff --git a/src/mol-util/array.ts b/src/mol-util/array.ts index 16b1ded0ab0905bab17f89e2b2c6b297c557cdc3..7a3931e568551c19c646423a467b7fe1dc7ca5b6 100644 --- a/src/mol-util/array.ts +++ b/src/mol-util/array.ts @@ -122,4 +122,14 @@ export function arrayIsIdentity(xs: ArrayLike<number>) { if (xs[i] !== i) return false; } return true; -} \ No newline at end of file +} + +export function arrayMapUpsert<T>(xs: [string, T][], key: string, value: T) { + for (let i = 0, il = xs.length; i < il; ++i) { + if (xs[i][0] === key) { + xs[i][1] = value; + return; + } + } + xs.push([key, value]); +}