Преглед на файлове

Merge pull request #779 from MadCatX/restore-vertex-array-per-program

Fix broken rendering caused by changes in 291d7abb7804d58e2ed4a35601715d50e6d4b8b8
Alexander Rose преди 2 години
родител
ревизия
2994caf411
променени са 5 файла, в които са добавени 22 реда и са изтрити 13 реда
  1. 1 0
      CHANGELOG.md
  2. 1 1
      src/mol-gl/_spec/renderer.spec.ts
  3. 13 5
      src/mol-gl/webgl/render-item.ts
  4. 4 4
      src/mol-gl/webgl/resources.ts
  5. 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` doubling workaround
 - Add `ModifiersKeys.areNone` helper function
+- Fix rendering issues caused by VAO reuse
 - Add "Zoom All", "Orient Axes", "Reset Axes" buttons to the "Reset Camera" button
 - Improve trackball move-state handling when key bindings use modifiers
 

+ 1 - 1
src/mol-gl/_spec/renderer.spec.ts

@@ -53,7 +53,7 @@ describe('renderer', () => {
         scene.commit();
         expect(ctx.stats.resourceCounts.attribute).toBe(ctx.isWebGL2 ? 4 : 5);
         expect(ctx.stats.resourceCounts.texture).toBe(9);
-        expect(ctx.stats.resourceCounts.vertexArray).toBe(ctx.extensions.vertexArrayObject ? 1 : 0);
+        expect(ctx.stats.resourceCounts.vertexArray).toBe(ctx.extensions.vertexArrayObject ? 6 : 0);
         expect(ctx.stats.resourceCounts.program).toBe(6);
         expect(ctx.stats.resourceCounts.shader).toBe(12);
 

+ 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);
     }