|
@@ -1,20 +1,22 @@
|
|
/**
|
|
/**
|
|
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
|
|
|
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
*
|
|
*
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
*/
|
|
*/
|
|
|
|
|
|
-import { createAttributeBuffers, createElementsBuffer, ElementsBuffer, createAttributeBuffer, ArrayKind } from './buffer';
|
|
|
|
-import { createTextures } from './texture';
|
|
|
|
-import { WebGLContext } from './context';
|
|
|
|
|
|
+import { createAttributeBuffers, createElementsBuffer, ElementsBuffer, createAttributeBuffer, AttributeKind } from './buffer';
|
|
|
|
+import { createTextures, Texture } from './texture';
|
|
|
|
+import { WebGLContext, checkError } from './context';
|
|
import { ShaderCode } from '../shader-code';
|
|
import { ShaderCode } from '../shader-code';
|
|
import { Program } from './program';
|
|
import { Program } from './program';
|
|
-import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, Values, splitKeys } from '../renderable/schema';
|
|
|
|
|
|
+import { RenderableSchema, RenderableValues, AttributeSpec, getValueVersions, splitValues, Values } from '../renderable/schema';
|
|
import { idFactory } from 'mol-util/id-factory';
|
|
import { idFactory } from 'mol-util/id-factory';
|
|
import { deleteVertexArray, createVertexArray } from './vertex-array';
|
|
import { deleteVertexArray, createVertexArray } from './vertex-array';
|
|
import { ValueCell } from 'mol-util';
|
|
import { ValueCell } from 'mol-util';
|
|
import { ReferenceItem } from 'mol-util/reference-cache';
|
|
import { ReferenceItem } from 'mol-util/reference-cache';
|
|
import { TextureImage, TextureVolume } from 'mol-gl/renderable/util';
|
|
import { TextureImage, TextureVolume } from 'mol-gl/renderable/util';
|
|
|
|
+import { checkFramebufferStatus } from './framebuffer';
|
|
|
|
+import { isDebugMode } from 'mol-util/debug';
|
|
|
|
|
|
const getNextRenderItemId = idFactory()
|
|
const getNextRenderItemId = idFactory()
|
|
|
|
|
|
@@ -33,22 +35,34 @@ export function getDrawMode(ctx: WebGLContext, drawMode: DrawMode) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-export interface RenderItem {
|
|
|
|
|
|
+export interface RenderItem<T extends string> {
|
|
readonly id: number
|
|
readonly id: number
|
|
- getProgram: (variant: RenderVariant) => Program
|
|
|
|
|
|
+ readonly materialId: number
|
|
|
|
+ getProgram: (variant: T) => Program
|
|
|
|
|
|
- render: (variant: RenderVariant) => void
|
|
|
|
|
|
+ render: (variant: T) => void
|
|
update: () => Readonly<ValueChanges>
|
|
update: () => Readonly<ValueChanges>
|
|
destroy: () => void
|
|
destroy: () => void
|
|
}
|
|
}
|
|
|
|
|
|
-const RenderVariantDefines = {
|
|
|
|
|
|
+//
|
|
|
|
+
|
|
|
|
+const GraphicsRenderVariantDefines = {
|
|
'draw': {},
|
|
'draw': {},
|
|
'pickObject': { dColorType: ValueCell.create('objectPicking') },
|
|
'pickObject': { dColorType: ValueCell.create('objectPicking') },
|
|
'pickInstance': { dColorType: ValueCell.create('instancePicking') },
|
|
'pickInstance': { dColorType: ValueCell.create('instancePicking') },
|
|
'pickGroup': { dColorType: ValueCell.create('groupPicking') }
|
|
'pickGroup': { dColorType: ValueCell.create('groupPicking') }
|
|
}
|
|
}
|
|
-export type RenderVariant = keyof typeof RenderVariantDefines
|
|
|
|
|
|
+export type GraphicsRenderVariant = keyof typeof GraphicsRenderVariantDefines
|
|
|
|
+
|
|
|
|
+const ComputeRenderVariantDefines = {
|
|
|
|
+ 'compute': {},
|
|
|
|
+}
|
|
|
|
+export type ComputeRenderVariant = keyof typeof ComputeRenderVariantDefines
|
|
|
|
+
|
|
|
|
+type RenderVariantDefines = typeof GraphicsRenderVariantDefines | typeof ComputeRenderVariantDefines
|
|
|
|
+
|
|
|
|
+//
|
|
|
|
|
|
type ProgramVariants = { [k: string]: ReferenceItem<Program> }
|
|
type ProgramVariants = { [k: string]: ReferenceItem<Program> }
|
|
type VertexArrayVariants = { [k: string]: WebGLVertexArrayObjectOES | null }
|
|
type VertexArrayVariants = { [k: string]: WebGLVertexArrayObjectOES | null }
|
|
@@ -58,7 +72,6 @@ interface ValueChanges {
|
|
defines: boolean
|
|
defines: boolean
|
|
elements: boolean
|
|
elements: boolean
|
|
textures: boolean
|
|
textures: boolean
|
|
- uniforms: boolean
|
|
|
|
}
|
|
}
|
|
function createValueChanges() {
|
|
function createValueChanges() {
|
|
return {
|
|
return {
|
|
@@ -66,7 +79,6 @@ function createValueChanges() {
|
|
defines: false,
|
|
defines: false,
|
|
elements: false,
|
|
elements: false,
|
|
textures: false,
|
|
textures: false,
|
|
- uniforms: false,
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function resetValueChanges(valueChanges: ValueChanges) {
|
|
function resetValueChanges(valueChanges: ValueChanges) {
|
|
@@ -74,31 +86,44 @@ function resetValueChanges(valueChanges: ValueChanges) {
|
|
valueChanges.defines = false
|
|
valueChanges.defines = false
|
|
valueChanges.elements = false
|
|
valueChanges.elements = false
|
|
valueChanges.textures = false
|
|
valueChanges.textures = false
|
|
- valueChanges.uniforms = false
|
|
|
|
}
|
|
}
|
|
|
|
|
|
-// TODO make `RenderVariantDefines` a parameter for `createRenderItem`
|
|
|
|
|
|
+//
|
|
|
|
+
|
|
|
|
+export type GraphicsRenderItem = RenderItem<keyof typeof GraphicsRenderVariantDefines & string>
|
|
|
|
+export function createGraphicsRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues, materialId: number) {
|
|
|
|
+ return createRenderItem(ctx, drawMode, shaderCode, schema, values, materialId, GraphicsRenderVariantDefines)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+export type ComputeRenderItem = RenderItem<keyof typeof ComputeRenderVariantDefines & string>
|
|
|
|
+export function createComputeRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues, materialId = -1) {
|
|
|
|
+ return createRenderItem(ctx, drawMode, shaderCode, schema, values, materialId, ComputeRenderVariantDefines)
|
|
|
|
+}
|
|
|
|
|
|
/**
|
|
/**
|
|
* Creates a render item
|
|
* Creates a render item
|
|
*
|
|
*
|
|
* - assumes that `values.drawCount` and `values.instanceCount` exist
|
|
* - assumes that `values.drawCount` and `values.instanceCount` exist
|
|
*/
|
|
*/
|
|
-export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues): RenderItem {
|
|
|
|
|
|
+export function createRenderItem<T extends RenderVariantDefines, S extends keyof T & string>(ctx: WebGLContext, drawMode: DrawMode, shaderCode: ShaderCode, schema: RenderableSchema, values: RenderableValues, materialId: number, renderVariantDefines: T): RenderItem<S> {
|
|
const id = getNextRenderItemId()
|
|
const id = getNextRenderItemId()
|
|
- const { programCache } = ctx
|
|
|
|
|
|
+ const { stats, state, programCache } = ctx
|
|
const { instancedArrays, vertexArrayObject } = ctx.extensions
|
|
const { instancedArrays, vertexArrayObject } = ctx.extensions
|
|
|
|
|
|
- const { attributeValues, defineValues, textureValues, uniformValues } = splitValues(schema, values)
|
|
|
|
- const { attributeKeys, defineKeys, textureKeys } = splitKeys(schema)
|
|
|
|
|
|
+ const { attributeValues, defineValues, textureValues, uniformValues, materialUniformValues } = splitValues(schema, values)
|
|
|
|
+
|
|
|
|
+ const uniformValueEntries = Object.entries(uniformValues)
|
|
|
|
+ const materialUniformValueEntries = Object.entries(materialUniformValues)
|
|
|
|
+ const defineValueEntries = Object.entries(defineValues)
|
|
|
|
+
|
|
const versions = getValueVersions(values)
|
|
const versions = getValueVersions(values)
|
|
|
|
|
|
const glDrawMode = getDrawMode(ctx, drawMode)
|
|
const glDrawMode = getDrawMode(ctx, drawMode)
|
|
|
|
|
|
const programs: ProgramVariants = {}
|
|
const programs: ProgramVariants = {}
|
|
- Object.keys(RenderVariantDefines).forEach(k => {
|
|
|
|
- const variantDefineValues: Values<RenderableSchema> = (RenderVariantDefines as any)[k]
|
|
|
|
- programs[k] = programCache.get(ctx, {
|
|
|
|
|
|
+ Object.keys(renderVariantDefines).forEach(k => {
|
|
|
|
+ const variantDefineValues: Values<RenderableSchema> = (renderVariantDefines as any)[k]
|
|
|
|
+ programs[k] = programCache.get({
|
|
defineValues: { ...defineValues, ...variantDefineValues },
|
|
defineValues: { ...defineValues, ...variantDefineValues },
|
|
shaderCode,
|
|
shaderCode,
|
|
schema
|
|
schema
|
|
@@ -115,51 +140,80 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
}
|
|
}
|
|
|
|
|
|
const vertexArrays: VertexArrayVariants = {}
|
|
const vertexArrays: VertexArrayVariants = {}
|
|
- Object.keys(RenderVariantDefines).forEach(k => {
|
|
|
|
|
|
+ Object.keys(renderVariantDefines).forEach(k => {
|
|
vertexArrays[k] = createVertexArray(ctx, programs[k].value, attributeBuffers, elementsBuffer)
|
|
vertexArrays[k] = createVertexArray(ctx, programs[k].value, attributeBuffers, elementsBuffer)
|
|
})
|
|
})
|
|
|
|
|
|
let drawCount = values.drawCount.ref.value
|
|
let drawCount = values.drawCount.ref.value
|
|
let instanceCount = values.instanceCount.ref.value
|
|
let instanceCount = values.instanceCount.ref.value
|
|
|
|
|
|
- ctx.drawCount += drawCount
|
|
|
|
- ctx.instanceCount += instanceCount
|
|
|
|
- ctx.instancedDrawCount += instanceCount * drawCount
|
|
|
|
|
|
+ stats.drawCount += drawCount
|
|
|
|
+ stats.instanceCount += instanceCount
|
|
|
|
+ stats.instancedDrawCount += instanceCount * drawCount
|
|
|
|
|
|
const valueChanges = createValueChanges()
|
|
const valueChanges = createValueChanges()
|
|
|
|
|
|
let destroyed = false
|
|
let destroyed = false
|
|
|
|
+ let currentProgramId = -1
|
|
|
|
|
|
return {
|
|
return {
|
|
id,
|
|
id,
|
|
- getProgram: (variant: RenderVariant) => programs[variant].value,
|
|
|
|
|
|
+ materialId,
|
|
|
|
+ getProgram: (variant: S) => programs[variant].value,
|
|
|
|
|
|
- render: (variant: RenderVariant) => {
|
|
|
|
|
|
+ render: (variant: S) => {
|
|
if (drawCount === 0 || instanceCount === 0) return
|
|
if (drawCount === 0 || instanceCount === 0) return
|
|
const program = programs[variant].value
|
|
const program = programs[variant].value
|
|
- const vertexArray = vertexArrays[variant]
|
|
|
|
- program.setUniforms(uniformValues)
|
|
|
|
- if (vertexArrayObject && vertexArray) {
|
|
|
|
- vertexArrayObject.bindVertexArray(vertexArray)
|
|
|
|
- // need to bind elements buffer explicitly since it is not always recorded in the VAO
|
|
|
|
- if (elementsBuffer) elementsBuffer.bind()
|
|
|
|
|
|
+ if (program.id === currentProgramId && state.currentRenderItemId === id) {
|
|
|
|
+ program.setUniforms(uniformValueEntries)
|
|
|
|
+ program.bindTextures(textures)
|
|
} else {
|
|
} else {
|
|
- if (elementsBuffer) elementsBuffer.bind()
|
|
|
|
- program.bindAttributes(attributeBuffers)
|
|
|
|
|
|
+ const vertexArray = vertexArrays[variant]
|
|
|
|
+ if (program.id !== state.currentProgramId || program.id !== currentProgramId ||
|
|
|
|
+ materialId === -1 || materialId !== state.currentMaterialId
|
|
|
|
+ ) {
|
|
|
|
+ // console.log('program.id changed or materialId changed/-1', materialId)
|
|
|
|
+ if (program.id !== state.currentProgramId) program.use()
|
|
|
|
+ program.setUniforms(materialUniformValueEntries)
|
|
|
|
+ state.currentMaterialId = materialId
|
|
|
|
+ currentProgramId = program.id
|
|
|
|
+ }
|
|
|
|
+ program.setUniforms(uniformValueEntries)
|
|
|
|
+ program.bindTextures(textures)
|
|
|
|
+ if (vertexArrayObject && vertexArray) {
|
|
|
|
+ vertexArrayObject.bindVertexArray(vertexArray)
|
|
|
|
+ // need to bind elements buffer explicitly since it is not always recorded in the VAO
|
|
|
|
+ if (elementsBuffer) elementsBuffer.bind()
|
|
|
|
+ } else {
|
|
|
|
+ if (elementsBuffer) elementsBuffer.bind()
|
|
|
|
+ program.bindAttributes(attributeBuffers)
|
|
|
|
+ }
|
|
|
|
+ state.currentRenderItemId = id
|
|
|
|
+ }
|
|
|
|
+ if (isDebugMode) {
|
|
|
|
+ checkFramebufferStatus(ctx.gl)
|
|
}
|
|
}
|
|
- program.bindTextures(textures)
|
|
|
|
if (elementsBuffer) {
|
|
if (elementsBuffer) {
|
|
instancedArrays.drawElementsInstanced(glDrawMode, drawCount, elementsBuffer._dataType, 0, instanceCount);
|
|
instancedArrays.drawElementsInstanced(glDrawMode, drawCount, elementsBuffer._dataType, 0, instanceCount);
|
|
} else {
|
|
} else {
|
|
instancedArrays.drawArraysInstanced(glDrawMode, 0, drawCount, instanceCount)
|
|
instancedArrays.drawArraysInstanced(glDrawMode, 0, drawCount, instanceCount)
|
|
}
|
|
}
|
|
|
|
+ if (isDebugMode) {
|
|
|
|
+ try {
|
|
|
|
+ checkError(ctx.gl)
|
|
|
|
+ } catch (e) {
|
|
|
|
+ // console.log('shaderCode', shaderCode)
|
|
|
|
+ // console.log('schema', schema)
|
|
|
|
+ // console.log('attributeBuffers', attributeBuffers)
|
|
|
|
+ throw new Error(`Error rendering item id ${id}: '${e}'`)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
},
|
|
},
|
|
update: () => {
|
|
update: () => {
|
|
resetValueChanges(valueChanges)
|
|
resetValueChanges(valueChanges)
|
|
|
|
|
|
- for (let i = 0, il = defineKeys.length; i < il; ++i) {
|
|
|
|
- const k = defineKeys[i]
|
|
|
|
- const value = defineValues[k]
|
|
|
|
|
|
+ for (let i = 0, il = defineValueEntries.length; i < il; ++i) {
|
|
|
|
+ const [k, value] = defineValueEntries[i]
|
|
if (value.ref.version !== versions[k]) {
|
|
if (value.ref.version !== versions[k]) {
|
|
// console.log('define version changed', k)
|
|
// console.log('define version changed', k)
|
|
valueChanges.defines = true
|
|
valueChanges.defines = true
|
|
@@ -169,10 +223,10 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
|
|
|
|
if (valueChanges.defines) {
|
|
if (valueChanges.defines) {
|
|
// console.log('some defines changed, need to rebuild programs')
|
|
// console.log('some defines changed, need to rebuild programs')
|
|
- Object.keys(RenderVariantDefines).forEach(k => {
|
|
|
|
- const variantDefineValues: Values<RenderableSchema> = (RenderVariantDefines as any)[k]
|
|
|
|
|
|
+ Object.keys(renderVariantDefines).forEach(k => {
|
|
|
|
+ const variantDefineValues: Values<RenderableSchema> = (renderVariantDefines as any)[k]
|
|
programs[k].free()
|
|
programs[k].free()
|
|
- programs[k] = programCache.get(ctx, {
|
|
|
|
|
|
+ programs[k] = programCache.get({
|
|
defineValues: { ...defineValues, ...variantDefineValues },
|
|
defineValues: { ...defineValues, ...variantDefineValues },
|
|
shaderCode,
|
|
shaderCode,
|
|
schema
|
|
schema
|
|
@@ -182,32 +236,31 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
|
|
|
|
if (values.drawCount.ref.version !== versions.drawCount) {
|
|
if (values.drawCount.ref.version !== versions.drawCount) {
|
|
// console.log('drawCount version changed')
|
|
// console.log('drawCount version changed')
|
|
- ctx.drawCount += values.drawCount.ref.value - drawCount
|
|
|
|
- ctx.instancedDrawCount += instanceCount * values.drawCount.ref.value - instanceCount * drawCount
|
|
|
|
|
|
+ stats.drawCount += values.drawCount.ref.value - drawCount
|
|
|
|
+ stats.instancedDrawCount += instanceCount * values.drawCount.ref.value - instanceCount * drawCount
|
|
drawCount = values.drawCount.ref.value
|
|
drawCount = values.drawCount.ref.value
|
|
versions.drawCount = values.drawCount.ref.version
|
|
versions.drawCount = values.drawCount.ref.version
|
|
}
|
|
}
|
|
if (values.instanceCount.ref.version !== versions.instanceCount) {
|
|
if (values.instanceCount.ref.version !== versions.instanceCount) {
|
|
// console.log('instanceCount version changed')
|
|
// console.log('instanceCount version changed')
|
|
- ctx.instanceCount += values.instanceCount.ref.value - instanceCount
|
|
|
|
- ctx.instancedDrawCount += values.instanceCount.ref.value * drawCount - instanceCount * drawCount
|
|
|
|
|
|
+ stats.instanceCount += values.instanceCount.ref.value - instanceCount
|
|
|
|
+ stats.instancedDrawCount += values.instanceCount.ref.value * drawCount - instanceCount * drawCount
|
|
instanceCount = values.instanceCount.ref.value
|
|
instanceCount = values.instanceCount.ref.value
|
|
versions.instanceCount = values.instanceCount.ref.version
|
|
versions.instanceCount = values.instanceCount.ref.version
|
|
}
|
|
}
|
|
|
|
|
|
- for (let i = 0, il = attributeKeys.length; i < il; ++i) {
|
|
|
|
- const k = attributeKeys[i]
|
|
|
|
|
|
+ for (let i = 0, il = attributeBuffers.length; i < il; ++i) {
|
|
|
|
+ const [k, buffer] = attributeBuffers[i]
|
|
const value = attributeValues[k]
|
|
const value = attributeValues[k]
|
|
if (value.ref.version !== versions[k]) {
|
|
if (value.ref.version !== versions[k]) {
|
|
- const buffer = attributeBuffers[k]
|
|
|
|
if (buffer.length >= value.ref.value.length) {
|
|
if (buffer.length >= value.ref.value.length) {
|
|
// console.log('attribute array large enough to update', k, value.ref.id, value.ref.version)
|
|
// console.log('attribute array large enough to update', k, value.ref.id, value.ref.version)
|
|
buffer.updateData(value.ref.value)
|
|
buffer.updateData(value.ref.value)
|
|
} else {
|
|
} else {
|
|
// console.log('attribute array to small, need to create new attribute', k, value.ref.id, value.ref.version)
|
|
// console.log('attribute array to small, need to create new attribute', k, value.ref.id, value.ref.version)
|
|
buffer.destroy()
|
|
buffer.destroy()
|
|
- const { itemSize, divisor } = schema[k] as AttributeSpec<ArrayKind>
|
|
|
|
- attributeBuffers[k] = createAttributeBuffer(ctx, value.ref.value, itemSize, divisor)
|
|
|
|
|
|
+ const { itemSize, divisor } = schema[k] as AttributeSpec<AttributeKind>
|
|
|
|
+ attributeBuffers[i][1] = createAttributeBuffer(ctx, value.ref.value, itemSize, divisor)
|
|
valueChanges.attributes = true
|
|
valueChanges.attributes = true
|
|
}
|
|
}
|
|
versions[k] = value.ref.version
|
|
versions[k] = value.ref.version
|
|
@@ -231,7 +284,7 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
// console.log('program/defines or buffers changed, update vaos')
|
|
// console.log('program/defines or buffers changed, update vaos')
|
|
const { vertexArrayObject } = ctx.extensions
|
|
const { vertexArrayObject } = ctx.extensions
|
|
if (vertexArrayObject) {
|
|
if (vertexArrayObject) {
|
|
- Object.keys(RenderVariantDefines).forEach(k => {
|
|
|
|
|
|
+ Object.keys(renderVariantDefines).forEach(k => {
|
|
vertexArrayObject.bindVertexArray(vertexArrays[k])
|
|
vertexArrayObject.bindVertexArray(vertexArrays[k])
|
|
if (elementsBuffer && (valueChanges.defines || valueChanges.elements)) {
|
|
if (elementsBuffer && (valueChanges.defines || valueChanges.elements)) {
|
|
elementsBuffer.bind()
|
|
elementsBuffer.bind()
|
|
@@ -244,16 +297,18 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- for (let i = 0, il = textureKeys.length; i < il; ++i) {
|
|
|
|
- const k = textureKeys[i]
|
|
|
|
|
|
+ for (let i = 0, il = textures.length; i < il; ++i) {
|
|
|
|
+ const [k, texture] = textures[i]
|
|
const value = textureValues[k]
|
|
const value = textureValues[k]
|
|
if (value.ref.version !== versions[k]) {
|
|
if (value.ref.version !== versions[k]) {
|
|
// update of textures with kind 'texture' is done externally
|
|
// update of textures with kind 'texture' is done externally
|
|
if (schema[k].kind !== 'texture') {
|
|
if (schema[k].kind !== 'texture') {
|
|
// console.log('texture version changed, uploading image', k)
|
|
// console.log('texture version changed, uploading image', k)
|
|
- textures[k].load(value.ref.value as TextureImage<any> | TextureVolume<any>)
|
|
|
|
|
|
+ texture.load(value.ref.value as TextureImage<any> | TextureVolume<any>)
|
|
versions[k] = value.ref.version
|
|
versions[k] = value.ref.version
|
|
valueChanges.textures = true
|
|
valueChanges.textures = true
|
|
|
|
+ } else {
|
|
|
|
+ textures[i][1] = value.ref.value as Texture
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -262,17 +317,17 @@ export function createRenderItem(ctx: WebGLContext, drawMode: DrawMode, shaderCo
|
|
},
|
|
},
|
|
destroy: () => {
|
|
destroy: () => {
|
|
if (!destroyed) {
|
|
if (!destroyed) {
|
|
- Object.keys(RenderVariantDefines).forEach(k => {
|
|
|
|
|
|
+ Object.keys(renderVariantDefines).forEach(k => {
|
|
programs[k].free()
|
|
programs[k].free()
|
|
deleteVertexArray(ctx, vertexArrays[k])
|
|
deleteVertexArray(ctx, vertexArrays[k])
|
|
})
|
|
})
|
|
- Object.keys(textures).forEach(k => {
|
|
|
|
|
|
+ textures.forEach(([k, texture]) => {
|
|
// lifetime of textures with kind 'texture' is defined externally
|
|
// lifetime of textures with kind 'texture' is defined externally
|
|
if (schema[k].kind !== 'texture') {
|
|
if (schema[k].kind !== 'texture') {
|
|
- textures[k].destroy()
|
|
|
|
|
|
+ texture.destroy()
|
|
}
|
|
}
|
|
})
|
|
})
|
|
- Object.keys(attributeBuffers).forEach(k => attributeBuffers[k].destroy())
|
|
|
|
|
|
+ attributeBuffers.forEach(([_, buffer]) => buffer.destroy())
|
|
if (elementsBuffer) elementsBuffer.destroy()
|
|
if (elementsBuffer) elementsBuffer.destroy()
|
|
destroyed = true
|
|
destroyed = true
|
|
}
|
|
}
|