image.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /**
  2. * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { WebGLContext } from '../../mol-gl/webgl/context';
  7. import { RenderTarget } from '../../mol-gl/webgl/render-target';
  8. import Renderer from '../../mol-gl/renderer';
  9. import Scene from '../../mol-gl/scene';
  10. import { BoundingSphereHelper } from '../helper/bounding-sphere-helper';
  11. import { ParamDefinition as PD } from '../../mol-util/param-definition';
  12. import { DrawPass, DrawPassParams } from './draw'
  13. import { PostprocessingPass, PostprocessingParams } from './postprocessing'
  14. import { MultiSamplePass, MultiSampleParams } from './multi-sample'
  15. import { Camera } from '../camera';
  16. import { Viewport } from '../camera/util';
  17. export const ImageParams = {
  18. transparentBackground: PD.Boolean(false),
  19. multiSample: PD.Group(MultiSampleParams),
  20. postprocessing: PD.Group(PostprocessingParams),
  21. drawPass: PD.Group(DrawPassParams),
  22. }
  23. export type ImageProps = PD.Values<typeof ImageParams>
  24. export class ImagePass {
  25. private _width = 1024
  26. private _height = 768
  27. private _camera = new Camera()
  28. private _transparentBackground = false
  29. private _colorTarget: RenderTarget
  30. get colorTarget() { return this._colorTarget }
  31. readonly drawPass: DrawPass
  32. private readonly postprocessing: PostprocessingPass
  33. private readonly multiSample: MultiSamplePass
  34. get width() { return this._width }
  35. get height() { return this._height }
  36. constructor(webgl: WebGLContext, private renderer: Renderer, scene: Scene, private camera: Camera, debugHelper: BoundingSphereHelper, props: Partial<ImageProps>) {
  37. const p = { ...PD.getDefaultValues(ImageParams), ...props }
  38. this._transparentBackground = p.transparentBackground
  39. this.drawPass = new DrawPass(webgl, renderer, scene, this._camera, debugHelper, p.drawPass)
  40. this.postprocessing = new PostprocessingPass(webgl, this._camera, this.drawPass, p.postprocessing)
  41. this.multiSample = new MultiSamplePass(webgl, this._camera, this.drawPass, this.postprocessing, p.multiSample)
  42. this.setSize(this._width, this._height)
  43. }
  44. setSize(width: number, height: number) {
  45. if (width === this._width && height === this._height) return
  46. this._width = width
  47. this._height = height
  48. this.drawPass.setSize(width, height)
  49. this.postprocessing.setSize(width, height)
  50. this.multiSample.setSize(width, height)
  51. }
  52. setProps(props: Partial<ImageProps> = {}) {
  53. if (props.transparentBackground !== undefined) this._transparentBackground = props.transparentBackground
  54. if (props.postprocessing) this.postprocessing.setProps(props.postprocessing)
  55. if (props.multiSample) this.multiSample.setProps(props.multiSample)
  56. if (props.drawPass) this.drawPass.setProps(props.drawPass)
  57. }
  58. get props(): ImageProps {
  59. return {
  60. transparentBackground: this._transparentBackground,
  61. postprocessing: this.postprocessing.props,
  62. multiSample: this.multiSample.props,
  63. drawPass: this.drawPass.props
  64. }
  65. }
  66. render() {
  67. Camera.copySnapshot(this._camera.state, this.camera.state)
  68. Viewport.set(this._camera.viewport, 0, 0, this._width, this._height)
  69. this._camera.update()
  70. this.renderer.setViewport(0, 0, this._width, this._height);
  71. if (this.multiSample.enabled) {
  72. this.multiSample.render(false, this._transparentBackground)
  73. this._colorTarget = this.multiSample.colorTarget
  74. } else {
  75. this.drawPass.render(false, this._transparentBackground)
  76. if (this.postprocessing.enabled) {
  77. this.postprocessing.render(false)
  78. this._colorTarget = this.postprocessing.target
  79. } else {
  80. this._colorTarget = this.drawPass.colorTarget
  81. }
  82. }
  83. }
  84. getImageData(width: number, height: number) {
  85. this.setSize(width, height)
  86. this.render()
  87. const pd = this.colorTarget.getPixelData()
  88. return new ImageData(new Uint8ClampedArray(pd.array), pd.width, pd.height)
  89. }
  90. }