@react-x11/components 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +979 -21
- package/dist/ansi/cast.d.ts +48 -0
- package/dist/ansi/cast.d.ts.map +1 -0
- package/dist/ansi/cast.js +135 -0
- package/dist/ansi/cast.js.map +1 -0
- package/dist/ansi/index.d.ts +10 -0
- package/dist/ansi/index.d.ts.map +1 -0
- package/dist/ansi/index.js +27 -0
- package/dist/ansi/index.js.map +1 -0
- package/dist/ansi/palette.d.ts +79 -0
- package/dist/ansi/palette.d.ts.map +1 -0
- package/dist/ansi/palette.js +155 -0
- package/dist/ansi/palette.js.map +1 -0
- package/dist/ansi/parse.d.ts +114 -0
- package/dist/ansi/parse.d.ts.map +1 -0
- package/dist/ansi/parse.js +687 -0
- package/dist/ansi/parse.js.map +1 -0
- package/dist/ansi/sgr.d.ts +87 -0
- package/dist/ansi/sgr.d.ts.map +1 -0
- package/dist/ansi/sgr.js +302 -0
- package/dist/ansi/sgr.js.map +1 -0
- package/dist/ansi/utf8.d.ts +15 -0
- package/dist/ansi/utf8.d.ts.map +1 -0
- package/dist/ansi/utf8.js +82 -0
- package/dist/ansi/utf8.js.map +1 -0
- package/dist/calendar/Calendar.d.ts +136 -0
- package/dist/calendar/Calendar.d.ts.map +1 -0
- package/dist/calendar/Calendar.js +460 -0
- package/dist/calendar/Calendar.js.map +1 -0
- package/dist/calendar/DatePicker.d.ts +52 -0
- package/dist/calendar/DatePicker.d.ts.map +1 -0
- package/dist/calendar/DatePicker.js +257 -0
- package/dist/calendar/DatePicker.js.map +1 -0
- package/dist/calendar/dates.d.ts +90 -0
- package/dist/calendar/dates.d.ts.map +1 -0
- package/dist/calendar/dates.js +236 -0
- package/dist/calendar/dates.js.map +1 -0
- package/dist/calendar/index.d.ts +8 -0
- package/dist/calendar/index.d.ts.map +1 -0
- package/dist/calendar/index.js +15 -0
- package/dist/calendar/index.js.map +1 -0
- package/dist/charts/components.d.ts +141 -0
- package/dist/charts/components.d.ts.map +1 -0
- package/dist/charts/components.js +580 -0
- package/dist/charts/components.js.map +1 -0
- package/dist/charts/data.d.ts +198 -0
- package/dist/charts/data.d.ts.map +1 -0
- package/dist/charts/data.js +616 -0
- package/dist/charts/data.js.map +1 -0
- package/dist/charts/hx.d.ts +21 -0
- package/dist/charts/hx.d.ts.map +1 -0
- package/dist/charts/hx.js +15 -0
- package/dist/charts/hx.js.map +1 -0
- package/dist/charts/index.d.ts +27 -0
- package/dist/charts/index.d.ts.map +1 -0
- package/dist/charts/index.js +38 -0
- package/dist/charts/index.js.map +1 -0
- package/dist/charts/node.d.ts +96 -0
- package/dist/charts/node.d.ts.map +1 -0
- package/dist/charts/node.js +720 -0
- package/dist/charts/node.js.map +1 -0
- package/dist/charts/render.d.ts +153 -0
- package/dist/charts/render.d.ts.map +1 -0
- package/dist/charts/render.js +762 -0
- package/dist/charts/render.js.map +1 -0
- package/dist/charts/scale.d.ts +42 -0
- package/dist/charts/scale.d.ts.map +1 -0
- package/dist/charts/scale.js +173 -0
- package/dist/charts/scale.js.map +1 -0
- package/dist/charts/spec.d.ts +91 -0
- package/dist/charts/spec.d.ts.map +1 -0
- package/dist/charts/spec.js +33 -0
- package/dist/charts/spec.js.map +1 -0
- package/dist/charts/timers.d.ts +6 -0
- package/dist/charts/timers.d.ts.map +1 -0
- package/dist/charts/timers.js +14 -0
- package/dist/charts/timers.js.map +1 -0
- package/dist/code/hx.d.ts +24 -0
- package/dist/code/hx.d.ts.map +1 -0
- package/dist/code/hx.js +25 -0
- package/dist/code/hx.js.map +1 -0
- package/dist/code/index.d.ts +45 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/index.js +93 -0
- package/dist/code/index.js.map +1 -0
- package/dist/code-editor/completion.d.ts +26 -0
- package/dist/code-editor/completion.d.ts.map +1 -0
- package/dist/code-editor/completion.js +129 -0
- package/dist/code-editor/completion.js.map +1 -0
- package/dist/code-editor/doc.d.ts +35 -0
- package/dist/code-editor/doc.d.ts.map +1 -0
- package/dist/code-editor/doc.js +162 -0
- package/dist/code-editor/doc.js.map +1 -0
- package/dist/code-editor/hx.d.ts +13 -0
- package/dist/code-editor/hx.d.ts.map +1 -0
- package/dist/code-editor/hx.js +10 -0
- package/dist/code-editor/hx.js.map +1 -0
- package/dist/code-editor/index.d.ts +88 -0
- package/dist/code-editor/index.d.ts.map +1 -0
- package/dist/code-editor/index.js +401 -0
- package/dist/code-editor/index.js.map +1 -0
- package/dist/code-editor/node.d.ts +343 -0
- package/dist/code-editor/node.d.ts.map +1 -0
- package/dist/code-editor/node.js +1521 -0
- package/dist/code-editor/node.js.map +1 -0
- package/dist/code-language/hljs.d.ts +47 -0
- package/dist/code-language/hljs.d.ts.map +1 -0
- package/dist/code-language/hljs.js +211 -0
- package/dist/code-language/hljs.js.map +1 -0
- package/dist/code-language/index.d.ts +22 -0
- package/dist/code-language/index.d.ts.map +1 -0
- package/dist/code-language/index.js +20 -0
- package/dist/code-language/index.js.map +1 -0
- package/dist/code-language/languages/glsl.d.ts +4 -0
- package/dist/code-language/languages/glsl.d.ts.map +1 -0
- package/dist/code-language/languages/glsl.js +99 -0
- package/dist/code-language/languages/glsl.js.map +1 -0
- package/dist/code-language/languages/javascript.d.ts +10 -0
- package/dist/code-language/languages/javascript.d.ts.map +1 -0
- package/dist/code-language/languages/javascript.js +360 -0
- package/dist/code-language/languages/javascript.js.map +1 -0
- package/dist/code-language/languages/json.d.ts +4 -0
- package/dist/code-language/languages/json.d.ts.map +1 -0
- package/dist/code-language/languages/json.js +68 -0
- package/dist/code-language/languages/json.js.map +1 -0
- package/dist/code-language/languages/shell.d.ts +4 -0
- package/dist/code-language/languages/shell.d.ts.map +1 -0
- package/dist/code-language/languages/shell.js +189 -0
- package/dist/code-language/languages/shell.js.map +1 -0
- package/dist/code-language/languages/sql.d.ts +11 -0
- package/dist/code-language/languages/sql.d.ts.map +1 -0
- package/dist/code-language/languages/sql.js +133 -0
- package/dist/code-language/languages/sql.js.map +1 -0
- package/dist/code-language/lezer.d.ts +24 -0
- package/dist/code-language/lezer.d.ts.map +1 -0
- package/dist/code-language/lezer.js +148 -0
- package/dist/code-language/lezer.js.map +1 -0
- package/dist/code-language/registry.d.ts +19 -0
- package/dist/code-language/registry.d.ts.map +1 -0
- package/dist/code-language/registry.js +56 -0
- package/dist/code-language/registry.js.map +1 -0
- package/dist/code-language/runs.d.ts +35 -0
- package/dist/code-language/runs.d.ts.map +1 -0
- package/dist/code-language/runs.js +88 -0
- package/dist/code-language/runs.js.map +1 -0
- package/dist/code-language/stream.d.ts +70 -0
- package/dist/code-language/stream.d.ts.map +1 -0
- package/dist/code-language/stream.js +243 -0
- package/dist/code-language/stream.js.map +1 -0
- package/dist/code-language/textmate.d.ts +27 -0
- package/dist/code-language/textmate.d.ts.map +1 -0
- package/dist/code-language/textmate.js +86 -0
- package/dist/code-language/textmate.js.map +1 -0
- package/dist/code-language/theme.d.ts +26 -0
- package/dist/code-language/theme.d.ts.map +1 -0
- package/dist/code-language/theme.js +108 -0
- package/dist/code-language/theme.js.map +1 -0
- package/dist/code-language/timers.d.ts +7 -0
- package/dist/code-language/timers.d.ts.map +1 -0
- package/dist/code-language/timers.js +22 -0
- package/dist/code-language/timers.js.map +1 -0
- package/dist/code-language/types.d.ts +173 -0
- package/dist/code-language/types.d.ts.map +1 -0
- package/dist/code-language/types.js +41 -0
- package/dist/code-language/types.js.map +1 -0
- package/dist/codeblock/index.d.ts +69 -0
- package/dist/codeblock/index.d.ts.map +1 -0
- package/dist/codeblock/index.js +85 -0
- package/dist/codeblock/index.js.map +1 -0
- package/dist/color-picker/ColorField.d.ts +39 -0
- package/dist/color-picker/ColorField.d.ts.map +1 -0
- package/dist/color-picker/ColorField.js +239 -0
- package/dist/color-picker/ColorField.js.map +1 -0
- package/dist/color-picker/ColorPicker.d.ts +109 -0
- package/dist/color-picker/ColorPicker.d.ts.map +1 -0
- package/dist/color-picker/ColorPicker.js +757 -0
- package/dist/color-picker/ColorPicker.js.map +1 -0
- package/dist/color-picker/color.d.ts +105 -0
- package/dist/color-picker/color.d.ts.map +1 -0
- package/dist/color-picker/color.js +313 -0
- package/dist/color-picker/color.js.map +1 -0
- package/dist/color-picker/index.d.ts +8 -0
- package/dist/color-picker/index.d.ts.map +1 -0
- package/dist/color-picker/index.js +19 -0
- package/dist/color-picker/index.js.map +1 -0
- package/dist/desktop-calendar/eds.d.ts +102 -0
- package/dist/desktop-calendar/eds.d.ts.map +1 -0
- package/dist/desktop-calendar/eds.js +356 -0
- package/dist/desktop-calendar/eds.js.map +1 -0
- package/dist/desktop-calendar/ical.d.ts +63 -0
- package/dist/desktop-calendar/ical.d.ts.map +1 -0
- package/dist/desktop-calendar/ical.js +57 -0
- package/dist/desktop-calendar/ical.js.map +1 -0
- package/dist/desktop-calendar/index.d.ts +72 -0
- package/dist/desktop-calendar/index.d.ts.map +1 -0
- package/dist/desktop-calendar/index.js +213 -0
- package/dist/desktop-calendar/index.js.map +1 -0
- package/dist/embed/client.d.ts +121 -0
- package/dist/embed/client.d.ts.map +1 -0
- package/dist/embed/client.js +203 -0
- package/dist/embed/client.js.map +1 -0
- package/dist/embed/host.d.ts +96 -0
- package/dist/embed/host.d.ts.map +1 -0
- package/dist/embed/host.js +266 -0
- package/dist/embed/host.js.map +1 -0
- package/dist/embed/index.d.ts +5 -0
- package/dist/embed/index.d.ts.map +1 -0
- package/dist/embed/index.js +13 -0
- package/dist/embed/index.js.map +1 -0
- package/dist/embed/timers.d.ts +6 -0
- package/dist/embed/timers.d.ts.map +1 -0
- package/dist/embed/timers.js +16 -0
- package/dist/embed/timers.js.map +1 -0
- package/dist/flow/draw.d.ts +45 -0
- package/dist/flow/draw.d.ts.map +1 -0
- package/dist/flow/draw.js +295 -0
- package/dist/flow/draw.js.map +1 -0
- package/dist/flow/index.d.ts +64 -0
- package/dist/flow/index.d.ts.map +1 -0
- package/dist/flow/index.js +306 -0
- package/dist/flow/index.js.map +1 -0
- package/dist/flow/model.d.ts +158 -0
- package/dist/flow/model.d.ts.map +1 -0
- package/dist/flow/model.js +566 -0
- package/dist/flow/model.js.map +1 -0
- package/dist/flow/node.d.ts +429 -0
- package/dist/flow/node.d.ts.map +1 -0
- package/dist/flow/node.js +3025 -0
- package/dist/flow/node.js.map +1 -0
- package/dist/flow/paths.d.ts +43 -0
- package/dist/flow/paths.d.ts.map +1 -0
- package/dist/flow/paths.js +327 -0
- package/dist/flow/paths.js.map +1 -0
- package/dist/flow/types.d.ts +561 -0
- package/dist/flow/types.d.ts.map +1 -0
- package/dist/flow/types.js +2 -0
- package/dist/flow/types.js.map +1 -0
- package/dist/formula/hx.d.ts +24 -0
- package/dist/formula/hx.d.ts.map +1 -0
- package/dist/formula/hx.js +25 -0
- package/dist/formula/hx.js.map +1 -0
- package/dist/formula/index.d.ts +74 -0
- package/dist/formula/index.d.ts.map +1 -0
- package/dist/formula/index.js +155 -0
- package/dist/formula/index.js.map +1 -0
- package/dist/formula/katex.d.ts +78 -0
- package/dist/formula/katex.d.ts.map +1 -0
- package/dist/formula/katex.js +130 -0
- package/dist/formula/katex.js.map +1 -0
- package/dist/formula/layout.d.ts +103 -0
- package/dist/formula/layout.d.ts.map +1 -0
- package/dist/formula/layout.js +716 -0
- package/dist/formula/layout.js.map +1 -0
- package/dist/formula/node.d.ts +50 -0
- package/dist/formula/node.d.ts.map +1 -0
- package/dist/formula/node.js +351 -0
- package/dist/formula/node.js.map +1 -0
- package/dist/html/controls.d.ts +48 -0
- package/dist/html/controls.d.ts.map +1 -0
- package/dist/html/controls.js +195 -0
- package/dist/html/controls.js.map +1 -0
- package/dist/html/css/cascade.d.ts +51 -0
- package/dist/html/css/cascade.d.ts.map +1 -0
- package/dist/html/css/cascade.js +552 -0
- package/dist/html/css/cascade.js.map +1 -0
- package/dist/html/css/parse.d.ts +74 -0
- package/dist/html/css/parse.d.ts.map +1 -0
- package/dist/html/css/parse.js +464 -0
- package/dist/html/css/parse.js.map +1 -0
- package/dist/html/css/style.d.ts +142 -0
- package/dist/html/css/style.d.ts.map +1 -0
- package/dist/html/css/style.js +1145 -0
- package/dist/html/css/style.js.map +1 -0
- package/dist/html/css/ua.d.ts +5 -0
- package/dist/html/css/ua.d.ts.map +1 -0
- package/dist/html/css/ua.js +171 -0
- package/dist/html/css/ua.js.map +1 -0
- package/dist/html/css/values.d.ts +78 -0
- package/dist/html/css/values.d.ts.map +1 -0
- package/dist/html/css/values.js +330 -0
- package/dist/html/css/values.js.map +1 -0
- package/dist/html/dom.d.ts +112 -0
- package/dist/html/dom.d.ts.map +1 -0
- package/dist/html/dom.js +374 -0
- package/dist/html/dom.js.map +1 -0
- package/dist/html/hx.d.ts +24 -0
- package/dist/html/hx.d.ts.map +1 -0
- package/dist/html/hx.js +29 -0
- package/dist/html/hx.js.map +1 -0
- package/dist/html/index.d.ts +137 -0
- package/dist/html/index.d.ts.map +1 -0
- package/dist/html/index.js +339 -0
- package/dist/html/index.js.map +1 -0
- package/dist/html/layout/block.d.ts +58 -0
- package/dist/html/layout/block.d.ts.map +1 -0
- package/dist/html/layout/block.js +724 -0
- package/dist/html/layout/block.js.map +1 -0
- package/dist/html/layout/boxes.d.ts +261 -0
- package/dist/html/layout/boxes.d.ts.map +1 -0
- package/dist/html/layout/boxes.js +725 -0
- package/dist/html/layout/boxes.js.map +1 -0
- package/dist/html/layout/flex.d.ts +16 -0
- package/dist/html/layout/flex.d.ts.map +1 -0
- package/dist/html/layout/flex.js +242 -0
- package/dist/html/layout/flex.js.map +1 -0
- package/dist/html/layout/floats.d.ts +50 -0
- package/dist/html/layout/floats.d.ts.map +1 -0
- package/dist/html/layout/floats.js +110 -0
- package/dist/html/layout/floats.js.map +1 -0
- package/dist/html/layout/inline.d.ts +44 -0
- package/dist/html/layout/inline.d.ts.map +1 -0
- package/dist/html/layout/inline.js +700 -0
- package/dist/html/layout/inline.js.map +1 -0
- package/dist/html/layout/table.d.ts +5 -0
- package/dist/html/layout/table.d.ts.map +1 -0
- package/dist/html/layout/table.js +340 -0
- package/dist/html/layout/table.js.map +1 -0
- package/dist/html/node.d.ts +149 -0
- package/dist/html/node.d.ts.map +1 -0
- package/dist/html/node.js +861 -0
- package/dist/html/node.js.map +1 -0
- package/dist/html/paint.d.ts +48 -0
- package/dist/html/paint.d.ts.map +1 -0
- package/dist/html/paint.js +495 -0
- package/dist/html/paint.js.map +1 -0
- package/dist/html/resources.d.ts +48 -0
- package/dist/html/resources.d.ts.map +1 -0
- package/dist/html/resources.js +156 -0
- package/dist/html/resources.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/heights.d.ts +88 -0
- package/dist/internal/heights.d.ts.map +1 -0
- package/dist/internal/heights.js +203 -0
- package/dist/internal/heights.js.map +1 -0
- package/dist/internal/hx.d.ts +24 -0
- package/dist/internal/hx.d.ts.map +1 -0
- package/dist/internal/hx.js +27 -0
- package/dist/internal/hx.js.map +1 -0
- package/dist/internal/scroll.d.ts +62 -0
- package/dist/internal/scroll.d.ts.map +1 -0
- package/dist/internal/scroll.js +224 -0
- package/dist/internal/scroll.js.map +1 -0
- package/dist/internal/text.d.ts +6 -0
- package/dist/internal/text.d.ts.map +1 -0
- package/dist/internal/text.js +44 -0
- package/dist/internal/text.js.map +1 -0
- package/dist/internal/timers.d.ts +8 -0
- package/dist/internal/timers.d.ts.map +1 -0
- package/dist/internal/timers.js +22 -0
- package/dist/internal/timers.js.map +1 -0
- package/dist/internal/widget.d.ts +40 -0
- package/dist/internal/widget.d.ts.map +1 -0
- package/dist/internal/widget.js +44 -0
- package/dist/internal/widget.js.map +1 -0
- package/dist/markdown/ast.d.ts +126 -0
- package/dist/markdown/ast.d.ts.map +1 -0
- package/dist/markdown/ast.js +8 -0
- package/dist/markdown/ast.js.map +1 -0
- package/dist/markdown/hx.d.ts +24 -0
- package/dist/markdown/hx.d.ts.map +1 -0
- package/dist/markdown/hx.js +25 -0
- package/dist/markdown/hx.js.map +1 -0
- package/dist/markdown/index.d.ts +90 -0
- package/dist/markdown/index.d.ts.map +1 -0
- package/dist/markdown/index.js +413 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +8 -0
- package/dist/markdown/parse.d.ts.map +1 -0
- package/dist/markdown/parse.js +911 -0
- package/dist/markdown/parse.js.map +1 -0
- package/dist/markdown/spans.d.ts +20 -0
- package/dist/markdown/spans.d.ts.map +1 -0
- package/dist/markdown/spans.js +96 -0
- package/dist/markdown/spans.js.map +1 -0
- package/dist/media-player/backends.d.ts +64 -0
- package/dist/media-player/backends.d.ts.map +1 -0
- package/dist/media-player/backends.js +110 -0
- package/dist/media-player/backends.js.map +1 -0
- package/dist/media-player/control.d.ts +40 -0
- package/dist/media-player/control.d.ts.map +1 -0
- package/dist/media-player/control.js +44 -0
- package/dist/media-player/control.js.map +1 -0
- package/dist/media-player/hx.d.ts +24 -0
- package/dist/media-player/hx.d.ts.map +1 -0
- package/dist/media-player/hx.js +25 -0
- package/dist/media-player/hx.js.map +1 -0
- package/dist/media-player/index.d.ts +107 -0
- package/dist/media-player/index.d.ts.map +1 -0
- package/dist/media-player/index.js +219 -0
- package/dist/media-player/index.js.map +1 -0
- package/dist/media-player/mpv.d.ts +4 -0
- package/dist/media-player/mpv.d.ts.map +1 -0
- package/dist/media-player/mpv.js +120 -0
- package/dist/media-player/mpv.js.map +1 -0
- package/dist/media-player/vlc.d.ts +8 -0
- package/dist/media-player/vlc.d.ts.map +1 -0
- package/dist/media-player/vlc.js +83 -0
- package/dist/media-player/vlc.js.map +1 -0
- package/dist/richtext/index.d.ts +19 -0
- package/dist/richtext/index.d.ts.map +1 -0
- package/dist/richtext/index.js +4 -0
- package/dist/richtext/index.js.map +1 -0
- package/dist/richtext/links.d.ts +12 -0
- package/dist/richtext/links.d.ts.map +1 -0
- package/dist/richtext/links.js +64 -0
- package/dist/richtext/links.js.map +1 -0
- package/dist/richtext/menu.d.ts +11 -0
- package/dist/richtext/menu.d.ts.map +1 -0
- package/dist/richtext/menu.js +43 -0
- package/dist/richtext/menu.js.map +1 -0
- package/dist/richtext/node.d.ts +151 -0
- package/dist/richtext/node.d.ts.map +1 -0
- package/dist/richtext/node.js +255 -0
- package/dist/richtext/node.js.map +1 -0
- package/dist/richtext/runs.d.ts +92 -0
- package/dist/richtext/runs.d.ts.map +1 -0
- package/dist/richtext/runs.js +158 -0
- package/dist/richtext/runs.js.map +1 -0
- package/dist/table/hx.d.ts +24 -0
- package/dist/table/hx.d.ts.map +1 -0
- package/dist/table/hx.js +25 -0
- package/dist/table/hx.js.map +1 -0
- package/dist/table/index.d.ts +169 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +890 -0
- package/dist/table/index.js.map +1 -0
- package/dist/table/rows.d.ts +136 -0
- package/dist/table/rows.d.ts.map +1 -0
- package/dist/table/rows.js +146 -0
- package/dist/table/rows.js.map +1 -0
- package/dist/terminal/backends.d.ts +105 -0
- package/dist/terminal/backends.d.ts.map +1 -0
- package/dist/terminal/backends.js +185 -0
- package/dist/terminal/backends.js.map +1 -0
- package/dist/terminal/hx.d.ts +24 -0
- package/dist/terminal/hx.d.ts.map +1 -0
- package/dist/terminal/hx.js +25 -0
- package/dist/terminal/hx.js.map +1 -0
- package/dist/terminal/index.d.ts +160 -0
- package/dist/terminal/index.d.ts.map +1 -0
- package/dist/terminal/index.js +344 -0
- package/dist/terminal/index.js.map +1 -0
- package/dist/terminal/title.d.ts +24 -0
- package/dist/terminal/title.d.ts.map +1 -0
- package/dist/terminal/title.js +129 -0
- package/dist/terminal/title.js.map +1 -0
- package/dist/terminal/vt/colors.d.ts +63 -0
- package/dist/terminal/vt/colors.d.ts.map +1 -0
- package/dist/terminal/vt/colors.js +203 -0
- package/dist/terminal/vt/colors.js.map +1 -0
- package/dist/terminal/vt/diff.d.ts +117 -0
- package/dist/terminal/vt/diff.d.ts.map +1 -0
- package/dist/terminal/vt/diff.js +358 -0
- package/dist/terminal/vt/diff.js.map +1 -0
- package/dist/terminal/vt/fonts.d.ts +92 -0
- package/dist/terminal/vt/fonts.d.ts.map +1 -0
- package/dist/terminal/vt/fonts.js +178 -0
- package/dist/terminal/vt/fonts.js.map +1 -0
- package/dist/terminal/vt/index.d.ts +78 -0
- package/dist/terminal/vt/index.d.ts.map +1 -0
- package/dist/terminal/vt/index.js +312 -0
- package/dist/terminal/vt/index.js.map +1 -0
- package/dist/terminal/vt/keys.d.ts +74 -0
- package/dist/terminal/vt/keys.d.ts.map +1 -0
- package/dist/terminal/vt/keys.js +309 -0
- package/dist/terminal/vt/keys.js.map +1 -0
- package/dist/terminal/vt/mouse.d.ts +44 -0
- package/dist/terminal/vt/mouse.d.ts.map +1 -0
- package/dist/terminal/vt/mouse.js +106 -0
- package/dist/terminal/vt/mouse.js.map +1 -0
- package/dist/terminal/vt/node.d.ts +246 -0
- package/dist/terminal/vt/node.d.ts.map +1 -0
- package/dist/terminal/vt/node.js +1068 -0
- package/dist/terminal/vt/node.js.map +1 -0
- package/dist/terminal/vt/pty.d.ts +81 -0
- package/dist/terminal/vt/pty.d.ts.map +1 -0
- package/dist/terminal/vt/pty.js +201 -0
- package/dist/terminal/vt/pty.js.map +1 -0
- package/dist/terminal/vt/renderer.d.ts +179 -0
- package/dist/terminal/vt/renderer.d.ts.map +1 -0
- package/dist/terminal/vt/renderer.js +357 -0
- package/dist/terminal/vt/renderer.js.map +1 -0
- package/dist/terminal/vt/timers.d.ts +6 -0
- package/dist/terminal/vt/timers.d.ts.map +1 -0
- package/dist/terminal/vt/timers.js +16 -0
- package/dist/terminal/vt/timers.js.map +1 -0
- package/dist/terminal/vt/xterm.d.ts +142 -0
- package/dist/terminal/vt/xterm.d.ts.map +1 -0
- package/dist/terminal/vt/xterm.js +32 -0
- package/dist/terminal/vt/xterm.js.map +1 -0
- package/dist/terminal-output/hx.d.ts +24 -0
- package/dist/terminal-output/hx.d.ts.map +1 -0
- package/dist/terminal-output/hx.js +25 -0
- package/dist/terminal-output/hx.js.map +1 -0
- package/dist/terminal-output/index.d.ts +92 -0
- package/dist/terminal-output/index.d.ts.map +1 -0
- package/dist/terminal-output/index.js +179 -0
- package/dist/terminal-output/index.js.map +1 -0
- package/dist/terminal-output/runs.d.ts +27 -0
- package/dist/terminal-output/runs.d.ts.map +1 -0
- package/dist/terminal-output/runs.js +66 -0
- package/dist/terminal-output/runs.js.map +1 -0
- package/dist/three/canvas.d.ts +46 -0
- package/dist/three/canvas.d.ts.map +1 -0
- package/dist/three/canvas.js +305 -0
- package/dist/three/canvas.js.map +1 -0
- package/dist/three/events.d.ts +64 -0
- package/dist/three/events.d.ts.map +1 -0
- package/dist/three/events.js +146 -0
- package/dist/three/events.js.map +1 -0
- package/dist/three/geometries.d.ts +89 -0
- package/dist/three/geometries.d.ts.map +1 -0
- package/dist/three/geometries.js +345 -0
- package/dist/three/geometries.js.map +1 -0
- package/dist/three/globals.d.ts +7 -0
- package/dist/three/globals.d.ts.map +1 -0
- package/dist/three/globals.js +20 -0
- package/dist/three/globals.js.map +1 -0
- package/dist/three/hx.d.ts +9 -0
- package/dist/three/hx.d.ts.map +1 -0
- package/dist/three/hx.js +10 -0
- package/dist/three/hx.js.map +1 -0
- package/dist/three/index.d.ts +22 -0
- package/dist/three/index.d.ts.map +1 -0
- package/dist/three/index.js +24 -0
- package/dist/three/index.js.map +1 -0
- package/dist/three/jsx-dev-runtime.d.ts +19 -0
- package/dist/three/jsx-dev-runtime.d.ts.map +1 -0
- package/dist/three/jsx-dev-runtime.js +2 -0
- package/dist/three/jsx-dev-runtime.js.map +1 -0
- package/dist/three/jsx-runtime.d.ts +19 -0
- package/dist/three/jsx-runtime.d.ts.map +1 -0
- package/dist/three/jsx-runtime.js +2 -0
- package/dist/three/jsx-runtime.js.map +1 -0
- package/dist/three/jsx.d.ts +198 -0
- package/dist/three/jsx.d.ts.map +1 -0
- package/dist/three/jsx.js +2 -0
- package/dist/three/jsx.js.map +1 -0
- package/dist/three/materials.d.ts +125 -0
- package/dist/three/materials.d.ts.map +1 -0
- package/dist/three/materials.js +229 -0
- package/dist/three/materials.js.map +1 -0
- package/dist/three/math.d.ts +146 -0
- package/dist/three/math.d.ts.map +1 -0
- package/dist/three/math.js +464 -0
- package/dist/three/math.js.map +1 -0
- package/dist/three/objects.d.ts +185 -0
- package/dist/three/objects.d.ts.map +1 -0
- package/dist/three/objects.js +309 -0
- package/dist/three/objects.js.map +1 -0
- package/dist/three/passes.d.ts +54 -0
- package/dist/three/passes.d.ts.map +1 -0
- package/dist/three/passes.js +78 -0
- package/dist/three/passes.js.map +1 -0
- package/dist/three/postprocess.d.ts +85 -0
- package/dist/three/postprocess.d.ts.map +1 -0
- package/dist/three/postprocess.js +503 -0
- package/dist/three/postprocess.js.map +1 -0
- package/dist/three/raycast.d.ts +24 -0
- package/dist/three/raycast.d.ts.map +1 -0
- package/dist/three/raycast.js +138 -0
- package/dist/three/raycast.js.map +1 -0
- package/dist/three/reconciler.d.ts +48 -0
- package/dist/three/reconciler.d.ts.map +1 -0
- package/dist/three/reconciler.js +416 -0
- package/dist/three/reconciler.js.map +1 -0
- package/dist/three/renderer-direct.d.ts +102 -0
- package/dist/three/renderer-direct.d.ts.map +1 -0
- package/dist/three/renderer-direct.js +782 -0
- package/dist/three/renderer-direct.js.map +1 -0
- package/dist/three/renderer-indirect.d.ts +68 -0
- package/dist/three/renderer-indirect.d.ts.map +1 -0
- package/dist/three/renderer-indirect.js +438 -0
- package/dist/three/renderer-indirect.js.map +1 -0
- package/dist/three/store.d.ts +81 -0
- package/dist/three/store.d.ts.map +1 -0
- package/dist/three/store.js +110 -0
- package/dist/three/store.js.map +1 -0
- package/dist/timeline/hx.d.ts +18 -0
- package/dist/timeline/hx.d.ts.map +1 -0
- package/dist/timeline/hx.js +10 -0
- package/dist/timeline/hx.js.map +1 -0
- package/dist/timeline/index.d.ts +152 -0
- package/dist/timeline/index.d.ts.map +1 -0
- package/dist/timeline/index.js +383 -0
- package/dist/timeline/index.js.map +1 -0
- package/dist/tray-host/hx.d.ts +24 -0
- package/dist/tray-host/hx.d.ts.map +1 -0
- package/dist/tray-host/hx.js +25 -0
- package/dist/tray-host/hx.js.map +1 -0
- package/dist/tray-host/index.d.ts +110 -0
- package/dist/tray-host/index.d.ts.map +1 -0
- package/dist/tray-host/index.js +191 -0
- package/dist/tray-host/index.js.map +1 -0
- package/dist/tray-host/manager.d.ts +137 -0
- package/dist/tray-host/manager.d.ts.map +1 -0
- package/dist/tray-host/manager.js +462 -0
- package/dist/tray-host/manager.js.map +1 -0
- package/dist/tray-host/notify.d.ts +22 -0
- package/dist/tray-host/notify.d.ts.map +1 -0
- package/dist/tray-host/notify.js +74 -0
- package/dist/tray-host/notify.js.map +1 -0
- package/dist/tray-host/protocol.d.ts +106 -0
- package/dist/tray-host/protocol.d.ts.map +1 -0
- package/dist/tray-host/protocol.js +191 -0
- package/dist/tray-host/protocol.js.map +1 -0
- package/dist/tree/hx.d.ts +24 -0
- package/dist/tree/hx.d.ts.map +1 -0
- package/dist/tree/hx.js +25 -0
- package/dist/tree/hx.js.map +1 -0
- package/dist/tree/index.d.ts +221 -0
- package/dist/tree/index.d.ts.map +1 -0
- package/dist/tree/index.js +751 -0
- package/dist/tree/index.js.map +1 -0
- package/dist/tree/internal.d.ts +18 -0
- package/dist/tree/internal.d.ts.map +1 -0
- package/dist/tree/internal.js +66 -0
- package/dist/tree/internal.js.map +1 -0
- package/dist/tree/rows.d.ts +177 -0
- package/dist/tree/rows.d.ts.map +1 -0
- package/dist/tree/rows.js +179 -0
- package/dist/tree/rows.js.map +1 -0
- package/package.json +166 -12
- package/src/ansi/cast.ts +159 -0
- package/src/ansi/index.ts +53 -0
- package/src/ansi/palette.ts +226 -0
- package/src/ansi/parse.ts +780 -0
- package/src/ansi/sgr.ts +380 -0
- package/src/ansi/utf8.ts +84 -0
- package/src/calendar/Calendar.ts +744 -0
- package/src/calendar/DatePicker.ts +368 -0
- package/src/calendar/dates.ts +307 -0
- package/src/calendar/index.ts +51 -0
- package/src/charts/components.ts +864 -0
- package/src/charts/data.ts +776 -0
- package/src/charts/hx.ts +39 -0
- package/src/charts/index.ts +99 -0
- package/src/charts/node.ts +932 -0
- package/src/charts/render.ts +982 -0
- package/src/charts/scale.ts +214 -0
- package/src/charts/spec.ts +122 -0
- package/src/charts/timers.ts +24 -0
- package/src/code/hx.ts +51 -0
- package/src/code/index.ts +174 -0
- package/src/code-editor/completion.ts +161 -0
- package/src/code-editor/doc.ts +198 -0
- package/src/code-editor/hx.ts +26 -0
- package/src/code-editor/index.ts +615 -0
- package/src/code-editor/node.ts +1926 -0
- package/src/code-language/hljs.ts +302 -0
- package/src/code-language/index.ts +51 -0
- package/src/code-language/languages/glsl.ts +120 -0
- package/src/code-language/languages/javascript.ts +419 -0
- package/src/code-language/languages/json.ts +72 -0
- package/src/code-language/languages/shell.ts +221 -0
- package/src/code-language/languages/sql.ts +165 -0
- package/src/code-language/lezer.ts +190 -0
- package/src/code-language/registry.ts +66 -0
- package/src/code-language/runs.ts +128 -0
- package/src/code-language/stream.ts +306 -0
- package/src/code-language/textmate.ts +134 -0
- package/src/code-language/theme.ts +124 -0
- package/src/code-language/timers.ts +36 -0
- package/src/code-language/types.ts +252 -0
- package/src/codeblock/index.ts +146 -0
- package/src/color-picker/ColorField.ts +333 -0
- package/src/color-picker/ColorPicker.ts +1069 -0
- package/src/color-picker/color.ts +399 -0
- package/src/color-picker/index.ts +50 -0
- package/src/desktop-calendar/eds.ts +484 -0
- package/src/desktop-calendar/ical.ts +119 -0
- package/src/desktop-calendar/index.ts +287 -0
- package/src/embed/client.ts +311 -0
- package/src/embed/host.ts +432 -0
- package/src/embed/index.ts +33 -0
- package/src/embed/timers.ts +32 -0
- package/src/flow/draw.ts +418 -0
- package/src/flow/index.ts +473 -0
- package/src/flow/model.ts +687 -0
- package/src/flow/node.ts +3694 -0
- package/src/flow/paths.ts +403 -0
- package/src/flow/types.ts +634 -0
- package/src/formula/hx.ts +51 -0
- package/src/formula/index.ts +243 -0
- package/src/formula/katex.ts +209 -0
- package/src/formula/layout.ts +876 -0
- package/src/formula/node.ts +467 -0
- package/src/html/controls.ts +244 -0
- package/src/html/css/cascade.ts +606 -0
- package/src/html/css/parse.ts +500 -0
- package/src/html/css/style.ts +1371 -0
- package/src/html/css/ua.ts +174 -0
- package/src/html/css/values.ts +358 -0
- package/src/html/dom.ts +410 -0
- package/src/html/hx.ts +55 -0
- package/src/html/index.ts +545 -0
- package/src/html/layout/block.ts +876 -0
- package/src/html/layout/boxes.ts +981 -0
- package/src/html/layout/flex.ts +297 -0
- package/src/html/layout/floats.ts +125 -0
- package/src/html/layout/inline.ts +870 -0
- package/src/html/layout/table.ts +380 -0
- package/src/html/node.ts +967 -0
- package/src/html/paint.ts +605 -0
- package/src/html/resources.ts +214 -0
- package/src/index.ts +638 -0
- package/src/internal/heights.ts +222 -0
- package/src/internal/hx.ts +53 -0
- package/src/internal/scroll.ts +288 -0
- package/src/internal/text.ts +44 -0
- package/src/internal/timers.ts +44 -0
- package/src/internal/widget.ts +92 -0
- package/src/markdown/ast.ts +163 -0
- package/src/markdown/hx.ts +51 -0
- package/src/markdown/index.ts +686 -0
- package/src/markdown/parse.ts +1037 -0
- package/src/markdown/spans.ts +143 -0
- package/src/media-player/backends.ts +155 -0
- package/src/media-player/control.ts +70 -0
- package/src/media-player/hx.ts +51 -0
- package/src/media-player/index.ts +378 -0
- package/src/media-player/mpv.ts +146 -0
- package/src/media-player/vlc.ts +97 -0
- package/src/richtext/index.ts +42 -0
- package/src/richtext/links.ts +78 -0
- package/src/richtext/menu.ts +49 -0
- package/src/richtext/node.ts +406 -0
- package/src/richtext/runs.ts +253 -0
- package/src/table/hx.ts +51 -0
- package/src/table/index.ts +1270 -0
- package/src/table/rows.ts +275 -0
- package/src/terminal/backends.ts +242 -0
- package/src/terminal/hx.ts +51 -0
- package/src/terminal/index.ts +574 -0
- package/src/terminal/title.ts +172 -0
- package/src/terminal/vt/colors.ts +247 -0
- package/src/terminal/vt/diff.ts +467 -0
- package/src/terminal/vt/fonts.ts +233 -0
- package/src/terminal/vt/index.ts +443 -0
- package/src/terminal/vt/keys.ts +369 -0
- package/src/terminal/vt/mouse.ts +144 -0
- package/src/terminal/vt/node.ts +1242 -0
- package/src/terminal/vt/pty.ts +334 -0
- package/src/terminal/vt/renderer.ts +555 -0
- package/src/terminal/vt/timers.ts +31 -0
- package/src/terminal/vt/xterm.ts +193 -0
- package/src/terminal-output/hx.ts +51 -0
- package/src/terminal-output/index.ts +340 -0
- package/src/terminal-output/runs.ts +79 -0
- package/src/three/canvas.ts +451 -0
- package/src/three/events.ts +197 -0
- package/src/three/geometries.ts +429 -0
- package/src/three/globals.ts +34 -0
- package/src/three/hx.ts +22 -0
- package/src/three/index.ts +98 -0
- package/src/three/jsx-dev-runtime.ts +27 -0
- package/src/three/jsx-runtime.ts +38 -0
- package/src/three/jsx.ts +275 -0
- package/src/three/materials.ts +270 -0
- package/src/three/math.ts +585 -0
- package/src/three/objects.ts +397 -0
- package/src/three/passes.ts +90 -0
- package/src/three/postprocess.ts +677 -0
- package/src/three/raycast.ts +189 -0
- package/src/three/react-reconciler.d.ts +50 -0
- package/src/three/reconciler.ts +624 -0
- package/src/three/renderer-direct.ts +1055 -0
- package/src/three/renderer-indirect.ts +570 -0
- package/src/three/store.ts +207 -0
- package/src/timeline/hx.ts +31 -0
- package/src/timeline/index.ts +603 -0
- package/src/tray-host/hx.ts +51 -0
- package/src/tray-host/index.ts +331 -0
- package/src/tray-host/manager.ts +639 -0
- package/src/tray-host/notify.ts +102 -0
- package/src/tray-host/protocol.ts +235 -0
- package/src/tree/hx.ts +51 -0
- package/src/tree/index.ts +1127 -0
- package/src/tree/internal.ts +87 -0
- package/src/tree/rows.ts +334 -0
- package/src/index.d.ts +0 -2
- package/src/index.js +0 -9
- package/src/sparkline/index.d.ts +0 -29
- package/src/sparkline/index.js +0 -50
- package/src/sparkline/node.js +0 -72
|
@@ -0,0 +1,1055 @@
|
|
|
1
|
+
// The same scene, drawn through OpenGL ES 2 on the GPU — ntk's direct
|
|
2
|
+
// backend, where geometry is a vertex buffer, materials are generated GLSL
|
|
3
|
+
// and a frame is a handful of uniform writes and one draw call per mesh.
|
|
4
|
+
// A port of react-x11's `src/scene3d-shader.js`, reading the object graph.
|
|
5
|
+
//
|
|
6
|
+
// Two deliberate differences from the fixed-function path, both improvements
|
|
7
|
+
// the hardware makes free — and both identical to what three.js does with
|
|
8
|
+
// the same material names:
|
|
9
|
+
//
|
|
10
|
+
// - **lighting is per fragment.** Fixed-function GL shades per vertex, so a
|
|
11
|
+
// large triangle lit by a nearby point light bands visibly.
|
|
12
|
+
// - **the shader is generated for the scene it draws.** A program is
|
|
13
|
+
// compiled per (material kind, lit, textured, light count) so a scene
|
|
14
|
+
// with two lights spends two lights' worth of uniforms — ES 2 guarantees
|
|
15
|
+
// very few of those, and a fixed eight-light shader would not fit the
|
|
16
|
+
// minimum.
|
|
17
|
+
/* The one file-wide `any`: the GL façade (camelCase ES 2). */
|
|
18
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
19
|
+
type GL = any;
|
|
20
|
+
|
|
21
|
+
import type { Mat4 } from './math.js';
|
|
22
|
+
import { identity, invert, multiply, normalMatrix } from './math.js';
|
|
23
|
+
import type { BufferGeometry } from './geometries.js';
|
|
24
|
+
import type {
|
|
25
|
+
Camera,
|
|
26
|
+
Light,
|
|
27
|
+
Mesh,
|
|
28
|
+
Object3D,
|
|
29
|
+
PointLight,
|
|
30
|
+
Primitive,
|
|
31
|
+
Scene,
|
|
32
|
+
SpotLight,
|
|
33
|
+
} from './objects.js';
|
|
34
|
+
import { InstancedMesh } from './objects.js';
|
|
35
|
+
import type { Material, TextureImage, UniformEntry } from './materials.js';
|
|
36
|
+
import {
|
|
37
|
+
ShaderMaterial,
|
|
38
|
+
RawShaderMaterial,
|
|
39
|
+
UNLIT_MATERIALS,
|
|
40
|
+
materialColors,
|
|
41
|
+
} from './materials.js';
|
|
42
|
+
import {
|
|
43
|
+
collectLights,
|
|
44
|
+
instanceMatrix,
|
|
45
|
+
MAX_LIGHTS,
|
|
46
|
+
} from './renderer-indirect.js';
|
|
47
|
+
import type { FrameCamera } from './renderer-indirect.js';
|
|
48
|
+
import { Color } from './math.js';
|
|
49
|
+
import { warn } from './globals.js';
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The default float precision, injected into **both** stages.
|
|
53
|
+
*
|
|
54
|
+
* GLSL ES requires a uniform declared in the vertex and the fragment shader
|
|
55
|
+
* to carry the same precision, and the default differs between them —
|
|
56
|
+
* `highp` in a vertex shader, nothing at all in a fragment shader — so a
|
|
57
|
+
* `uniform float uTime` used in both fails to *link* unless something says
|
|
58
|
+
* otherwise. three.js injects a default for the same reason.
|
|
59
|
+
*/
|
|
60
|
+
const PRECISION = 'precision mediump float;\n';
|
|
61
|
+
|
|
62
|
+
// three.js's attribute and matrix names, so a shader written against r3f —
|
|
63
|
+
// or copied out of a tutorial — compiles here unchanged
|
|
64
|
+
const COMMON_VERTEX_UNIFORMS = `${PRECISION}
|
|
65
|
+
uniform mat4 projectionMatrix;
|
|
66
|
+
uniform mat4 modelViewMatrix;
|
|
67
|
+
uniform mat4 modelMatrix;
|
|
68
|
+
uniform mat3 normalMatrix;
|
|
69
|
+
attribute vec3 position;
|
|
70
|
+
attribute vec3 normal;
|
|
71
|
+
attribute vec2 uv;
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
interface ProgramSpec {
|
|
75
|
+
kind: string;
|
|
76
|
+
lit: boolean;
|
|
77
|
+
textured: boolean;
|
|
78
|
+
lights: number;
|
|
79
|
+
primitive: Primitive;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The vertex/fragment pair for one material configuration. */
|
|
83
|
+
function materialProgramSource({
|
|
84
|
+
kind,
|
|
85
|
+
lit,
|
|
86
|
+
textured,
|
|
87
|
+
lights,
|
|
88
|
+
primitive,
|
|
89
|
+
}: ProgramSpec): { vertex: string; fragment: string } {
|
|
90
|
+
const phong = kind === 'meshPhongMaterial' || kind === 'meshStandardMaterial';
|
|
91
|
+
const points = primitive === 'points';
|
|
92
|
+
const vertex = `${COMMON_VERTEX_UNIFORMS}${points ? 'uniform float pointSize;\n' : ''}
|
|
93
|
+
varying vec3 vNormal;
|
|
94
|
+
varying vec3 vViewPosition;
|
|
95
|
+
varying vec2 vUv;
|
|
96
|
+
void main() {
|
|
97
|
+
vUv = uv;
|
|
98
|
+
vNormal = normalize(normalMatrix * normal);
|
|
99
|
+
vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
|
|
100
|
+
// the direction from the surface toward the eye, which is the origin in
|
|
101
|
+
// view space
|
|
102
|
+
vViewPosition = -mvPosition.xyz;
|
|
103
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
104
|
+
${points ? ' // ES 2 has no glPointSize: a point sprite is sized by the vertex shader\n gl_PointSize = pointSize;\n' : ''}}`;
|
|
105
|
+
|
|
106
|
+
const lighting = lit
|
|
107
|
+
? `
|
|
108
|
+
uniform vec3 ambientColor;
|
|
109
|
+
// w picks the kind: 0 is a direction toward the light, 1 is a position
|
|
110
|
+
uniform vec4 lightPosition[${lights}];
|
|
111
|
+
uniform vec3 lightColor[${lights}];
|
|
112
|
+
uniform vec3 spotDirection[${lights}];
|
|
113
|
+
// x = cos(cutoff) or -1 for a light that is not a spot, y = spot exponent,
|
|
114
|
+
// z = linear attenuation, w unused
|
|
115
|
+
uniform vec4 spotParams[${lights}];
|
|
116
|
+
`
|
|
117
|
+
: '';
|
|
118
|
+
|
|
119
|
+
const lightingBody = lit
|
|
120
|
+
? `
|
|
121
|
+
vec3 normal = normalize(vNormal) * (gl_FrontFacing ? 1.0 : -1.0);
|
|
122
|
+
vec3 viewDir = normalize(vViewPosition);
|
|
123
|
+
vec3 lit = ambientColor * diffuseColor;
|
|
124
|
+
for (int i = 0; i < ${lights}; i++) {
|
|
125
|
+
vec3 toLight;
|
|
126
|
+
float attenuation = 1.0;
|
|
127
|
+
if (lightPosition[i].w == 0.0) {
|
|
128
|
+
toLight = normalize(lightPosition[i].xyz);
|
|
129
|
+
} else {
|
|
130
|
+
vec3 offset = lightPosition[i].xyz - (-vViewPosition);
|
|
131
|
+
float dist = length(offset);
|
|
132
|
+
toLight = offset / max(dist, 0.0001);
|
|
133
|
+
attenuation = 1.0 / (1.0 + spotParams[i].z * dist);
|
|
134
|
+
if (spotParams[i].x >= -0.5) {
|
|
135
|
+
float aligned = dot(-toLight, normalize(spotDirection[i]));
|
|
136
|
+
attenuation *= aligned < spotParams[i].x
|
|
137
|
+
? 0.0
|
|
138
|
+
: pow(aligned, spotParams[i].y);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
float diffuse = max(dot(normal, toLight), 0.0);
|
|
142
|
+
lit += diffuseColor * lightColor[i] * diffuse * attenuation;
|
|
143
|
+
${
|
|
144
|
+
phong
|
|
145
|
+
? ` if (diffuse > 0.0) {
|
|
146
|
+
vec3 halfway = normalize(toLight + viewDir);
|
|
147
|
+
float spec = pow(max(dot(normal, halfway), 0.0), max(shininess, 0.0001));
|
|
148
|
+
lit += specularColor * lightColor[i] * spec * attenuation;
|
|
149
|
+
}`
|
|
150
|
+
: ''
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
vec3 color = lit + emissiveColor;`
|
|
154
|
+
: `
|
|
155
|
+
vec3 color = diffuseColor;`;
|
|
156
|
+
|
|
157
|
+
const fragment = `${PRECISION}uniform vec3 diffuse;
|
|
158
|
+
uniform float opacity;
|
|
159
|
+
uniform vec3 emissive;
|
|
160
|
+
${phong ? 'uniform vec3 specular;\nuniform float shininess;\n' : ''}${textured ? 'uniform sampler2D map;\n' : ''}${lighting}
|
|
161
|
+
varying vec3 vNormal;
|
|
162
|
+
varying vec3 vViewPosition;
|
|
163
|
+
varying vec2 vUv;
|
|
164
|
+
void main() {
|
|
165
|
+
vec4 base = vec4(diffuse, opacity);
|
|
166
|
+
${textured ? ' base *= texture2D(map, vUv);\n' : ''}
|
|
167
|
+
vec3 diffuseColor = base.rgb;
|
|
168
|
+
vec3 emissiveColor = ${lit ? 'emissive' : 'vec3(0.0)'};
|
|
169
|
+
${phong ? ' vec3 specularColor = specular;\n' : ''}${lightingBody}
|
|
170
|
+
gl_FragColor = vec4(color, base.a);
|
|
171
|
+
}`;
|
|
172
|
+
|
|
173
|
+
return { vertex, fragment };
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Shader sources for a `<shaderMaterial>`, with three.js's prelude. */
|
|
177
|
+
function userProgramSource(
|
|
178
|
+
material: ShaderMaterial,
|
|
179
|
+
raw: boolean,
|
|
180
|
+
): { vertex: string; fragment: string } {
|
|
181
|
+
const vertex = raw
|
|
182
|
+
? material.vertexShader
|
|
183
|
+
: `${COMMON_VERTEX_UNIFORMS}uniform vec3 cameraPosition;
|
|
184
|
+
${material.vertexShader}`;
|
|
185
|
+
const fragment = raw
|
|
186
|
+
? material.fragmentShader
|
|
187
|
+
: `${PRECISION}${material.fragmentShader}`;
|
|
188
|
+
return { vertex, fragment };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** The ES 2 draw mode a drawable's primitive assembles into. */
|
|
192
|
+
function PRIMITIVE_MODE(gl: GL, primitive: Primitive): number {
|
|
193
|
+
switch (primitive) {
|
|
194
|
+
case 'points':
|
|
195
|
+
return gl.POINTS;
|
|
196
|
+
case 'lines':
|
|
197
|
+
return gl.LINES;
|
|
198
|
+
case 'lineStrip':
|
|
199
|
+
return gl.LINE_STRIP;
|
|
200
|
+
case 'lineLoop':
|
|
201
|
+
return gl.LINE_LOOP;
|
|
202
|
+
default:
|
|
203
|
+
return gl.TRIANGLES;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const isTypedArray = (v: unknown): v is Float32Array =>
|
|
208
|
+
ArrayBuffer.isView(v) && !(v instanceof DataView);
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* A `<shaderMaterial>` uniform value, sent with whichever setter its
|
|
212
|
+
* JavaScript type implies. Matrices need a typed array or a 9/16-long
|
|
213
|
+
* array, since nothing else says "this is a mat3, not three vec3s".
|
|
214
|
+
*/
|
|
215
|
+
function setUniform(gl: GL, location: unknown, value: unknown): void {
|
|
216
|
+
if (location === null || location === -1 || value === undefined) return;
|
|
217
|
+
if (typeof value === 'number') return gl.uniform1f(location, value);
|
|
218
|
+
if (typeof value === 'boolean') return gl.uniform1i(location, value ? 1 : 0);
|
|
219
|
+
if (value instanceof Color) {
|
|
220
|
+
return gl.uniform3fv(location, new Float32Array(value.toArray()));
|
|
221
|
+
}
|
|
222
|
+
if (isTypedArray(value) || Array.isArray(value)) {
|
|
223
|
+
const array =
|
|
224
|
+
value instanceof Float32Array
|
|
225
|
+
? value
|
|
226
|
+
: new Float32Array(value as ArrayLike<number>);
|
|
227
|
+
switch (array.length) {
|
|
228
|
+
case 2:
|
|
229
|
+
return gl.uniform2fv(location, array);
|
|
230
|
+
case 3:
|
|
231
|
+
return gl.uniform3fv(location, array);
|
|
232
|
+
case 4:
|
|
233
|
+
return gl.uniform4fv(location, array);
|
|
234
|
+
case 9:
|
|
235
|
+
return gl.uniformMatrix3fv(location, false, array);
|
|
236
|
+
case 16:
|
|
237
|
+
return gl.uniformMatrix4fv(location, false, array);
|
|
238
|
+
default:
|
|
239
|
+
return gl.uniform1fv(location, array);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
interface GeometryBuffers {
|
|
245
|
+
version: number;
|
|
246
|
+
position: unknown;
|
|
247
|
+
normal: unknown;
|
|
248
|
+
uv: unknown;
|
|
249
|
+
index: unknown;
|
|
250
|
+
count: number;
|
|
251
|
+
/** Lazily built unique-edge index — how wireframe draws where ES 2 has no
|
|
252
|
+
* `glPolygonMode`. Rides the entry so it releases and rebuilds with it. */
|
|
253
|
+
wire: { index: unknown; count: number } | null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface CompiledProgram {
|
|
257
|
+
program: unknown;
|
|
258
|
+
uniform(name: string): unknown;
|
|
259
|
+
attribute(name: string): number;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
interface LightUniforms {
|
|
263
|
+
count: number;
|
|
264
|
+
ambient: Float32Array;
|
|
265
|
+
position: Float32Array;
|
|
266
|
+
color: Float32Array;
|
|
267
|
+
spotDirection: Float32Array;
|
|
268
|
+
spotParams: Float32Array;
|
|
269
|
+
lit: boolean;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Per-surface GPU state for the direct backend: one buffer set per geometry,
|
|
274
|
+
* one program per material configuration, one texture per image.
|
|
275
|
+
*/
|
|
276
|
+
export class DirectRenderer {
|
|
277
|
+
readonly backend = 'direct';
|
|
278
|
+
|
|
279
|
+
private geometries = new Map<
|
|
280
|
+
BufferGeometry,
|
|
281
|
+
Map<'shaded' | 'flat', GeometryBuffers>
|
|
282
|
+
>();
|
|
283
|
+
private programs = new Map<string, { program: unknown } | CompiledProgram>();
|
|
284
|
+
private textures = new Map<
|
|
285
|
+
TextureImage,
|
|
286
|
+
{ texture: unknown; unit: number }
|
|
287
|
+
>();
|
|
288
|
+
private failed = new Set<string>();
|
|
289
|
+
private wireWarned = new WeakSet<BufferGeometry>();
|
|
290
|
+
private _usable: boolean | undefined;
|
|
291
|
+
|
|
292
|
+
camera: FrameCamera | null = null;
|
|
293
|
+
/** A shader that will not build is reported here, once per source. */
|
|
294
|
+
onError: ((err: Error & { code?: string }) => void) | null = null;
|
|
295
|
+
|
|
296
|
+
render(
|
|
297
|
+
gl: GL,
|
|
298
|
+
scene: Scene,
|
|
299
|
+
camera: Camera,
|
|
300
|
+
size: { width: number; height: number },
|
|
301
|
+
): boolean {
|
|
302
|
+
const roots = scene.children.filter((c) => c.isObject3D);
|
|
303
|
+
if (roots.length === 0) return false;
|
|
304
|
+
if (!this.usable(gl)) return false;
|
|
305
|
+
|
|
306
|
+
gl.enable(gl.DEPTH_TEST);
|
|
307
|
+
gl.depthFunc(gl.LEQUAL);
|
|
308
|
+
|
|
309
|
+
const projection = camera.projectionMatrix(size.width, size.height);
|
|
310
|
+
const view = camera.viewMatrix();
|
|
311
|
+
this.camera = { projection, view, width: size.width, height: size.height };
|
|
312
|
+
|
|
313
|
+
const lights = this.lightUniforms(collectLights(roots, identity()), view);
|
|
314
|
+
|
|
315
|
+
for (const node of roots) this.drawObject(gl, node, identity(), lights);
|
|
316
|
+
return true;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Does this context have the GL entry points a material needs? It can
|
|
321
|
+
* genuinely lack them: ntk passes the `x11-dri` addon's table straight
|
|
322
|
+
* through, so the context is only as complete as the addon installed. The
|
|
323
|
+
* failure without this check is a `TypeError` from inside a draw call,
|
|
324
|
+
* which names nothing a consumer could act on.
|
|
325
|
+
*/
|
|
326
|
+
private usable(gl: GL): boolean {
|
|
327
|
+
if (this._usable !== undefined) return this._usable;
|
|
328
|
+
const missing = [
|
|
329
|
+
'createBuffer',
|
|
330
|
+
'bufferData',
|
|
331
|
+
'createShader',
|
|
332
|
+
'linkProgram',
|
|
333
|
+
'uniform3fv',
|
|
334
|
+
'uniformMatrix4fv',
|
|
335
|
+
'uniformMatrix3fv',
|
|
336
|
+
'drawElements',
|
|
337
|
+
'blendFunc',
|
|
338
|
+
'depthMask',
|
|
339
|
+
].filter((name) => typeof gl[name] !== 'function');
|
|
340
|
+
this._usable = missing.length === 0;
|
|
341
|
+
if (!this._usable) {
|
|
342
|
+
this.report(
|
|
343
|
+
'gl-incomplete',
|
|
344
|
+
`this GL context is missing ${missing.join(', ')}, so the 3D scene ` +
|
|
345
|
+
'cannot be drawn. The direct backend exposes whatever the x11-dri ' +
|
|
346
|
+
'addon provides; check with `npm ls x11-dri`.',
|
|
347
|
+
'GL_CONTEXT_INCOMPLETE',
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return this._usable;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Lights as flat arrays in view space, which is where the shader works.
|
|
355
|
+
* Transformed here rather than in the shader for the same reason
|
|
356
|
+
* fixed-function GL transforms them when they are set: once per frame
|
|
357
|
+
* beats once per fragment.
|
|
358
|
+
*/
|
|
359
|
+
private lightUniforms(
|
|
360
|
+
lights: { node: Light; world: Mat4 }[],
|
|
361
|
+
view: Mat4,
|
|
362
|
+
): LightUniforms {
|
|
363
|
+
const ambient = [0, 0, 0];
|
|
364
|
+
const used: {
|
|
365
|
+
node: Light;
|
|
366
|
+
intensity: number;
|
|
367
|
+
color: [number, number, number];
|
|
368
|
+
world: Mat4;
|
|
369
|
+
}[] = [];
|
|
370
|
+
for (const light of lights) {
|
|
371
|
+
const { node } = light;
|
|
372
|
+
const intensity = node.intensity;
|
|
373
|
+
const { r, g, b } = node.color;
|
|
374
|
+
if ((node as { isAmbientLight?: boolean }).isAmbientLight) {
|
|
375
|
+
ambient[0] += r * intensity;
|
|
376
|
+
ambient[1] += g * intensity;
|
|
377
|
+
ambient[2] += b * intensity;
|
|
378
|
+
continue;
|
|
379
|
+
}
|
|
380
|
+
if (used.length >= MAX_LIGHTS) continue;
|
|
381
|
+
used.push({ node, intensity, color: [r, g, b], world: light.world });
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
const count = used.length;
|
|
385
|
+
const position = new Float32Array(Math.max(1, count) * 4);
|
|
386
|
+
const color = new Float32Array(Math.max(1, count) * 3);
|
|
387
|
+
const spotDirection = new Float32Array(Math.max(1, count) * 3);
|
|
388
|
+
const spotParams = new Float32Array(Math.max(1, count) * 4);
|
|
389
|
+
|
|
390
|
+
used.forEach((light, i) => {
|
|
391
|
+
const { node, intensity, world } = light;
|
|
392
|
+
const wx = world[12];
|
|
393
|
+
const wy = world[13];
|
|
394
|
+
const wz = world[14];
|
|
395
|
+
const directional = (node as { isDirectionalLight?: boolean })
|
|
396
|
+
.isDirectionalLight;
|
|
397
|
+
// view-space position (w = 1) or direction toward the light (w = 0)
|
|
398
|
+
const w = directional ? 0 : 1;
|
|
399
|
+
position[i * 4] =
|
|
400
|
+
view[0] * wx + view[4] * wy + view[8] * wz + view[12] * w;
|
|
401
|
+
position[i * 4 + 1] =
|
|
402
|
+
view[1] * wx + view[5] * wy + view[9] * wz + view[13] * w;
|
|
403
|
+
position[i * 4 + 2] =
|
|
404
|
+
view[2] * wx + view[6] * wy + view[10] * wz + view[14] * w;
|
|
405
|
+
position[i * 4 + 3] = w;
|
|
406
|
+
color[i * 3] = light.color[0] * intensity;
|
|
407
|
+
color[i * 3 + 1] = light.color[1] * intensity;
|
|
408
|
+
color[i * 3 + 2] = light.color[2] * intensity;
|
|
409
|
+
|
|
410
|
+
const distance = (node as PointLight).distance ?? 0;
|
|
411
|
+
spotParams[i * 4 + 2] = distance > 0 ? 1 / distance : 0;
|
|
412
|
+
if ((node as { isSpotLight?: boolean }).isSpotLight) {
|
|
413
|
+
const spot = node as SpotLight;
|
|
414
|
+
const dx = spot.target.x - wx;
|
|
415
|
+
const dy = spot.target.y - wy;
|
|
416
|
+
const dz = spot.target.z - wz;
|
|
417
|
+
const length = Math.hypot(dx, dy, dz) || 1;
|
|
418
|
+
// the direction is a vector, so the translation column does not apply
|
|
419
|
+
spotDirection[i * 3] =
|
|
420
|
+
(view[0] * dx + view[4] * dy + view[8] * dz) / length;
|
|
421
|
+
spotDirection[i * 3 + 1] =
|
|
422
|
+
(view[1] * dx + view[5] * dy + view[9] * dz) / length;
|
|
423
|
+
spotDirection[i * 3 + 2] =
|
|
424
|
+
(view[2] * dx + view[6] * dy + view[10] * dz) / length;
|
|
425
|
+
spotParams[i * 4] = Math.cos(Math.min(Math.PI / 2, spot.angle));
|
|
426
|
+
spotParams[i * 4 + 1] = spot.penumbra * 128;
|
|
427
|
+
} else {
|
|
428
|
+
spotParams[i * 4] = -1; // not a spot
|
|
429
|
+
spotParams[i * 4 + 1] = 0;
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
return {
|
|
434
|
+
count,
|
|
435
|
+
ambient: new Float32Array(ambient),
|
|
436
|
+
position,
|
|
437
|
+
color,
|
|
438
|
+
spotDirection,
|
|
439
|
+
spotParams,
|
|
440
|
+
lit: count > 0 || ambient.some((c) => c > 0),
|
|
441
|
+
};
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
private drawObject(
|
|
445
|
+
gl: GL,
|
|
446
|
+
node: Object3D,
|
|
447
|
+
parentWorld: Mat4,
|
|
448
|
+
lights: LightUniforms,
|
|
449
|
+
): void {
|
|
450
|
+
if (!node.visible) return;
|
|
451
|
+
const world = multiply(parentWorld, node.localMatrix());
|
|
452
|
+
node.__world = world;
|
|
453
|
+
if ((node as Mesh).isMesh) this.drawMesh(gl, node as Mesh, world, lights);
|
|
454
|
+
for (const child of node.children) {
|
|
455
|
+
if (child.isObject3D) this.drawObject(gl, child, world, lights);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
private drawMesh(
|
|
460
|
+
gl: GL,
|
|
461
|
+
mesh: Mesh,
|
|
462
|
+
world: Mat4,
|
|
463
|
+
lights: LightUniforms,
|
|
464
|
+
): void {
|
|
465
|
+
const geometry = mesh.geometry;
|
|
466
|
+
if (!geometry) return;
|
|
467
|
+
const primitive = mesh.primitive;
|
|
468
|
+
const buffers = this.geometryFor(gl, geometry, primitive);
|
|
469
|
+
if (!buffers) return;
|
|
470
|
+
|
|
471
|
+
const material = mesh.material;
|
|
472
|
+
const program = this.programFor(gl, material, lights, primitive);
|
|
473
|
+
if (!program) return;
|
|
474
|
+
|
|
475
|
+
gl.useProgram(program.program);
|
|
476
|
+
const applied = this.applyMaterial(gl, program, material, lights);
|
|
477
|
+
|
|
478
|
+
gl.uniformMatrix4fv(
|
|
479
|
+
program.uniform('projectionMatrix'),
|
|
480
|
+
false,
|
|
481
|
+
this.camera!.projection,
|
|
482
|
+
);
|
|
483
|
+
gl.uniformMatrix4fv(
|
|
484
|
+
program.uniform('viewMatrix'),
|
|
485
|
+
false,
|
|
486
|
+
this.camera!.view,
|
|
487
|
+
);
|
|
488
|
+
this.bindAttributes(gl, program, buffers);
|
|
489
|
+
|
|
490
|
+
const wire =
|
|
491
|
+
primitive === 'triangles' && material?.wireframe
|
|
492
|
+
? this.wireframeFor(gl, geometry, buffers)
|
|
493
|
+
: null;
|
|
494
|
+
|
|
495
|
+
if (!(mesh instanceof InstancedMesh)) {
|
|
496
|
+
this.drawOne(gl, program, buffers, world, primitive, wire);
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// One upload, many transforms. Neither backend does GPU instancing —
|
|
501
|
+
// ES 2 guarantees none and GLX encodes none — so what this saves is the
|
|
502
|
+
// geometry, not the draw calls: each instance is a matrix and a draw.
|
|
503
|
+
const diffuse = program.uniform('diffuse');
|
|
504
|
+
for (const instance of mesh.instances) {
|
|
505
|
+
if (instance.color) {
|
|
506
|
+
const c = new Color(instance.color as never);
|
|
507
|
+
gl.uniform3fv(diffuse, new Float32Array([c.r, c.g, c.b]));
|
|
508
|
+
} else if (applied) {
|
|
509
|
+
gl.uniform3fv(diffuse, new Float32Array(applied.color));
|
|
510
|
+
}
|
|
511
|
+
this.drawOne(
|
|
512
|
+
gl,
|
|
513
|
+
program,
|
|
514
|
+
buffers,
|
|
515
|
+
multiply(world, instanceMatrix(instance)),
|
|
516
|
+
primitive,
|
|
517
|
+
wire,
|
|
518
|
+
);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/** One draw of `buffers` at `world`, as whichever primitive. */
|
|
523
|
+
private drawOne(
|
|
524
|
+
gl: GL,
|
|
525
|
+
program: CompiledProgram,
|
|
526
|
+
buffers: GeometryBuffers,
|
|
527
|
+
world: Mat4,
|
|
528
|
+
primitive: Primitive,
|
|
529
|
+
wire: { index: unknown; count: number } | null = null,
|
|
530
|
+
): void {
|
|
531
|
+
const modelView = multiply(this.camera!.view, world);
|
|
532
|
+
gl.uniformMatrix4fv(program.uniform('modelViewMatrix'), false, modelView);
|
|
533
|
+
gl.uniformMatrix4fv(program.uniform('modelMatrix'), false, world);
|
|
534
|
+
gl.uniformMatrix3fv(
|
|
535
|
+
program.uniform('normalMatrix'),
|
|
536
|
+
false,
|
|
537
|
+
normalMatrix(modelView),
|
|
538
|
+
);
|
|
539
|
+
if (wire) {
|
|
540
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, wire.index);
|
|
541
|
+
gl.drawElements(gl.LINES, wire.count, gl.UNSIGNED_SHORT, 0);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
const mode = PRIMITIVE_MODE(gl, primitive);
|
|
545
|
+
if (buffers.index) {
|
|
546
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.index);
|
|
547
|
+
gl.drawElements(mode, buffers.count, gl.UNSIGNED_SHORT, 0);
|
|
548
|
+
} else {
|
|
549
|
+
gl.drawArrays(mode, 0, buffers.count);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private bindAttributes(
|
|
554
|
+
gl: GL,
|
|
555
|
+
program: CompiledProgram,
|
|
556
|
+
buffers: GeometryBuffers,
|
|
557
|
+
): void {
|
|
558
|
+
for (const [name, buffer, size] of [
|
|
559
|
+
['position', buffers.position, 3],
|
|
560
|
+
['normal', buffers.normal, 3],
|
|
561
|
+
['uv', buffers.uv, 2],
|
|
562
|
+
] as const) {
|
|
563
|
+
const location = program.attribute(name);
|
|
564
|
+
if (location < 0) continue;
|
|
565
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
566
|
+
gl.enableVertexAttribArray(location);
|
|
567
|
+
gl.vertexAttribPointer(location, size, gl.FLOAT, false, 0, 0);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Upload a geometry once and keep it on the GPU. The indirect backend
|
|
573
|
+
* compiles geometry into a display list for exactly the same reason —
|
|
574
|
+
* never send the vertices twice — and the cache is keyed the same way, by
|
|
575
|
+
* object identity and version.
|
|
576
|
+
*/
|
|
577
|
+
private geometryFor(
|
|
578
|
+
gl: GL,
|
|
579
|
+
node: BufferGeometry,
|
|
580
|
+
primitive: Primitive,
|
|
581
|
+
): GeometryBuffers | null {
|
|
582
|
+
// Keyed by primitive as well as by node: points and lines want no
|
|
583
|
+
// normals and ignore the triangle index, so the same geometry used both
|
|
584
|
+
// ways is genuinely two uploads.
|
|
585
|
+
const shaded = primitive === 'triangles';
|
|
586
|
+
const key = shaded ? 'shaded' : 'flat';
|
|
587
|
+
let perPrimitive = this.geometries.get(node);
|
|
588
|
+
if (!perPrimitive) this.geometries.set(node, (perPrimitive = new Map()));
|
|
589
|
+
const cached = perPrimitive.get(key);
|
|
590
|
+
if (cached && cached.version === node.version) return cached;
|
|
591
|
+
if (cached) this.releaseGeometry(gl, cached);
|
|
592
|
+
|
|
593
|
+
const built = node.data({ normals: shaded });
|
|
594
|
+
const { positions, normals, uvs } = built;
|
|
595
|
+
// points are one dot per vertex; running a triangle index over them
|
|
596
|
+
// would draw every shared vertex again
|
|
597
|
+
const index = primitive === 'points' ? null : built.index;
|
|
598
|
+
const vertexCount = positions.length / 3;
|
|
599
|
+
if (vertexCount === 0) return null;
|
|
600
|
+
|
|
601
|
+
const upload = (data: number[], fallbackLength: number) => {
|
|
602
|
+
const buffer = gl.createBuffer();
|
|
603
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
604
|
+
const array = data.length
|
|
605
|
+
? new Float32Array(data)
|
|
606
|
+
: new Float32Array(fallbackLength);
|
|
607
|
+
gl.bufferData(gl.ARRAY_BUFFER, array, gl.STATIC_DRAW);
|
|
608
|
+
return buffer;
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
const entry: GeometryBuffers = {
|
|
612
|
+
version: node.version,
|
|
613
|
+
position: upload(positions, vertexCount * 3),
|
|
614
|
+
normal: upload(normals, vertexCount * 3),
|
|
615
|
+
uv: upload(uvs, vertexCount * 2),
|
|
616
|
+
index: null,
|
|
617
|
+
count: vertexCount,
|
|
618
|
+
wire: null,
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
if (index && index.length) {
|
|
622
|
+
// ES 2 indices are 16-bit. A geometry with more vertices than that is
|
|
623
|
+
// expanded to a flat triangle soup rather than quietly wrapping —
|
|
624
|
+
// sphereGeometry with enough segments really does get there.
|
|
625
|
+
if (vertexCount > 0xffff) {
|
|
626
|
+
const flat = {
|
|
627
|
+
positions: [] as number[],
|
|
628
|
+
normals: [] as number[],
|
|
629
|
+
uvs: [] as number[],
|
|
630
|
+
};
|
|
631
|
+
for (const i of index) {
|
|
632
|
+
flat.positions.push(
|
|
633
|
+
positions[i * 3],
|
|
634
|
+
positions[i * 3 + 1],
|
|
635
|
+
positions[i * 3 + 2],
|
|
636
|
+
);
|
|
637
|
+
flat.normals.push(
|
|
638
|
+
normals[i * 3],
|
|
639
|
+
normals[i * 3 + 1],
|
|
640
|
+
normals[i * 3 + 2],
|
|
641
|
+
);
|
|
642
|
+
flat.uvs.push(uvs[i * 2], uvs[i * 2 + 1]);
|
|
643
|
+
}
|
|
644
|
+
this.releaseGeometry(gl, entry);
|
|
645
|
+
entry.position = upload(flat.positions, 0);
|
|
646
|
+
entry.normal = upload(flat.normals, 0);
|
|
647
|
+
entry.uv = upload(flat.uvs, 0);
|
|
648
|
+
entry.index = null;
|
|
649
|
+
entry.count = index.length;
|
|
650
|
+
} else {
|
|
651
|
+
entry.index = gl.createBuffer();
|
|
652
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, entry.index);
|
|
653
|
+
gl.bufferData(
|
|
654
|
+
gl.ELEMENT_ARRAY_BUFFER,
|
|
655
|
+
new Uint16Array(index),
|
|
656
|
+
gl.STATIC_DRAW,
|
|
657
|
+
);
|
|
658
|
+
entry.count = index.length;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
perPrimitive.set(key, entry);
|
|
663
|
+
return entry;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
private releaseGeometry(gl: GL, entry: GeometryBuffers): void {
|
|
667
|
+
for (const key of ['position', 'normal', 'uv', 'index'] as const) {
|
|
668
|
+
if (entry[key]) gl.deleteBuffer(entry[key]);
|
|
669
|
+
entry[key] = null;
|
|
670
|
+
}
|
|
671
|
+
if (entry.wire) {
|
|
672
|
+
gl.deleteBuffer(entry.wire.index);
|
|
673
|
+
entry.wire = null;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* The unique-edge index that draws `node` as a wireframe. The indirect
|
|
679
|
+
* backend flips one server-side switch (`PolygonMode LINE`); ES 2 has no
|
|
680
|
+
* polygon modes, so this backend does what three.js's `WireframeGeometry`
|
|
681
|
+
* does — every triangle edge once, drawn as `LINES` over the same vertex
|
|
682
|
+
* buffers. Built on first use, cached until the geometry rebuilds.
|
|
683
|
+
*/
|
|
684
|
+
private wireframeFor(
|
|
685
|
+
gl: GL,
|
|
686
|
+
node: BufferGeometry,
|
|
687
|
+
buffers: GeometryBuffers,
|
|
688
|
+
): { index: unknown; count: number } | null {
|
|
689
|
+
if (buffers.wire) return buffers.wire;
|
|
690
|
+
// no index means consecutive-triplet triangles (including the >0xffff
|
|
691
|
+
// soup, whose vertices a 16-bit edge index cannot name)
|
|
692
|
+
if (!buffers.index && buffers.count > 0xffff) {
|
|
693
|
+
if (!this.wireWarned.has(node)) {
|
|
694
|
+
this.wireWarned.add(node);
|
|
695
|
+
warn(
|
|
696
|
+
`wireframe needs a 16-bit index and this geometry expanded to ` +
|
|
697
|
+
`${buffers.count} vertices — drawing it filled`,
|
|
698
|
+
);
|
|
699
|
+
}
|
|
700
|
+
return null;
|
|
701
|
+
}
|
|
702
|
+
const source = buffers.index ? node.data({ normals: true }).index : null;
|
|
703
|
+
const seen = new Set<number>();
|
|
704
|
+
const edges: number[] = [];
|
|
705
|
+
const push = (a: number, b: number) => {
|
|
706
|
+
const key = a < b ? a * 0x10000 + b : b * 0x10000 + a;
|
|
707
|
+
if (seen.has(key)) return;
|
|
708
|
+
seen.add(key);
|
|
709
|
+
edges.push(a, b);
|
|
710
|
+
};
|
|
711
|
+
const triangles = source ? source.length / 3 : buffers.count / 3;
|
|
712
|
+
for (let t = 0; t < triangles; t++) {
|
|
713
|
+
const a = source ? source[t * 3] : t * 3;
|
|
714
|
+
const b = source ? source[t * 3 + 1] : t * 3 + 1;
|
|
715
|
+
const c = source ? source[t * 3 + 2] : t * 3 + 2;
|
|
716
|
+
push(a, b);
|
|
717
|
+
push(b, c);
|
|
718
|
+
push(c, a);
|
|
719
|
+
}
|
|
720
|
+
const index = gl.createBuffer();
|
|
721
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, index);
|
|
722
|
+
gl.bufferData(
|
|
723
|
+
gl.ELEMENT_ARRAY_BUFFER,
|
|
724
|
+
new Uint16Array(edges),
|
|
725
|
+
gl.STATIC_DRAW,
|
|
726
|
+
);
|
|
727
|
+
buffers.wire = { index, count: edges.length };
|
|
728
|
+
return buffers.wire;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/** Compile once per material configuration, reuse for every mesh using it. */
|
|
732
|
+
private programFor(
|
|
733
|
+
gl: GL,
|
|
734
|
+
material: Material | null,
|
|
735
|
+
lights: LightUniforms,
|
|
736
|
+
primitive: Primitive,
|
|
737
|
+
): CompiledProgram | null {
|
|
738
|
+
const kind = material?.kind ?? 'meshBasicMaterial';
|
|
739
|
+
const user = material instanceof ShaderMaterial;
|
|
740
|
+
|
|
741
|
+
let signature: string;
|
|
742
|
+
let source: { vertex: string; fragment: string };
|
|
743
|
+
if (user) {
|
|
744
|
+
const shader = material as ShaderMaterial;
|
|
745
|
+
signature = `${kind} ${shader.vertexShader} ${shader.fragmentShader}`;
|
|
746
|
+
source = userProgramSource(shader, material instanceof RawShaderMaterial);
|
|
747
|
+
} else {
|
|
748
|
+
const lit = !UNLIT_MATERIALS.has(kind) && lights.lit && lights.count > 0;
|
|
749
|
+
const map = material?.map;
|
|
750
|
+
const textured = !!(map?.width && map?.data);
|
|
751
|
+
// the primitive is part of the signature because only a points program
|
|
752
|
+
// declares (and writes) gl_PointSize
|
|
753
|
+
signature = `${kind}|${lit}|${textured}|${lights.count}|${primitive}`;
|
|
754
|
+
source = materialProgramSource({
|
|
755
|
+
kind,
|
|
756
|
+
lit,
|
|
757
|
+
textured,
|
|
758
|
+
lights: lights.count,
|
|
759
|
+
primitive,
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
const cached = this.programs.get(signature);
|
|
764
|
+
if (cached) return cached.program ? (cached as CompiledProgram) : null;
|
|
765
|
+
|
|
766
|
+
const entry = this.compile(gl, source, signature, kind);
|
|
767
|
+
this.programs.set(signature, entry);
|
|
768
|
+
return entry.program ? (entry as CompiledProgram) : null;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
/** Lent to the post-processor, so a pass that will not build is reported
|
|
772
|
+
* exactly the way a material that will not build is. */
|
|
773
|
+
compile(
|
|
774
|
+
gl: GL,
|
|
775
|
+
source: { vertex: string; fragment: string },
|
|
776
|
+
signature: string,
|
|
777
|
+
kind: string,
|
|
778
|
+
): { program: unknown } | CompiledProgram {
|
|
779
|
+
const shader = (type: number, text: string, what: string) => {
|
|
780
|
+
const object = gl.createShader(type);
|
|
781
|
+
gl.shaderSource(object, text);
|
|
782
|
+
gl.compileShader(object);
|
|
783
|
+
if (gl.getShaderParameter(object, gl.COMPILE_STATUS)) return object;
|
|
784
|
+
this.report(
|
|
785
|
+
signature,
|
|
786
|
+
`${kind}: ${what} failed to compile\n${gl.getShaderInfoLog(object)}`,
|
|
787
|
+
);
|
|
788
|
+
gl.deleteShader(object);
|
|
789
|
+
return null;
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const vertex = shader(gl.VERTEX_SHADER, source.vertex, 'vertex shader');
|
|
793
|
+
const fragment =
|
|
794
|
+
vertex && shader(gl.FRAGMENT_SHADER, source.fragment, 'fragment shader');
|
|
795
|
+
if (!vertex || !fragment) {
|
|
796
|
+
if (vertex) gl.deleteShader(vertex);
|
|
797
|
+
return { program: null };
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
const program = gl.createProgram();
|
|
801
|
+
gl.attachShader(program, vertex);
|
|
802
|
+
gl.attachShader(program, fragment);
|
|
803
|
+
gl.linkProgram(program);
|
|
804
|
+
gl.deleteShader(vertex);
|
|
805
|
+
gl.deleteShader(fragment);
|
|
806
|
+
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
|
|
807
|
+
this.report(
|
|
808
|
+
signature,
|
|
809
|
+
`${kind}: program failed to link\n${gl.getProgramInfoLog(program)}`,
|
|
810
|
+
);
|
|
811
|
+
gl.deleteProgram(program);
|
|
812
|
+
return { program: null };
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
const uniforms = new Map<string, unknown>();
|
|
816
|
+
const attributes = new Map<string, number>();
|
|
817
|
+
return {
|
|
818
|
+
program,
|
|
819
|
+
uniform(name: string) {
|
|
820
|
+
if (!uniforms.has(name))
|
|
821
|
+
uniforms.set(name, gl.getUniformLocation(program, name));
|
|
822
|
+
return uniforms.get(name);
|
|
823
|
+
},
|
|
824
|
+
attribute(name: string) {
|
|
825
|
+
if (!attributes.has(name))
|
|
826
|
+
attributes.set(name, gl.getAttribLocation(program, name));
|
|
827
|
+
return attributes.get(name)!;
|
|
828
|
+
},
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* A shader that will not build is reported once and then skipped.
|
|
834
|
+
* Throwing would take down a render that is otherwise fine, and repeating
|
|
835
|
+
* it every frame would bury the message it came with — the compiler's own
|
|
836
|
+
* log, the only thing that says what to fix.
|
|
837
|
+
*/
|
|
838
|
+
report(signature: string, message: string, code = 'GL_SHADER_FAILED'): void {
|
|
839
|
+
if (this.failed.has(signature)) return;
|
|
840
|
+
this.failed.add(signature);
|
|
841
|
+
const err = new Error(`@react-x11/components: ${message}`) as Error & {
|
|
842
|
+
code?: string;
|
|
843
|
+
};
|
|
844
|
+
err.code = code;
|
|
845
|
+
if (this.onError) this.onError(err);
|
|
846
|
+
else warn(err.message);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/** `<shaderPass uniforms>` reads like a `<shaderMaterial>`'s. */
|
|
850
|
+
setUniform(gl: GL, location: unknown, value: unknown): void {
|
|
851
|
+
setUniform(gl, location, value);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
private applyMaterial(
|
|
855
|
+
gl: GL,
|
|
856
|
+
program: CompiledProgram,
|
|
857
|
+
material: Material | null,
|
|
858
|
+
lights: LightUniforms,
|
|
859
|
+
): { color: [number, number, number] } | undefined {
|
|
860
|
+
if (material instanceof ShaderMaterial) {
|
|
861
|
+
gl.uniform3fv(program.uniform('cameraPosition'), this.cameraPosition());
|
|
862
|
+
for (const [name, entry] of Object.entries(
|
|
863
|
+
material.uniforms as Record<string, UniformEntry>,
|
|
864
|
+
)) {
|
|
865
|
+
const value = entry.value;
|
|
866
|
+
const image = value as TextureImage | null;
|
|
867
|
+
if (
|
|
868
|
+
image &&
|
|
869
|
+
typeof image === 'object' &&
|
|
870
|
+
'width' in image &&
|
|
871
|
+
'data' in image &&
|
|
872
|
+
image.width &&
|
|
873
|
+
image.data
|
|
874
|
+
) {
|
|
875
|
+
const unit = this.textureFor(gl, image);
|
|
876
|
+
gl.uniform1i(program.uniform(name), unit);
|
|
877
|
+
} else {
|
|
878
|
+
setUniform(gl, program.uniform(name), value);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
this.applyDrawState(
|
|
882
|
+
gl,
|
|
883
|
+
material,
|
|
884
|
+
material.transparent || material.opacity < 1,
|
|
885
|
+
);
|
|
886
|
+
return undefined;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
const kind = material?.kind ?? 'meshBasicMaterial';
|
|
890
|
+
const colors = materialColors(material);
|
|
891
|
+
const scale = colors.diffuseScale;
|
|
892
|
+
gl.uniform3fv(
|
|
893
|
+
program.uniform('diffuse'),
|
|
894
|
+
new Float32Array([
|
|
895
|
+
colors.color[0] * scale,
|
|
896
|
+
colors.color[1] * scale,
|
|
897
|
+
colors.color[2] * scale,
|
|
898
|
+
]),
|
|
899
|
+
);
|
|
900
|
+
// three.js's names: `size` on a points material, `linewidth` on a line one
|
|
901
|
+
if (kind === 'pointsMaterial') {
|
|
902
|
+
gl.uniform1f(
|
|
903
|
+
program.uniform('pointSize'),
|
|
904
|
+
(material as { size?: number } | null)?.size ?? 1,
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
if (kind === 'lineBasicMaterial') {
|
|
908
|
+
gl.lineWidth((material as { linewidth?: number } | null)?.linewidth ?? 1);
|
|
909
|
+
}
|
|
910
|
+
gl.uniform1f(program.uniform('opacity'), colors.alpha);
|
|
911
|
+
gl.uniform3fv(
|
|
912
|
+
program.uniform('emissive'),
|
|
913
|
+
new Float32Array(colors.emissive),
|
|
914
|
+
);
|
|
915
|
+
if (kind === 'meshPhongMaterial' || kind === 'meshStandardMaterial') {
|
|
916
|
+
gl.uniform3fv(
|
|
917
|
+
program.uniform('specular'),
|
|
918
|
+
new Float32Array(colors.specular),
|
|
919
|
+
);
|
|
920
|
+
gl.uniform1f(program.uniform('shininess'), colors.shininess);
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
const map = material?.map;
|
|
924
|
+
if (map?.width && map?.data) {
|
|
925
|
+
gl.uniform1i(program.uniform('map'), this.textureFor(gl, map));
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
if (lights.count > 0 || lights.lit) {
|
|
929
|
+
gl.uniform3fv(program.uniform('ambientColor'), lights.ambient);
|
|
930
|
+
if (lights.count > 0) {
|
|
931
|
+
gl.uniform4fv(program.uniform('lightPosition[0]'), lights.position);
|
|
932
|
+
gl.uniform3fv(program.uniform('lightColor[0]'), lights.color);
|
|
933
|
+
gl.uniform3fv(
|
|
934
|
+
program.uniform('spotDirection[0]'),
|
|
935
|
+
lights.spotDirection,
|
|
936
|
+
);
|
|
937
|
+
gl.uniform4fv(program.uniform('spotParams[0]'), lights.spotParams);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
this.applyDrawState(
|
|
942
|
+
gl,
|
|
943
|
+
material,
|
|
944
|
+
colors.alpha < 1 || (material?.transparent ?? false),
|
|
945
|
+
);
|
|
946
|
+
// handed back so <instancedMesh> can restore it between instances that
|
|
947
|
+
// override the colour and instances that do not
|
|
948
|
+
return { color: colors.color };
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
/** Blending, culling and depth writes — the state a material implies. */
|
|
952
|
+
private applyDrawState(
|
|
953
|
+
gl: GL,
|
|
954
|
+
material: Material | null,
|
|
955
|
+
blended: boolean,
|
|
956
|
+
): void {
|
|
957
|
+
if (blended) {
|
|
958
|
+
gl.enable(gl.BLEND);
|
|
959
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
960
|
+
// a translucent surface must not hide what is behind it
|
|
961
|
+
gl.depthMask(false);
|
|
962
|
+
} else {
|
|
963
|
+
gl.disable(gl.BLEND);
|
|
964
|
+
gl.depthMask(true);
|
|
965
|
+
}
|
|
966
|
+
const side = material?.side ?? 'front';
|
|
967
|
+
if (side === 'double') {
|
|
968
|
+
gl.disable(gl.CULL_FACE);
|
|
969
|
+
} else {
|
|
970
|
+
gl.enable(gl.CULL_FACE);
|
|
971
|
+
gl.cullFace(side === 'back' ? gl.FRONT : gl.BACK);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
private cameraPosition(): Float32Array {
|
|
976
|
+
// the eye is the origin in view space, so its world position is the
|
|
977
|
+
// translation of the inverted view matrix
|
|
978
|
+
const inverse = this.camera ? invert(this.camera.view) : null;
|
|
979
|
+
return inverse
|
|
980
|
+
? new Float32Array([inverse[12], inverse[13], inverse[14]])
|
|
981
|
+
: new Float32Array(3);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Upload an image once and bind it to a texture unit. `map` is an ntk
|
|
986
|
+
* `Image`, or anything with `{ width, height, data }` in RGBA byte order —
|
|
987
|
+
* the same contract the indirect renderer takes.
|
|
988
|
+
*/
|
|
989
|
+
textureFor(gl: GL, image: TextureImage): number {
|
|
990
|
+
const cached = this.textures.get(image);
|
|
991
|
+
if (cached) {
|
|
992
|
+
gl.activeTexture(gl.TEXTURE0 + cached.unit);
|
|
993
|
+
gl.bindTexture(gl.TEXTURE_2D, cached.texture);
|
|
994
|
+
return cached.unit;
|
|
995
|
+
}
|
|
996
|
+
const unit = this.textures.size;
|
|
997
|
+
const texture = gl.createTexture();
|
|
998
|
+
gl.activeTexture(gl.TEXTURE0 + unit);
|
|
999
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
1000
|
+
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
|
|
1001
|
+
const data =
|
|
1002
|
+
image.data instanceof Uint8Array
|
|
1003
|
+
? image.data
|
|
1004
|
+
: new Uint8Array(image.data as ArrayLike<number>);
|
|
1005
|
+
gl.texImage2D(
|
|
1006
|
+
gl.TEXTURE_2D,
|
|
1007
|
+
0,
|
|
1008
|
+
gl.RGBA,
|
|
1009
|
+
image.width,
|
|
1010
|
+
image.height,
|
|
1011
|
+
0,
|
|
1012
|
+
gl.RGBA,
|
|
1013
|
+
gl.UNSIGNED_BYTE,
|
|
1014
|
+
data,
|
|
1015
|
+
);
|
|
1016
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
1017
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
1018
|
+
// REPEAT needs power-of-two dimensions in ES 2; CLAMP_TO_EDGE always works
|
|
1019
|
+
const pot = (n: number) => (n & (n - 1)) === 0;
|
|
1020
|
+
const wrap =
|
|
1021
|
+
pot(image.width) && pot(image.height) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
|
1022
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrap);
|
|
1023
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrap);
|
|
1024
|
+
this.textures.set(image, { texture, unit });
|
|
1025
|
+
return unit;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
/** A removed geometry's buffers are no longer needed on the GPU. */
|
|
1029
|
+
forget(gl: GL, node: BufferGeometry): void {
|
|
1030
|
+
const perPrimitive = this.geometries.get(node);
|
|
1031
|
+
if (!perPrimitive) return;
|
|
1032
|
+
this.geometries.delete(node);
|
|
1033
|
+
if (gl)
|
|
1034
|
+
for (const entry of perPrimitive.values())
|
|
1035
|
+
this.releaseGeometry(gl, entry);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
dispose(gl: GL): void {
|
|
1039
|
+
if (gl) {
|
|
1040
|
+
for (const perPrimitive of this.geometries.values()) {
|
|
1041
|
+
for (const entry of perPrimitive.values()) {
|
|
1042
|
+
this.releaseGeometry(gl, entry);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
for (const { program } of this.programs.values()) {
|
|
1046
|
+
if (program) gl.deleteProgram(program);
|
|
1047
|
+
}
|
|
1048
|
+
for (const { texture } of this.textures.values())
|
|
1049
|
+
gl.deleteTexture(texture);
|
|
1050
|
+
}
|
|
1051
|
+
this.geometries.clear();
|
|
1052
|
+
this.programs.clear();
|
|
1053
|
+
this.textures.clear();
|
|
1054
|
+
}
|
|
1055
|
+
}
|