Alexander Rose 6 years ago
parent
commit
784ecf541f

+ 2 - 1
src/apps/canvas/structure-view.ts

@@ -211,7 +211,8 @@ export async function StructureView(app: App, viewer: Viewer, models: ReadonlyAr
             console.log('createStructureRepr')
             for (const k in structureRepresentations) {
                 if (active[k]) {
-                    await app.runTask(structureRepresentations[k].createOrUpdate({}, structure).run(
+                    const p = { webgl: viewer.webgl }
+                    await app.runTask(structureRepresentations[k].createOrUpdate(p, structure).run(
                         progress => console.log(Progress.format(progress))
                     ), 'Create/update representation')
                     viewer.add(structureRepresentations[k])

+ 2 - 1
src/apps/canvas/volume-view.ts

@@ -55,7 +55,8 @@ export async function VolumeView(app: App, viewer: Viewer, volume: VolumeData, p
     async function createVolumeRepr() {
         for (const k in volumeRepresentations) {
             if (active[k]) {
-                await app.runTask(volumeRepresentations[k].createOrUpdate({}, volume).run(
+                const p = { webgl: viewer.webgl }
+                await app.runTask(volumeRepresentations[k].createOrUpdate(p, volume).run(
                     progress => console.log(Progress.format(progress))
                 ), 'Create/update representation')
                 viewer.add(volumeRepresentations[k])

+ 4 - 1
src/mol-geo/geometry/geometry.ts

@@ -15,9 +15,11 @@ import { LocationIterator } from '../util/location-iterator';
 import { ColorType } from './color-data';
 import { SizeType } from './size-data';
 import { Lines } from './lines/lines';
-import { paramDefaultValues, RangeParam, BooleanParam, SelectParam, ColorParam, StructureParam } from 'mol-view/parameter'
+import { paramDefaultValues, RangeParam, BooleanParam, SelectParam, ColorParam, StructureParam, ValueParam } from 'mol-view/parameter'
 import { Structure } from 'mol-model/structure';
 import { DirectVolume2d, DirectVolume3d } from './direct-volume/direct-volume';
+import { GLRenderingContext } from 'mol-gl/webgl/compat';
+import { Context } from 'mol-gl/webgl/context';
 
 //
 
@@ -70,6 +72,7 @@ export namespace Geometry {
         colorTheme: SelectParam<ColorThemeName>('Color Theme', '', 'uniform', ColorThemeOptions),
         colorValue: ColorParam('Color Value', '', Color(0xCCCCCC)),
         structure: StructureParam('Structure', '', Structure.Empty),
+        webgl: ValueParam('WebGL Context', '', undefined as Context | undefined),
     }
     export const DefaultProps = paramDefaultValues(Params)
     export type Props = typeof DefaultProps

+ 8 - 0
src/mol-geo/representation/structure/units-visual.ts

@@ -541,6 +541,9 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde
     let currentConformationId: UUID
 
     async function create(ctx: RuntimeContext, group: Unit.SymmetryGroup, props: Partial<P> = {}) {
+        const { webgl } = props
+        if (webgl === undefined) throw new Error('UnitsDirectVolumeVisual requires `webgl` in props')
+
         currentProps = Object.assign({}, defaultProps, props, { structure: currentStructure })
         currentGroup = group
 
@@ -550,12 +553,17 @@ export function UnitsDirectVolumeVisual<P extends UnitsDirectVolumeProps>(builde
             ? await createGeometry(ctx, unit, currentStructure, currentProps, directVolume)
             : DirectVolume2d.createEmpty(directVolume)
 
+        console.log('directVolume', directVolume)
+
         // TODO create empty location iterator when not in unitKinds
         locationIt = createLocationIterator(group)
         renderObject = await createUnitsDirectVolumeRenderObject(ctx, group, directVolume, locationIt, currentProps)
     }
 
     async function update(ctx: RuntimeContext, props: Partial<P> = {}) {
+        const { webgl } = props
+        if (webgl === undefined) throw new Error('UnitsDirectVolumeVisual requires `webgl` in props')
+
         if (!renderObject) return
 
         const newProps = Object.assign({}, currentProps, props, { structure: currentStructure })

+ 2 - 2
src/mol-geo/representation/structure/visual/gaussian-density-volume.ts

@@ -17,8 +17,8 @@ import { Vec3, Vec2 } from 'mol-math/linear-algebra';
 
 async function createGaussianDensityVolume(ctx: RuntimeContext, unit: Unit, structure: Structure, props: GaussianDensityProps, directVolume?: DirectVolume2d): Promise<DirectVolume2d> {
     const p = { ...props, useGpu: true, ignoreCache: true }
-    const { transform, renderTarget, bbox, gridDimension } = await unit.computeGaussianDensity(p, ctx)
-    if (!renderTarget || !bbox || !gridDimension) throw new Error('missing renderTarget and/or boundingBox and/or gridDimension')
+    const { transform, texture, bbox, gridDimension } = await unit.computeGaussianDensity(p, ctx)
+    if (!texture || !bbox || !gridDimension) throw new Error('missing renderTarget and/or boundingBox and/or gridDimension')
 
     if (directVolume) {
         ValueCell.update(directVolume.gridDimension, gridDimension)

+ 24 - 23
src/mol-geo/representation/volume/direct-volume.ts

@@ -17,13 +17,13 @@ import { ValueCell } from 'mol-util';
 import { DirectVolume2d, DirectVolume3d } from '../../geometry/direct-volume/direct-volume';
 import { Vec2, Vec3 } from 'mol-math/linear-algebra';
 import { Box3D } from 'mol-math/geometry';
-import { createImageData } from 'mol-gl/webgl/context';
+import { createImageData, Context } from 'mol-gl/webgl/context';
 import { debugTexture } from 'mol-gl/util';
 import { DirectVolume3dValues, DirectVolume2dValues } from 'mol-gl/renderable/direct-volume';
 
 // 2d volume texture
 
-function getVolumeTexture2dLayout(dim: Vec3, maxTextureSize = 4096) {
+function getVolumeTexture2dLayout(dim: Vec3, maxTextureSize: number) {
     let width = 0
     let height = dim[1]
     let rows = 1
@@ -41,19 +41,19 @@ function getVolumeTexture2dLayout(dim: Vec3, maxTextureSize = 4096) {
     return { width, height, columns, rows }
 }
 
-function createVolumeTexture2d(volume: VolumeData) {
+function createVolumeTexture2d(volume: VolumeData, maxTextureSize: number) {
     const { data: tensor, dataStats: stats } = volume
     const { space, data } = tensor
     const dim = space.dimensions as Vec3
     const { get } = space
-    const { width, height, columns, rows } = getVolumeTexture2dLayout(dim)
+    const { width, height, columns, rows } = getVolumeTexture2dLayout(dim, maxTextureSize)
 
     const array = new Uint8Array(width * height * 4)
     const textureImage = { array, width, height }
 
     const [ xl, yl, zl ] = dim
-    const xlp = xl + 1
-    const ylp = yl + 1
+    const xlp = xl + 1 // horizontal padding
+    const ylp = yl + 1 // vertical padding
 
     function setTex(value: number, x: number, y: number, z: number) {
         const column = Math.floor(((z * xlp) % width) / xlp)
@@ -77,10 +77,9 @@ function createVolumeTexture2d(volume: VolumeData) {
     return textureImage
 }
 
-export function createDirectVolume2d(ctx: RuntimeContext, volume: VolumeData, directVolume?: DirectVolume2d) {
+export function createDirectVolume2d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume2d) {
     const gridDimension = volume.data.space.dimensions as Vec3
-    // const textureImage = createTextureImage(1, 4)
-    const textureImage = createVolumeTexture2d(volume)
+    const textureImage = createVolumeTexture2d(volume, webgl.maxTextureSize)
     const transform = VolumeData.getGridToCartesianTransform(volume)
 
     console.log('textureImage', textureImage)
@@ -90,7 +89,9 @@ export function createDirectVolume2d(ctx: RuntimeContext, volume: VolumeData, di
     Box3D.add(bbox, gridDimension)
     Box3D.transform(bbox, bbox, transform)
 
-    const dim = Vec3.create(gridDimension[0] + 1, gridDimension[1] + 1, gridDimension[2])
+    const dim = Vec3.create(gridDimension[0], gridDimension[1], gridDimension[2])
+    dim[0] += 1 // horizontal padding
+    dim[0] += 1 // vertical padding
 
     if (directVolume) {
         ValueCell.update(directVolume.gridDimension, dim)
@@ -135,8 +136,7 @@ function createVolumeTexture3d(volume: VolumeData) {
     let i = 0
     for (let z = 0; z < depth; ++z) {
         for (let y = 0; y < height; ++y) {
-        for (let x = 0; x < width; ++x) {
-
+            for (let x = 0; x < width; ++x) {
                 array[i + 3] = ((get(data, x, y, z) - stats.min) / (stats.max - stats.min)) * 255
                 i += 4
             }
@@ -146,7 +146,7 @@ function createVolumeTexture3d(volume: VolumeData) {
     return textureVolume
 }
 
-export function createDirectVolume3d(ctx: RuntimeContext, volume: VolumeData, directVolume?: DirectVolume3d) {
+export function createDirectVolume3d(ctx: RuntimeContext, webgl: Context, volume: VolumeData, directVolume?: DirectVolume3d) {
     const gridDimension = volume.data.space.dimensions as Vec3
     const textureVolume = createVolumeTexture3d(volume)
     const transform = VolumeData.getGridToCartesianTransform(volume)
@@ -181,10 +181,6 @@ export function createDirectVolume3d(ctx: RuntimeContext, volume: VolumeData, di
 
 //
 
-function hasWebGL2() {
-    return true
-}
-
 export const DirectVolumeParams = {
     ...Geometry.Params,
     ...DirectVolume2d.Params
@@ -199,6 +195,9 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> {
     let directVolume: DirectVolume2d | DirectVolume3d
 
     async function create(ctx: RuntimeContext, volume: VolumeData, props: Partial<DirectVolumeProps> = {}) {
+        const { webgl } = props
+        if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props')
+
         currentProps = { ...DefaultDirectVolumeProps, ...props }
         if (props.isoValueRelative) {
             // currentProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative)
@@ -206,26 +205,28 @@ export function DirectVolumeVisual(): VolumeVisual<DirectVolumeProps> {
 
         const state = createRenderableState(currentProps)
 
-        if (hasWebGL2()) {
-            console.log('createing 3d volume')
-            directVolume = await createDirectVolume3d(ctx, volume, directVolume as DirectVolume3d)
+        if (webgl.isWebGL2) {
+            console.log('creating 3d volume')
+            directVolume = await createDirectVolume3d(ctx, webgl, volume, directVolume as DirectVolume3d)
             const values = await DirectVolume3d.createValues(ctx, directVolume as DirectVolume3d, currentProps)
             renderObject = createDirectVolume3dRenderObject(values, state)
         } else {
-            directVolume = await createDirectVolume2d(ctx, volume, directVolume as DirectVolume2d)
+            directVolume = await createDirectVolume2d(ctx, webgl, volume, directVolume as DirectVolume2d)
             const values = await DirectVolume2d.createValues(ctx, directVolume as DirectVolume2d, currentProps)
             renderObject = createDirectVolume2dRenderObject(values, state)
         }
     }
 
     async function update(ctx: RuntimeContext, props: Partial<DirectVolumeProps> = {}) {
-        console.log('props', props)
+        const { webgl } = props
+        if (webgl === undefined) throw new Error('DirectVolumeVisual requires `webgl` in props')
+
         const newProps = { ...currentProps, ...props }
         if (props.isoValueRelative) {
             // newProps.isoValueAbsolute = VolumeIsoValue.calcAbsolute(currentVolume.dataStats, props.isoValueRelative)
         }
 
-        if (hasWebGL2()) {
+        if (webgl.isWebGL2) {
             DirectVolume3d.updateValues(renderObject.values as DirectVolume3dValues, newProps)
         } else {
             DirectVolume2d.updateValues(renderObject.values as DirectVolume2dValues, newProps)

+ 2 - 2
src/mol-math/geometry/common.ts

@@ -7,8 +7,8 @@
 
 import { OrderedSet } from 'mol-data/int'
 import { Mat4, Tensor, Vec3 } from '../linear-algebra';
-import { RenderTarget } from 'mol-gl/webgl/render-target';
 import { Box3D } from '../geometry';
+import { Texture } from 'mol-gl/webgl/texture';
 
 export interface PositionData {
     x: ArrayLike<number>,
@@ -25,7 +25,7 @@ export type DensityData = {
     field: Tensor,
     idField: Tensor,
 
-    renderTarget?: RenderTarget,
+    texture?: Texture,
     bbox?: Box3D,
     gridDimension?: Vec3
 }

+ 2 - 4
src/mol-math/geometry/gaussian-density/gpu.ts

@@ -15,7 +15,6 @@ import { GaussianDensityValues } from 'mol-gl/renderable/gaussian-density'
 import { ValueCell } from 'mol-util'
 import { RenderableState } from 'mol-gl/renderable'
 import { createRenderable, createGaussianDensityRenderObject } from 'mol-gl/render-object'
-import { createRenderTarget } from 'mol-gl/webgl/render-target'
 import { Context, createContext, getGLContext } from 'mol-gl/webgl/context';
 import { createFramebuffer } from 'mol-gl/webgl/framebuffer';
 import { createTexture, Texture, TextureAttachment } from 'mol-gl/webgl/texture';
@@ -26,6 +25,7 @@ export async function GaussianDensityGPU(ctx: RuntimeContext, position: Position
     const webgl = getWebGLContext()
 
     const useMultiDraw = webgl.maxDrawBuffers > 0
+    console.log('useMultiDraw', useMultiDraw)
 
     console.time('gpu gaussian density render')
     const { texture, scale, bbox, dim } = useMultiDraw ?
@@ -46,9 +46,7 @@ export async function GaussianDensityGPU(ctx: RuntimeContext, position: Position
     Mat4.fromScaling(transform, scale)
     Mat4.setTranslation(transform, bbox.min)
 
-    const renderTarget = createRenderTarget(webgl, dim[0], dim[1])
-
-    return { field, idField, transform, renderTarget, bbox, gridDimension: dim }
+    return { field, idField, transform, texture, bbox, gridDimension: dim }
 }
 
 //

+ 8 - 1
src/mol-view/parameter.ts

@@ -13,6 +13,13 @@ export interface BaseParam<T> {
     defaultValue: T
 }
 
+export interface ValueParam<T> extends BaseParam<T> {
+    type: 'value'
+}
+export function ValueParam<T>(label: string, description: string, defaultValue: T): ValueParam<T> {
+    return { type: 'value', label, description, defaultValue }
+}
+
 export interface SelectParam<T extends string> extends BaseParam<T> {
     type: 'select'
     /** array of (value, label) tupels */
@@ -81,7 +88,7 @@ export function StructureParam(label: string, description: string, defaultValue:
     return { type: 'structure', label, description, defaultValue }
 }
 
-export type Param = SelectParam<any> | MultiSelectParam<any> | BooleanParam | RangeParam | TextParam | ColorParam | NumberParam | StructureParam
+export type Param = ValueParam<any> | SelectParam<any> | MultiSelectParam<any> | BooleanParam | RangeParam | TextParam | ColorParam | NumberParam | StructureParam
 
 export type Params = { [k: string]: Param }
 

+ 5 - 1
src/mol-view/viewer.ts

@@ -16,7 +16,7 @@ import TrackballControls from './controls/trackball'
 import { Viewport } from './camera/util'
 import { PerspectiveCamera } from './camera/perspective'
 import { resizeCanvas } from './util';
-import { createContext, getGLContext } from 'mol-gl/webgl/context';
+import { createContext, getGLContext, Context } from 'mol-gl/webgl/context';
 import { Representation } from 'mol-geo/representation';
 import { createRenderTarget } from 'mol-gl/webgl/render-target';
 import Scene from 'mol-gl/scene';
@@ -27,6 +27,8 @@ import { Loci, EmptyLoci, isEmptyLoci } from 'mol-model/loci';
 import { Color } from 'mol-util/color';
 
 interface Viewer {
+    webgl: Context,
+
     center: (p: Vec3) => void
 
     hide: (repr: Representation<any>) => void
@@ -247,6 +249,8 @@ namespace Viewer {
         handleResize()
 
         return {
+            webgl: ctx,
+
             center: (p: Vec3) => {
                 Vec3.set(controls.target, p[0], p[1], p[2])
             },