renderer.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /**
  2. * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Vec3, Mat4 } from 'mol-math/linear-algebra'
  7. import { Viewport } from 'mol-view/camera/util';
  8. import { Camera } from 'mol-view/camera/base';
  9. import * as glContext from './context'
  10. import Scene, { RenderObject } from './scene';
  11. export interface RendererStats {
  12. elementsCount: number
  13. bufferCount: number
  14. textureCount: number
  15. shaderCount: number
  16. renderableCount: number
  17. }
  18. interface Renderer {
  19. add: (o: RenderObject) => void
  20. remove: (o: RenderObject) => void
  21. clear: () => void
  22. draw: () => void
  23. setViewport: (viewport: Viewport) => void
  24. stats: RendererStats
  25. dispose: () => void
  26. }
  27. const extensions = [
  28. 'OES_element_index_uint',
  29. 'ANGLE_instanced_arrays'
  30. ]
  31. const optionalExtensions = [
  32. 'EXT_disjoint_timer_query'
  33. ]
  34. function getPixelRatio() {
  35. return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
  36. }
  37. namespace Renderer {
  38. export function create(gl: WebGLRenderingContext, camera: Camera): Renderer {
  39. const regl = glContext.create({ gl, extensions, optionalExtensions, profile: false })
  40. const scene = Scene.create(regl)
  41. const baseContext = regl({
  42. context: {
  43. model: Mat4.identity(),
  44. transform: Mat4.identity(),
  45. view: camera.view,
  46. projection: camera.projection,
  47. },
  48. uniforms: {
  49. pixelRatio: getPixelRatio(),
  50. viewportHeight: regl.context('viewportHeight'),
  51. model: regl.context('model' as any),
  52. transform: regl.context('transform' as any),
  53. view: regl.context('view' as any),
  54. projection: regl.context('projection' as any),
  55. 'light.position': Vec3.create(0, 0, -100),
  56. 'light.color': Vec3.create(1.0, 1.0, 1.0),
  57. 'light.ambient': Vec3.create(0.5, 0.5, 0.5),
  58. 'light.falloff': 0,
  59. 'light.radius': 500
  60. }
  61. })
  62. const draw = () => {
  63. regl.poll() // updates timers and viewport
  64. camera.update()
  65. baseContext(state => {
  66. regl.clear({ color: [0, 0, 0, 1] })
  67. // TODO painters sort, filter visible, filter picking, visibility culling?
  68. scene.forEach((r, o) => {
  69. if (o.visible) r.draw()
  70. })
  71. })
  72. }
  73. return {
  74. add: (o: RenderObject) => {
  75. scene.add(o)
  76. },
  77. remove: (o: RenderObject) => {
  78. scene.remove(o)
  79. },
  80. clear: () => {
  81. scene.clear()
  82. },
  83. draw,
  84. setViewport: (viewport: Viewport) => {
  85. regl({ viewport })
  86. },
  87. get stats() {
  88. return {
  89. elementsCount: regl.stats.elementsCount,
  90. bufferCount: regl.stats.bufferCount,
  91. textureCount: regl.stats.textureCount,
  92. shaderCount: regl.stats.shaderCount,
  93. renderableCount: scene.count
  94. }
  95. },
  96. dispose: () => {
  97. regl.destroy()
  98. }
  99. }
  100. }
  101. }
  102. export default Renderer