UNPKG

molstar

Version:

A comprehensive macromolecular library.

109 lines (108 loc) 5 kB
/** * Copyright (c) 2019-2024 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ import { createComputeRenderable } from '../../renderable'; import { createComputeRenderItem } from '../../webgl/render-item'; import { TextureSpec, UniformSpec, DefineSpec } from '../../renderable/schema'; import { ShaderCode } from '../../../mol-gl/shader-code'; import { ValueCell } from '../../../mol-util'; import { QuadSchema, QuadValues } from '../util'; import { getTriCount } from './tables'; import { quad_vert } from '../../../mol-gl/shader/quad.vert'; import { activeVoxels_frag } from '../../../mol-gl/shader/marching-cubes/active-voxels.frag'; import { isTimingMode } from '../../../mol-util/debug'; import { isWebGL2 } from '../../webgl/compat'; const ActiveVoxelsSchema = { ...QuadSchema, tTriCount: TextureSpec('image-uint8', 'alpha', 'ubyte', 'nearest'), tVolumeData: TextureSpec('texture', 'rgba', 'ubyte', 'nearest'), dValueChannel: DefineSpec('string', ['red', 'alpha']), uIsoValue: UniformSpec('f'), uGridDim: UniformSpec('v3'), uGridTexDim: UniformSpec('v3'), uScale: UniformSpec('v2'), }; const ActiveVoxelsName = 'active-voxels'; function valueChannel(ctx, volumeData) { return isWebGL2(ctx.gl) && volumeData.format === ctx.gl.RED ? 'red' : 'alpha'; } function getActiveVoxelsRenderable(ctx, volumeData, gridDim, gridTexDim, isoValue, scale) { if (ctx.namedComputeRenderables[ActiveVoxelsName]) { const v = ctx.namedComputeRenderables[ActiveVoxelsName].values; ValueCell.update(v.uQuadScale, scale); ValueCell.update(v.tVolumeData, volumeData); ValueCell.update(v.dValueChannel, valueChannel(ctx, volumeData)); ValueCell.updateIfChanged(v.uIsoValue, isoValue); ValueCell.update(v.uGridDim, gridDim); ValueCell.update(v.uGridTexDim, gridTexDim); ValueCell.update(v.uScale, scale); ctx.namedComputeRenderables[ActiveVoxelsName].update(); } else { ctx.namedComputeRenderables[ActiveVoxelsName] = createActiveVoxelsRenderable(ctx, volumeData, gridDim, gridTexDim, isoValue, scale); } return ctx.namedComputeRenderables[ActiveVoxelsName]; } function createActiveVoxelsRenderable(ctx, volumeData, gridDim, gridTexDim, isoValue, scale) { const values = { ...QuadValues, tTriCount: ValueCell.create(getTriCount()), uQuadScale: ValueCell.create(scale), tVolumeData: ValueCell.create(volumeData), dValueChannel: ValueCell.create(valueChannel(ctx, volumeData)), uIsoValue: ValueCell.create(isoValue), uGridDim: ValueCell.create(gridDim), uGridTexDim: ValueCell.create(gridTexDim), uScale: ValueCell.create(scale), }; const schema = { ...ActiveVoxelsSchema }; const shaderCode = ShaderCode('active-voxels', quad_vert, activeVoxels_frag); const renderItem = createComputeRenderItem(ctx, 'triangles', shaderCode, schema, values); return createComputeRenderable(renderItem, values); } function setRenderingDefaults(ctx) { const { gl, state } = ctx; state.disable(gl.CULL_FACE); state.disable(gl.BLEND); state.disable(gl.DEPTH_TEST); state.enable(gl.SCISSOR_TEST); state.depthMask(false); state.colorMask(true, true, true, true); state.clearColor(0, 0, 0, 0); } export function calcActiveVoxels(ctx, volumeData, gridDim, gridTexDim, isoValue, gridScale) { if (isTimingMode) ctx.timer.mark('calcActiveVoxels'); const { gl, state, resources } = ctx; const width = volumeData.getWidth(); const height = volumeData.getHeight(); if (!ctx.namedFramebuffers[ActiveVoxelsName]) { ctx.namedFramebuffers[ActiveVoxelsName] = resources.framebuffer(); } const framebuffer = ctx.namedFramebuffers[ActiveVoxelsName]; framebuffer.bind(); if (!ctx.namedTextures[ActiveVoxelsName]) { ctx.namedTextures[ActiveVoxelsName] = resources.texture('image-uint8', 'rgba', 'ubyte', 'nearest'); } const activeVoxelsTex = ctx.namedTextures[ActiveVoxelsName]; activeVoxelsTex.define(width, height); const renderable = getActiveVoxelsRenderable(ctx, volumeData, gridDim, gridTexDim, isoValue, gridScale); ctx.state.currentRenderItemId = -1; activeVoxelsTex.attachFramebuffer(framebuffer, 0); setRenderingDefaults(ctx); state.viewport(0, 0, width, height); state.scissor(0, 0, width, height); gl.clear(gl.COLOR_BUFFER_BIT); state.scissor(0, 0, gridTexDim[0], gridTexDim[1]); renderable.render(); // console.log('gridScale', gridScale, 'gridTexDim', gridTexDim, 'gridDim', gridDim); // console.log('volumeData', volumeData); // console.log('at', readTexture(ctx, activeVoxelsTex)); // printTextureImage(readTexture(ctx, activeVoxelsTex), { scale: 0.75 }); gl.finish(); if (isTimingMode) ctx.timer.markEnd('calcActiveVoxels'); return activeVoxelsTex; }