Преглед изворни кода

Do not reuse vertex arrays among programs

Michal Malý пре 2 година
родитељ
комит
1985eb59dd
4 измењених фајлова са 21 додато и 12 уклоњено
  1. 1 0
      CHANGELOG.md
  2. 13 5
      src/mol-gl/webgl/render-item.ts
  3. 4 4
      src/mol-gl/webgl/resources.ts
  4. 3 3
      src/mol-gl/webgl/vertex-array.ts

+ 1 - 0
CHANGELOG.md

@@ -9,6 +9,7 @@ Note that since we don't clearly distinguish between a public and private interf
 - Avoid `renderMarkingDepth` for fully transparent renderables
 - Remove `camera.far` doubeling workaround
 - Add `ModifiersKeys.areNone` helper function
+- Fix broken rendering caused by vertex array reuse
 
 ## [v3.33.0] - 2023-04-02
 

+ 13 - 5
src/mol-gl/webgl/render-item.ts

@@ -144,7 +144,10 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode:
         elementsBuffer = resources.elements(elements.ref.value);
     }
 
-    let vertexArray: VertexArray | null = vertexArrayObject ? resources.vertexArray(programs, attributeBuffers, elementsBuffer) : null;
+    const vertexArrays: Record<string, VertexArray | null> = {};
+    for (const k of renderVariants) {
+        vertexArrays[k] = vertexArrayObject ? resources.vertexArray(programs[k], attributeBuffers, elementsBuffer) : null;
+    }
 
     let drawCount: number = values.drawCount.ref.value;
     let instanceCount: number = values.instanceCount.ref.value;
@@ -170,6 +173,7 @@ 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
                 ) {
@@ -291,9 +295,12 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode:
             }
 
             if (valueChanges.attributes || valueChanges.defines || valueChanges.elements) {
-                // console.log('program/defines or buffers changed, update vao');
-                if (vertexArray) vertexArray.destroy();
-                vertexArray = vertexArrayObject ? resources.vertexArray(programs, attributeBuffers, elementsBuffer) : null;
+                // 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;
+                }
             }
 
             for (let i = 0, il = textures.length; i < il; ++i) {
@@ -341,8 +348,9 @@ export function createRenderItem<T extends string>(ctx: WebGLContext, drawMode:
             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();

+ 4 - 4
src/mol-gl/webgl/resources.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { ProgramProps, createProgram, Program, Programs } from './program';
+import { ProgramProps, createProgram, Program } from './program';
 import { ShaderType, createShader, Shader, ShaderProps } from './shader';
 import { GLRenderingContext } from './compat';
 import { Framebuffer, createFramebuffer } from './framebuffer';
@@ -60,7 +60,7 @@ export interface WebGLResources {
     shader: (type: ShaderType, source: string) => Shader
     texture: (kind: TextureKind, format: TextureFormat, type: TextureType, filter: TextureFilter) => Texture,
     cubeTexture: (faces: CubeFaces, mipmaps: boolean, onload?: () => void) => Texture,
-    vertexArray: (programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => VertexArray,
+    vertexArray: (program: Program, 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: (programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => {
-            return wrap('vertexArray', createVertexArray(gl, extensions, programs, attributeBuffers, elementsBuffer));
+        vertexArray: (program: Program, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer) => {
+            return wrap('vertexArray', createVertexArray(gl, extensions, program, attributeBuffers, elementsBuffer));
         },
 
         getByteCounts: () => {

+ 3 - 3
src/mol-gl/webgl/vertex-array.ts

@@ -4,7 +4,7 @@
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  */
 
-import { Programs } from './program';
+import { Program } 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, programs: Programs, attributeBuffers: AttributeBuffers, elementsBuffer?: ElementsBuffer): VertexArray {
+export function createVertexArray(gl: GLRenderingContext, extensions: WebGLExtensions, program: Program, 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();
-        for (const p of Object.values(programs)) p.bindAttributes(attributeBuffers);
+        program.bindAttributes(attributeBuffers);
         vertexArrayObject.bindVertexArray(null);
     }