render-target.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /**
  2. * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { idFactory } from '../../mol-util/id-factory';
  7. import { Texture, TextureFilter } from './texture';
  8. import { Framebuffer } from './framebuffer';
  9. import { WebGLResources } from './resources';
  10. import { GLRenderingContext } from './compat';
  11. const getNextRenderTargetId = idFactory();
  12. export interface RenderTarget {
  13. readonly id: number
  14. readonly texture: Texture
  15. readonly framebuffer: Framebuffer
  16. getWidth: () => number
  17. getHeight: () => number
  18. /** binds framebuffer and sets viewport to rendertarget's width and height */
  19. bind: () => void
  20. setSize: (width: number, height: number) => void
  21. reset: () => void
  22. destroy: () => void
  23. }
  24. export function createRenderTarget(gl: GLRenderingContext, resources: WebGLResources, _width: number, _height: number, depth = true, type: 'uint8' | 'float32' = 'uint8', filter: TextureFilter = 'nearest'): RenderTarget {
  25. const framebuffer = resources.framebuffer();
  26. const targetTexture = type === 'float32'
  27. ? resources.texture('image-float32', 'rgba', 'float', filter)
  28. : resources.texture('image-uint8', 'rgba', 'ubyte', filter);
  29. // make a depth renderbuffer of the same size as the targetTexture
  30. const depthRenderbuffer = depth
  31. ? resources.renderbuffer('depth16', 'depth', _width, _height)
  32. : null;
  33. function init() {
  34. targetTexture.define(_width, _height);
  35. targetTexture.attachFramebuffer(framebuffer, 'color0');
  36. if (depthRenderbuffer) depthRenderbuffer.attachFramebuffer(framebuffer);
  37. }
  38. init();
  39. let destroyed = false;
  40. return {
  41. id: getNextRenderTargetId(),
  42. texture: targetTexture,
  43. framebuffer,
  44. getWidth: () => _width,
  45. getHeight: () => _height,
  46. bind: () => {
  47. framebuffer.bind();
  48. gl.viewport(0, 0, _width, _height);
  49. },
  50. setSize: (width: number, height: number) => {
  51. _width = width;
  52. _height = height;
  53. targetTexture.define(_width, _height);
  54. if (depthRenderbuffer) depthRenderbuffer.setSize(_width, _height);
  55. },
  56. reset: () => {
  57. init();
  58. },
  59. destroy: () => {
  60. if (destroyed) return;
  61. targetTexture.destroy();
  62. framebuffer.destroy();
  63. if (depthRenderbuffer) depthRenderbuffer.destroy();
  64. destroyed = true;
  65. }
  66. };
  67. }