Ver código fonte

using plain webgl, removed regl

Alexander Rose 7 anos atrás
pai
commit
98f651dfd3

+ 484 - 84
package-lock.json

@@ -24,6 +24,16 @@
         "js-tokens": "3.0.2"
       }
     },
+    "@mrmlnc/readdir-enhanced": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+      "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+      "dev": true,
+      "requires": {
+        "call-me-maybe": "1.0.1",
+        "glob-to-regexp": "0.3.0"
+      }
+    },
     "@sindresorhus/is": {
       "version": "0.7.0",
       "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
@@ -49,7 +59,7 @@
       "dev": true,
       "requires": {
         "@types/express": "4.11.1",
-        "@types/node": "9.6.6"
+        "@types/node": "9.6.8"
       }
     },
     "@types/events": {
@@ -76,7 +86,7 @@
       "dev": true,
       "requires": {
         "@types/events": "1.1.0",
-        "@types/node": "9.6.6"
+        "@types/node": "9.6.8"
       }
     },
     "@types/jest": {
@@ -101,33 +111,26 @@
       "dev": true
     },
     "@types/node": {
-      "version": "9.6.6",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.6.tgz",
-      "integrity": "sha512-SJe0g5cZeGNDP5sD8mIX3scb+eq8LQQZ60FXiKZHipYSeEFZ5EKml+NNMiO76F74TY4PoMWlNxF/YRY40FOvZQ==",
+      "version": "9.6.8",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.8.tgz",
+      "integrity": "sha512-0PmgMBskTJa7zDyENW9C7Lunk+I0L2CHYF2RrBRljCmLSMM1fBHIIdvE1IboNNz7N6t+raJIj90YMvUYl2VT1g==",
       "dev": true
     },
     "@types/node-fetch": {
-      "version": "1.6.8",
-      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-1.6.8.tgz",
-      "integrity": "sha512-O8DUwXf7KUBu036HAbF5RKRaA1vvE0BsaPfAnC9YD7Xy4eNoJmNIdEjBIEEHAVszozRgH4m9JnVCsueSKiKXMA==",
+      "version": "1.6.9",
+      "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-1.6.9.tgz",
+      "integrity": "sha512-n2r6WLoY7+uuPT7pnEtKJCmPUGyJ+cbyBR8Avnu4+m1nzz7DwBVuyIvvlBzCZ/nrpC7rIgb3D6pNavL7rFEa9g==",
       "dev": true,
       "requires": {
-        "@types/node": "9.6.6"
+        "@types/node": "9.6.8"
       }
     },
     "@types/react": {
-      "version": "16.3.12",
-      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.3.12.tgz",
-      "integrity": "sha512-FfBhLC3QeXXEtjoGGLixS7cB305vzBOM1dZKtbUuXeTfjY0quzRRMxpqylC4QyUaLqdhNLdER0ZdHUGAVlGSCA==",
+      "version": "16.3.13",
+      "resolved": "https://registry.npmjs.org/@types/react/-/react-16.3.13.tgz",
+      "integrity": "sha512-YMFH/E9ryjUm2AoOy8KdTuG1SufaMuYmO/5xACROl0pm9dRmE2RN3d2zjv/eHALF6LGRZPVb7G9kqP0n5dWttQ==",
       "requires": {
         "csstype": "2.3.0"
-      },
-      "dependencies": {
-        "csstype": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.3.0.tgz",
-          "integrity": "sha512-+iowf+HbYUKV65+HjAhXkx4KH6IFpIxnBlO0maKsXmBIHJXEndaTRYPVL4pEwtK6+1zRvkXo+WD1tRFKygMHQg=="
-        }
       }
     },
     "@types/react-dom": {
@@ -136,8 +139,8 @@
       "integrity": "sha512-ony2hEYlGXCLWNAWWgbsHR7qVvDbeMRFc5b43+7dhj3n+zXzxz81HV9Yjpc3JD8vLCiwYoSLqFCI6bD0+0zG2Q==",
       "dev": true,
       "requires": {
-        "@types/node": "9.6.6",
-        "@types/react": "16.3.12"
+        "@types/node": "9.6.8",
+        "@types/react": "16.3.13"
       }
     },
     "@types/react-transition-group": {
@@ -145,7 +148,7 @@
       "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.0.8.tgz",
       "integrity": "sha512-52rCkAlhkFfaXplkujWUevTMb9/DCsND1DwB6VONPJKAShC3MrRl130ADV7Rc+7t83KVAoz4HPFhJuHI5pfnZA==",
       "requires": {
-        "@types/react": "16.3.12"
+        "@types/react": "16.3.13"
       }
     },
     "@types/serve-static": {
@@ -1767,6 +1770,12 @@
         }
       }
     },
+    "call-me-maybe": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+      "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+      "dev": true
+    },
     "callsites": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
@@ -2176,9 +2185,9 @@
       "dev": true
     },
     "colors": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz",
-      "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.3.tgz",
+      "integrity": "sha512-qTfM2pNFeMZcLvf/RbrVAzDEVttZjFhaApfx9dplNjvHSX88Ui66zBRb/4YGob/xUWxDceirgoC1lT676asfCQ==",
       "dev": true
     },
     "combined-stream": {
@@ -2703,6 +2712,33 @@
         "randombytes": "2.0.6"
       }
     },
+    "dir-glob": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz",
+      "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==",
+      "dev": true,
+      "requires": {
+        "arrify": "1.0.1",
+        "path-type": "3.0.0"
+      },
+      "dependencies": {
+        "path-type": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+          "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+          "dev": true,
+          "requires": {
+            "pify": "3.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
     "dom-helpers": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz",
@@ -3193,9 +3229,9 @@
       }
     },
     "extra-watch-webpack-plugin": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/extra-watch-webpack-plugin/-/extra-watch-webpack-plugin-1.0.1.tgz",
-      "integrity": "sha512-zhCYnRWa2y1hc33mL3hwWF0BRnXDibVLKLbNDA/ie0UnV+5dd0tNO0NLRptNbMEkQCxrjHLz0D9gvLel0jFxjg==",
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/extra-watch-webpack-plugin/-/extra-watch-webpack-plugin-1.0.3.tgz",
+      "integrity": "sha512-ZScQdMH6hNofRRN6QMQFg+aa5vqimfBgnPXmRDhdaLpttT6hrzpY9Oyren3Gh/FySPrgsvKCNbx/NFA7XNdIsg==",
       "dev": true,
       "requires": {
         "glob": "7.1.2",
@@ -3251,6 +3287,302 @@
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
       "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
     },
+    "fast-glob": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.1.tgz",
+      "integrity": "sha512-wSyW1TBK3ia5V+te0rGPXudeMHoUQW6O5Y9oATiaGhpENmEifPDlOdhpsnlj5HoG6ttIvGiY1DdCmI9X2xGMhg==",
+      "dev": true,
+      "requires": {
+        "@mrmlnc/readdir-enhanced": "2.2.1",
+        "glob-parent": "3.1.0",
+        "is-glob": "4.0.0",
+        "merge2": "1.2.1",
+        "micromatch": "3.1.10"
+      },
+      "dependencies": {
+        "arr-diff": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+          "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+          "dev": true
+        },
+        "array-unique": {
+          "version": "0.3.2",
+          "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+          "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+          "dev": true
+        },
+        "braces": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+          "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+          "dev": true,
+          "requires": {
+            "arr-flatten": "1.1.0",
+            "array-unique": "0.3.2",
+            "extend-shallow": "2.0.1",
+            "fill-range": "4.0.0",
+            "isobject": "3.0.1",
+            "repeat-element": "1.1.2",
+            "snapdragon": "0.8.2",
+            "snapdragon-node": "2.1.1",
+            "split-string": "3.1.0",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "expand-brackets": {
+          "version": "2.1.4",
+          "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+          "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+          "dev": true,
+          "requires": {
+            "debug": "2.6.9",
+            "define-property": "0.2.5",
+            "extend-shallow": "2.0.1",
+            "posix-character-classes": "0.1.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "0.2.5",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+              "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "0.1.6"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            },
+            "is-descriptor": {
+              "version": "0.1.6",
+              "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+              "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+              "dev": true,
+              "requires": {
+                "is-accessor-descriptor": "0.1.6",
+                "is-data-descriptor": "0.1.4",
+                "kind-of": "5.1.0"
+              }
+            },
+            "kind-of": {
+              "version": "5.1.0",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+              "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+              "dev": true
+            }
+          }
+        },
+        "extglob": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+          "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+          "dev": true,
+          "requires": {
+            "array-unique": "0.3.2",
+            "define-property": "1.0.0",
+            "expand-brackets": "2.1.4",
+            "extend-shallow": "2.0.1",
+            "fragment-cache": "0.2.1",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          },
+          "dependencies": {
+            "define-property": {
+              "version": "1.0.0",
+              "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+              "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+              "dev": true,
+              "requires": {
+                "is-descriptor": "1.0.2"
+              }
+            },
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "fill-range": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+          "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "2.0.1",
+            "is-number": "3.0.0",
+            "repeat-string": "1.6.1",
+            "to-regex-range": "2.1.1"
+          },
+          "dependencies": {
+            "extend-shallow": {
+              "version": "2.0.1",
+              "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+              "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+              "dev": true,
+              "requires": {
+                "is-extendable": "0.1.1"
+              }
+            }
+          }
+        },
+        "glob-parent": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+          "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+          "dev": true,
+          "requires": {
+            "is-glob": "3.1.0",
+            "path-dirname": "1.0.2"
+          },
+          "dependencies": {
+            "is-glob": {
+              "version": "3.1.0",
+              "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+              "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+              "dev": true,
+              "requires": {
+                "is-extglob": "2.1.1"
+              }
+            }
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "0.1.6",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+          "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "is-data-descriptor": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+          "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "is-extglob": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+          "dev": true
+        },
+        "is-glob": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+          "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "2.1.1"
+          }
+        },
+        "is-number": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+          "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+          "dev": true,
+          "requires": {
+            "kind-of": "3.2.2"
+          },
+          "dependencies": {
+            "kind-of": {
+              "version": "3.2.2",
+              "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+              "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+              "dev": true,
+              "requires": {
+                "is-buffer": "1.1.5"
+              }
+            }
+          }
+        },
+        "isobject": {
+          "version": "3.0.1",
+          "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+          "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+          "dev": true
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        },
+        "micromatch": {
+          "version": "3.1.10",
+          "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+          "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+          "dev": true,
+          "requires": {
+            "arr-diff": "4.0.0",
+            "array-unique": "0.3.2",
+            "braces": "2.3.2",
+            "define-property": "2.0.2",
+            "extend-shallow": "3.0.2",
+            "extglob": "2.0.4",
+            "fragment-cache": "0.2.1",
+            "kind-of": "6.0.2",
+            "nanomatch": "1.2.9",
+            "object.pick": "1.3.0",
+            "regex-not": "1.0.2",
+            "snapdragon": "0.8.2",
+            "to-regex": "3.0.2"
+          }
+        }
+      }
+    },
     "fast-json-stable-stringify": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
@@ -3404,9 +3736,9 @@
       }
     },
     "flow-parser": {
-      "version": "0.70.0",
-      "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.70.0.tgz",
-      "integrity": "sha512-gGdyVUZWswG5jcINrVDHd3RY4nJptBTAx9mR9thGsrGGmAUR7omgJXQSpR+fXrLtxSTAea3HpAZNU/yzRJc2Cg==",
+      "version": "0.71.0",
+      "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.71.0.tgz",
+      "integrity": "sha512-rXSvqSBLf8aRI6T3P99jMcUYvZoO1KZcKDkzGJmXvYdNAgRKu7sfGNtxEsn3cX4TgungBuJpX+K8aHRC9/B5MA==",
       "dev": true
     },
     "flush-write-stream": {
@@ -4652,6 +4984,12 @@
         "is-glob": "2.0.1"
       }
     },
+    "glob-to-regexp": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+      "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+      "dev": true
+    },
     "glob2base": {
       "version": "0.0.12",
       "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz",
@@ -5343,10 +5681,11 @@
       "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=",
       "dev": true
     },
-    "immutable": {
-      "version": "3.8.2",
-      "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
-      "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
+    "ignore": {
+      "version": "3.3.8",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
+      "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==",
+      "dev": true
     },
     "import-local": {
       "version": "1.0.0",
@@ -5797,6 +6136,12 @@
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
       "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
     },
+    "isbinaryfile": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz",
+      "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=",
+      "dev": true
+    },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -6361,9 +6706,9 @@
         "babel-preset-es2015": "6.24.1",
         "babel-preset-stage-1": "6.24.1",
         "babel-register": "6.26.0",
-        "babylon": "7.0.0-beta.44",
-        "colors": "1.2.1",
-        "flow-parser": "0.70.0",
+        "babylon": "7.0.0-beta.46",
+        "colors": "1.2.3",
+        "flow-parser": "0.71.0",
         "lodash": "4.17.4",
         "micromatch": "2.3.11",
         "neo-async": "2.5.1",
@@ -6375,9 +6720,9 @@
       },
       "dependencies": {
         "babylon": {
-          "version": "7.0.0-beta.44",
-          "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.44.tgz",
-          "integrity": "sha512-5Hlm13BJVAioCHpImtFqNOF2H3ieTOHd0fmFGMxOJ9jgeFqeAwsv3u5P5cR7CSeFrkgHsT19DgFJkHV0/Mcd8g==",
+          "version": "7.0.0-beta.46",
+          "resolved": "https://registry.npmjs.org/babylon/-/babylon-7.0.0-beta.46.tgz",
+          "integrity": "sha512-WFJlg2WatdkXRFMpk7BN/Uzzkjkcjk+WaqnrSCpay+RYl4ypW9ZetZyT9kNt22IH/BQNst3M6PaaBn9IXsUNrg==",
           "dev": true
         },
         "write-file-atomic": {
@@ -7190,16 +7535,17 @@
       }
     },
     "mem-fs-editor": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-3.0.2.tgz",
-      "integrity": "sha1-3Qpuryu4prN3QAZ6pUnrUwEFr58=",
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/mem-fs-editor/-/mem-fs-editor-4.0.1.tgz",
+      "integrity": "sha512-54fptqhSZX1sSYsVVInG2qzUWPPrEv/6qYxHAwXJZQfzDcviJcL+7p/wmupg8SdAOi42m/vilMBemx3D6Sz22g==",
       "dev": true,
       "requires": {
         "commondir": "1.0.1",
-        "deep-extend": "0.4.2",
+        "deep-extend": "0.5.1",
         "ejs": "2.5.9",
         "glob": "7.1.2",
-        "globby": "6.1.0",
+        "globby": "8.0.1",
+        "isbinaryfile": "3.0.2",
         "mkdirp": "0.5.1",
         "multimatch": "2.1.0",
         "rimraf": "2.6.2",
@@ -7208,9 +7554,9 @@
       },
       "dependencies": {
         "clone": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
-          "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+          "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=",
           "dev": true
         },
         "clone-stats": {
@@ -7219,6 +7565,33 @@
           "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
           "dev": true
         },
+        "deep-extend": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
+          "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
+          "dev": true
+        },
+        "globby": {
+          "version": "8.0.1",
+          "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.1.tgz",
+          "integrity": "sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw==",
+          "dev": true,
+          "requires": {
+            "array-union": "1.0.2",
+            "dir-glob": "2.0.0",
+            "fast-glob": "2.2.1",
+            "glob": "7.1.2",
+            "ignore": "3.3.8",
+            "pify": "3.0.0",
+            "slash": "1.0.0"
+          }
+        },
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        },
         "replace-ext": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
@@ -7231,7 +7604,7 @@
           "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=",
           "dev": true,
           "requires": {
-            "clone": "2.1.2",
+            "clone": "2.1.1",
             "clone-buffer": "1.0.0",
             "clone-stats": "1.0.0",
             "cloneable-readable": "1.1.2",
@@ -7271,6 +7644,12 @@
         "readable-stream": "2.3.3"
       }
     },
+    "merge2": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.1.tgz",
+      "integrity": "sha512-wUqcG5pxrAcaFI1lkqkMnk3Q7nUxV/NWfpAFSeWUwG9TRODnBDCUHa75mi3o3vLWQ5N4CQERWCauSlP0I3ZqUg==",
+      "dev": true
+    },
     "methods": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
@@ -9046,10 +9425,6 @@
         }
       }
     },
-    "regl": {
-      "version": "git+https://github.com/regl-project/regl.git#45c6ec570232420fca21567499c9c5a2a054432e",
-      "dev": true
-    },
     "remove-trailing-separator": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
@@ -9268,9 +9643,9 @@
       }
     },
     "rxjs": {
-      "version": "6.0.0-beta.4",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.0.0-beta.4.tgz",
-      "integrity": "sha512-H+ghJ4H2mPrugoMfgbeky0yhmOrk4y0ykRyZpYvU2za0VbE2WTKgY/9pF7HJCogPFNIyI4GqI9Ujk3Xr4XxHbQ==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.0.0.tgz",
+      "integrity": "sha512-2MgLQr1zvks8+Kip4T6hcJdiBhV+SIvxguoWjhwtSpNPTp/5e09HJbgclCwR/nW0yWzhubM+6Q0prl8G5RuoBA==",
       "requires": {
         "tslib": "1.9.0"
       },
@@ -11205,9 +11580,9 @@
       "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
     },
     "uglify-js": {
-      "version": "3.3.22",
-      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.22.tgz",
-      "integrity": "sha512-tqw96rL6/BG+7LM5VItdhDjTQmL5zG/I0b2RqWytlgeHe2eydZHuBHdA9vuGpCDhH/ZskNGcqDhivoR2xt8RIw==",
+      "version": "3.3.23",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.23.tgz",
+      "integrity": "sha512-Ks+KqLGDsYn4z+pU7JsKCzC0T3mPYl+rU+VcPZiQOazjE4Uqi4UCRY3qPMDbJi7ze37n1lDXj3biz1ik93vqvw==",
       "dev": true,
       "requires": {
         "commander": "2.15.1",
@@ -12270,8 +12645,8 @@
             "babel-preset-stage-1": "6.24.1",
             "babel-register": "6.26.0",
             "babylon": "6.18.0",
-            "colors": "1.2.1",
-            "flow-parser": "0.70.0",
+            "colors": "1.2.3",
+            "flow-parser": "0.71.0",
             "lodash": "4.17.4",
             "micromatch": "2.3.11",
             "node-dir": "0.1.8",
@@ -12314,12 +12689,12 @@
       }
     },
     "webpack-cli": {
-      "version": "2.0.15",
-      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.0.15.tgz",
-      "integrity": "sha512-bjNeIUO51D4OsmZ5ufzcpzVoacjxfWNfeBZKYL3jc+EMfCME3TyfdCPSUoKiOnebQChfupQuIRpAnx7L4l3Hew==",
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.1.2.tgz",
+      "integrity": "sha512-2C6bs9gORlzCSgkNZTnj8hnXMxe3g2v+yqiUdB+1l/I3sI36ND4zZStV00yq0eGjE5CNu0eqOQr7YYe+42H2Yw==",
       "dev": true,
       "requires": {
-        "chalk": "2.4.0",
+        "chalk": "2.4.1",
         "cross-spawn": "6.0.5",
         "diff": "3.5.0",
         "enhanced-resolve": "4.0.0",
@@ -12333,7 +12708,7 @@
         "jscodeshift": "0.5.0",
         "listr": "0.13.0",
         "loader-utils": "1.1.0",
-        "lodash": "4.17.5",
+        "lodash": "4.17.10",
         "log-symbols": "2.2.0",
         "mkdirp": "0.5.1",
         "p-each-series": "1.0.0",
@@ -12344,7 +12719,7 @@
         "webpack-addons": "1.1.5",
         "yargs": "11.1.0",
         "yeoman-environment": "2.0.6",
-        "yeoman-generator": "2.0.4"
+        "yeoman-generator": "2.0.5"
       },
       "dependencies": {
         "ansi-styles": {
@@ -12363,9 +12738,9 @@
           "dev": true
         },
         "chalk": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.0.tgz",
-          "integrity": "sha512-Wr/w0f4o9LuE7K53cD0qmbAMM+2XNLzR29vFn5hqko4sxGlUsyy363NvmyGIyk5tpe9cjTr9SJYbysEyPkRnFw==",
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
           "dev": true,
           "requires": {
             "ansi-styles": "3.2.1",
@@ -12374,9 +12749,9 @@
           }
         },
         "cliui": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
-          "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+          "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
           "dev": true,
           "requires": {
             "string-width": "2.1.1",
@@ -12410,9 +12785,9 @@
           "dev": true
         },
         "lodash": {
-          "version": "4.17.5",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
-          "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==",
+          "version": "4.17.10",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+          "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
           "dev": true
         },
         "semver": {
@@ -12436,7 +12811,7 @@
           "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
           "dev": true,
           "requires": {
-            "cliui": "4.0.0",
+            "cliui": "4.1.0",
             "decamelize": "1.2.0",
             "find-up": "2.1.0",
             "get-caller-file": "1.0.2",
@@ -12782,15 +13157,15 @@
       }
     },
     "yeoman-generator": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.4.tgz",
-      "integrity": "sha512-Sgvz3MAkOpEIobcpW3rjEl6bOTNnl8SkibP9z7hYKfIGIlw0QDC2k0MAeXvyE2pLqc2M0Duql+6R7/W9GrJojg==",
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/yeoman-generator/-/yeoman-generator-2.0.5.tgz",
+      "integrity": "sha512-rV6tJ8oYzm4mmdF2T3wjY+Q42jKF2YiiD0VKfJ8/0ZYwmhCKC9Xs2346HVLPj/xE13i68psnFJv7iS6gWRkeAg==",
       "dev": true,
       "requires": {
         "async": "2.6.0",
         "chalk": "2.3.1",
         "cli-table": "0.3.1",
-        "cross-spawn": "5.1.0",
+        "cross-spawn": "6.0.5",
         "dargs": "5.1.0",
         "dateformat": "3.0.3",
         "debug": "3.1.0",
@@ -12799,9 +13174,9 @@
         "find-up": "2.1.0",
         "github-username": "4.1.0",
         "istextorbinary": "2.2.1",
-        "lodash": "4.17.4",
+        "lodash": "4.17.10",
         "make-dir": "1.2.0",
-        "mem-fs-editor": "3.0.2",
+        "mem-fs-editor": "4.0.1",
         "minimist": "1.2.0",
         "pretty-bytes": "4.0.2",
         "read-chunk": "2.1.0",
@@ -12814,6 +13189,19 @@
         "yeoman-environment": "2.0.6"
       },
       "dependencies": {
+        "cross-spawn": {
+          "version": "6.0.5",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+          "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+          "dev": true,
+          "requires": {
+            "nice-try": "1.0.4",
+            "path-key": "2.0.1",
+            "semver": "5.5.0",
+            "shebang-command": "1.2.0",
+            "which": "1.3.0"
+          }
+        },
         "debug": {
           "version": "3.1.0",
           "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -12835,6 +13223,12 @@
             "strip-bom": "3.0.0"
           }
         },
+        "lodash": {
+          "version": "4.17.10",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+          "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
+          "dev": true
+        },
         "minimist": {
           "version": "1.2.0",
           "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
@@ -12887,6 +13281,12 @@
             "read-pkg": "3.0.0"
           }
         },
+        "semver": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+          "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+          "dev": true
+        },
         "strip-bom": {
           "version": "3.0.0",
           "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",

+ 7 - 8
package.json

@@ -60,27 +60,26 @@
     "@types/benchmark": "^1.0.31",
     "@types/express": "^4.11.1",
     "@types/jest": "^22.2.3",
-    "@types/node": "^9.6.6",
-    "@types/node-fetch": "^1.6.8",
-    "@types/react": "^16.3.12",
+    "@types/node": "^9.6.8",
+    "@types/node-fetch": "^1.6.9",
+    "@types/react": "^16.3.13",
     "@types/react-dom": "^16.0.5",
     "benchmark": "^2.1.4",
     "copyfiles": "^2.0.0",
     "cpx": "^1.5.0",
-    "extra-watch-webpack-plugin": "^1.0.1",
+    "extra-watch-webpack-plugin": "^1.0.3",
     "glslify-import": "^3.1.0",
     "glslify-loader": "^1.0.2",
     "jest": "^22.4.3",
     "jest-raw-loader": "^1.0.1",
     "raw-loader": "^0.5.1",
-    "regl": "git+https://github.com/regl-project/regl.git#45c6ec570232420fca21567499c9c5a2a054432e",
     "ts-jest": "^22.4.4",
     "tslint": "^5.9.1",
     "typescript": "^2.8.3",
-    "uglify-js": "^3.3.22",
+    "uglify-js": "^3.3.23",
     "util.promisify": "^1.0.0",
     "webpack": "^4.6.0",
-    "webpack-cli": "^2.0.15"
+    "webpack-cli": "^2.1.2"
   },
   "dependencies": {
     "argparse": "^1.0.10",
@@ -90,6 +89,6 @@
     "node-fetch": "^2.1.2",
     "react": "^16.3.2",
     "react-dom": "^16.3.2",
-    "rxjs": "^6.0.0-beta.4"
+    "rxjs": "^6.0.0"
   }
 }

+ 5 - 5
src/apps/render-test/state.ts

@@ -41,9 +41,9 @@ export default class State {
     initialized = new BehaviorSubject<boolean>(false)
     loading = new BehaviorSubject<boolean>(false)
 
-    colorTheme = new BehaviorSubject<ColorTheme>('uniform')
-    colorValue = new BehaviorSubject<Color>(0xFF0000)
-    detail = new BehaviorSubject<number>(2)
+    colorTheme = new BehaviorSubject<ColorTheme>('element-symbol')
+    colorValue = new BehaviorSubject<Color>(0xFF4411)
+    detail = new BehaviorSubject<number>(0)
 
     pointVisibility = new BehaviorSubject<boolean>(true)
     spacefillVisibility = new BehaviorSubject<boolean>(true)
@@ -98,8 +98,8 @@ export default class State {
         viewer.add(this.pointRepr)
 
         this.spacefillRepr = StructureRepresentation(Spacefill)
-        // await Run(this.spacefillRepr.create(struct, this.getSpacefillProps()), log, 100)
-        // viewer.add(this.spacefillRepr)
+        await Run(this.spacefillRepr.create(struct, this.getSpacefillProps()), log, 100)
+        viewer.add(this.spacefillRepr)
 
         this.updateVisibility()
         viewer.requestDraw()

+ 13 - 13
src/mol-geo/representation/structure/point.ts

@@ -83,8 +83,8 @@ export default function Point(): UnitsRepresentation<PointProps> {
 
                     position: ValueCell.create(vertices),
                     id: ValueCell.create(fillSerial(new Float32Array(elementCount))),
-                    size: ValueCell.create(size),
-                    color: ValueCell.create(color),
+                    size: size,
+                    color: color,
                     transform: ValueCell.create(transforms),
 
                     instanceCount: unitCount,
@@ -106,21 +106,21 @@ export default function Point(): UnitsRepresentation<PointProps> {
                     return true
                 }
 
-                const elementCount = OrderedSet.size(_elementGroup.elements)
+                // const elementCount = OrderedSet.size(_elementGroup.elements)
                 // const unitCount = _units.length
 
-                const vertexMap = VertexMap.create(
-                    elementCount,
-                    elementCount + 1,
-                    fillSerial(new Uint32Array(elementCount)),
-                    fillSerial(new Uint32Array(elementCount + 1))
-                )
+                // const vertexMap = VertexMap.create(
+                //     elementCount,
+                //     elementCount + 1,
+                //     fillSerial(new Uint32Array(elementCount)),
+                //     fillSerial(new Uint32Array(elementCount + 1))
+                // )
 
                 if (!deepEqual(curProps.colorTheme, newProps.colorTheme)) {
                     console.log('colorTheme changed', curProps.colorTheme, newProps.colorTheme)
-                    await ctx.update('Computing point colors');
-                    const color = createColors(_units, _elementGroup, vertexMap, newProps.colorTheme)
-                    ValueCell.update(points.props.color, color)
+                    // await ctx.update('Computing point colors');
+                    // const color = createColors(_units, _elementGroup, vertexMap, newProps.colorTheme)
+                    // ValueCell.update(points.props.color, color)
                 }
 
                 if (!deepEqual(curProps.sizeTheme, newProps.sizeTheme)) {
@@ -128,7 +128,7 @@ export default function Point(): UnitsRepresentation<PointProps> {
                 }
 
                 curProps = newProps
-                return true
+                return false
             })
         }
     }

+ 1 - 1
src/mol-geo/representation/structure/spacefill.ts

@@ -86,7 +86,7 @@ export default function Spacefill(): UnitsRepresentation<SpacefillProps> {
 
                     position: mesh.vertexBuffer,
                     normal: mesh.normalBuffer as ValueCell<Float32Array>,
-                    color: ValueCell.create(color),
+                    color: color,
                     id: mesh.idBuffer as ValueCell<Float32Array>,
                     transform: ValueCell.create(transforms),
                     index: mesh.indexBuffer,

+ 12 - 12
src/mol-geo/util/color-data.ts

@@ -9,11 +9,11 @@ import { TextureImage, createColorTexture } from 'mol-gl/renderable/util';
 import { Color } from 'mol-util/color';
 import VertexMap from '../shape/vertex-map';
 
-export type UniformColor = { type: 'uniform', value: number[] }
-export type AttributeColor = { type: 'attribute', value: ValueCell<Float32Array> }
-export type InstanceColor = { type: 'instance', value: ValueCell<TextureImage> }
-export type ElementColor = { type: 'element', value: ValueCell<TextureImage> }
-export type ElementInstanceColor = { type: 'element-instance', value: ValueCell<TextureImage> }
+export type UniformColor = { type: 'uniform', data: number[] }
+export type AttributeColor = { type: 'attribute', data: ValueCell<Float32Array> }
+export type InstanceColor = { type: 'instance', data: ValueCell<TextureImage> }
+export type ElementColor = { type: 'element', data: ValueCell<TextureImage> }
+export type ElementInstanceColor = { type: 'element-instance', data: ValueCell<TextureImage> }
 export type ColorData = UniformColor | AttributeColor | InstanceColor | ElementColor | ElementInstanceColor
 
 export interface UniformColorProps {
@@ -22,7 +22,7 @@ export interface UniformColorProps {
 
 /** Creates color uniform */
 export function createUniformColor(props: UniformColorProps): UniformColor {
-    return { type: 'uniform', value: Color.toRgbNormalized(props.value) }
+    return { type: 'uniform', data: Color.toRgbNormalized(props.value) }
 }
 
 export interface AttributeColorProps {
@@ -30,7 +30,7 @@ export interface AttributeColorProps {
     vertexMap: VertexMap
 }
 
-/** Creates color attribute with color for each element (i.e. shared across indtances/units) */
+/** Creates color attribute with color for each element (i.e. shared across instances/units) */
 export function createAttributeColor(props: AttributeColorProps): AttributeColor {
     const { colorFn, vertexMap } = props
     const { idCount, offsetCount, offsets } = vertexMap
@@ -43,7 +43,7 @@ export function createAttributeColor(props: AttributeColorProps): AttributeColor
             Color.toArrayNormalized(hexColor, colors, i * 3)
         }
     }
-    return { type: 'attribute', value: ValueCell.create(colors) }
+    return { type: 'attribute', data: ValueCell.create(colors) }
 }
 
 export interface InstanceColorProps {
@@ -58,7 +58,7 @@ export function createInstanceColor(props: InstanceColorProps): InstanceColor {
     for (let i = 0; i < instanceCount; i++) {
         Color.toArray(colorFn(i), colors.array, i * 3)
     }
-    return { type: 'instance', value: ValueCell.create(colors) }
+    return { type: 'instance', data: ValueCell.create(colors) }
 }
 
 export interface ElementColorProps {
@@ -66,7 +66,7 @@ export interface ElementColorProps {
     vertexMap: VertexMap
 }
 
-/** Creates color texture with color for each element (i.e. shared across indtances/units) */
+/** Creates color texture with color for each element (i.e. shared across instances/units) */
 export function createElementColor(props: ElementColorProps): ElementColor {
     const { colorFn, vertexMap } = props
     const elementCount = vertexMap.offsetCount - 1
@@ -74,7 +74,7 @@ export function createElementColor(props: ElementColorProps): ElementColor {
     for (let i = 0, il = elementCount; i < il; ++i) {
         Color.toArray(colorFn(i), colors.array, i * 3)
     }
-    return { type: 'element', value: ValueCell.create(colors) }
+    return { type: 'element', data: ValueCell.create(colors) }
 }
 
 export interface ElementInstanceColorProps {
@@ -96,7 +96,7 @@ export function createElementInstanceColor(props: ElementInstanceColorProps): El
             colorOffset += 3
         }
     }
-    return { type: 'element-instance', value: ValueCell.create(colors) }
+    return { type: 'element-instance', data: ValueCell.create(colors) }
 }
 
 /** Create color attribute or texture, depending on the vertexMap */

+ 2 - 3
src/mol-gl/_spec/renderer.spec.ts

@@ -41,8 +41,8 @@ function createRenderer(gl: WebGLRenderingContext) {
 function createPoints() {
     const position = ValueCell.create(new Float32Array([0, -1, 0, -1, 0, 0, 1, 1, 0]))
     const id = ValueCell.create(fillSerial(new Float32Array(3)))
-    const color = ValueCell.create(createUniformColor({ value: 0xFF0000 }))
-    const size = ValueCell.create(createUniformSize({ value: 1 }))
+    const color = createUniformColor({ value: 0xFF0000 })
+    const size = createUniformSize({ value: 1 })
 
     const transform = ValueCell.create(new Float32Array(16))
     const m4 = Mat4.identity()
@@ -64,7 +64,6 @@ function createPoints() {
 }
 
 // TODO not working
-// - headless-gl does not support 'OES_element_index_uint'
 // - shaders not transformed via glslify
 describe.skip('renderer', () => {
     it('basic', () => {

+ 0 - 120
src/mol-gl/attribute.ts

@@ -1,120 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import REGL = require('regl');
-import { ValueCell } from 'mol-util/value-cell'
-
-// export type AttributeGroupMutator<T extends AttributesData> = (data: T) => (boolean | void)
-// export type AttributeGroupData = { [k: string]: Helpers.TypedArray }
-// export type AttributesBuffers<T extends AttributesData> = { [K in keyof T]: REGL.Buffer }
-
-// interface AttributeGroup<T extends AttributeGroup.Data> {
-//     readonly buffer: REGL.Buffer
-//     readonly length: number
-//     readonly data: T
-//     setCount(size: number): void
-//     update(mutator: AttributeGroup.Mutator<T>): void
-// }
-
-// namespace AttributeGroup {
-//     export type Data = { [k: string]: Helpers.TypedArray }
-//     export type Mutator<T extends Data> = (data: T) => (UpdateInfo<T> | void)
-//     export type UpdateInfo<T extends Data> = boolean | { [k in keyof T]: Attribute.UpdateInfo }
-//     export type Attributes<T extends Data> = { [K in keyof T]: Attribute<T[K]> }
-
-//     export function create<T extends Data>(regl: REGL.Regl, data: T): AttributeGroup<T> {
-//         const attributes: Attributes<any> = {}
-//         for (const k of Object.keys(data)) {
-//             attributes[k] = Attribute.create(regl, data[k])
-//         }
-//         return {
-//             update: (mutator: Mutator<T>) => {
-
-//             }
-//         }
-//     }
-// }
-
-
-interface Attribute<T extends Helpers.TypedArray> {
-    readonly buffer: REGL.AttributeConfig
-    getCount(): number
-    setCount(count: number): void
-    getArray(): T
-    set(index: number, ...values: number[]): void
-    update(mutator: Attribute.Mutator<T>): void
-    reload(): void
-    destroy(): void
-}
-
-interface AttributeProps {
-    size: 1 | 2 | 3 | 4,
-    divisor?: number,
-    offset?: number,
-    stride?: number
-}
-
-namespace Attribute {
-    export type Mutator<T extends Helpers.TypedArray> = (data: T) => (UpdateInfo | void)
-    export type UpdateInfo = boolean | { offset: number, count: number }
-    export type ArrayCell<T> = { array: ReferenceCell<T> }
-    export type ReferenceCell<T> = { readonly version: number, readonly value: T }
-
-    export function create<T extends Float32Array>(regl: REGL.Regl, array: ValueCell<T>, count: number, props: AttributeProps): Attribute<T> {
-        const itemSize = props.size
-        let _array = array.ref.value
-        let _count = count
-        // if (props.stride) _count = _array.length / (props.stride / _array.BYTES_PER_ELEMENT)
-        // console.log(_array.length, props.stride)
-        // console.log('buffer', {
-        //     data: _array,
-        //     length: count * itemSize,
-        //     usage: 'dynamic',
-        //     type: 'float32'
-        // })
-        const buffer = regl.buffer({
-            data: _array,
-            // length: count * itemSize * _array.BYTES_PER_ELEMENT,
-            usage: 'dynamic',
-            type: 'float32',
-            dimension: itemSize
-        } as any)
-        // console.log(buffer)
-        const attribute: REGL.AttributeConfig = { ...props, buffer }
-        const growIfNeeded = function(count: number) {
-            if (count * itemSize > _array.length) {
-                const newArray: T = new (_array as any).constructor(count * itemSize)
-                newArray.set(_array)
-                _array = newArray
-                buffer(_array)
-            }
-            _count = count
-        }
-        return {
-            buffer: attribute,
-            getCount: () =>  _count,
-            setCount: (count: number) => growIfNeeded(count),
-            getArray: () => _array,
-            set: (index: number, ...values: number[]) => {
-                if (values.length !== itemSize) throw new Error('wrong number of values given')
-                growIfNeeded(index)
-                for (let i = 0; i < itemSize; ++i) {
-                    _array[index * itemSize + i] = values[i]
-                }
-                buffer.subdata(values, index * itemSize * _array.BYTES_PER_ELEMENT)
-            },
-            update: (mutator: Mutator<T>, offset?: number, count?: number) => {
-                if (offset && count) growIfNeeded(offset + count)
-                mutator(_array)
-                buffer(_array)
-            },
-            reload: () => buffer(_array),
-            destroy: () => buffer.destroy()
-        }
-    }
-}
-
-export default Attribute

+ 0 - 57
src/mol-gl/model.ts

@@ -1,57 +0,0 @@
-/**
- * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
- *
- * @author Alexander Rose <alexander.rose@weirdbyte.de>
- */
-
-import REGL = require('regl');
-import { Mat4, Quat, Vec3 } from 'mol-math/linear-algebra'
-import { defaults } from 'mol-util';
-
-const tmpMat4 = Mat4()
-
-type ModelProps = {
-    rotation?: Quat,
-    position?: Vec3,
-    scale?: Vec3
-}
-
-function createModel(regl: REGL.Regl, props: ModelProps = {}) {
-    const transform = Mat4.identity()
-
-    const rotation = defaults(props.rotation, Quat.identity())
-    const position = defaults(props.position, Vec3.zero())
-    const scale = defaults(props.scale, Vec3.create(1, 1, 1))
-
-    const draw = regl({
-        context: { transform, rotation, position, scale },
-
-        uniforms: {
-            model(ctx: REGL.DefaultContext, props: any = {}) {
-                const model = Mat4.identity()
-
-                if ('rotation' in props) Quat.copy(rotation, props.rotation)
-                if ('position' in props) Vec3.copy(position, props.position)
-                if ('scale' in props) Vec3.copy(scale, props.scale)
-
-                Mat4.translate(model, model, position)
-                Mat4.mul(model, model, Mat4.fromQuat(tmpMat4, rotation))
-                Mat4.scale(model, model, scale)
-
-                if ('transform' in props) Mat4.mul(model, props.transform, model)
-                Mat4.copy(transform, model)
-
-                return model
-            }
-        }
-    })
-
-    return Object.assign(draw, {
-        get transform() { return transform },
-        get position() { return position },
-        get rotation() { return rotation },
-        get scale() { return scale },
-    })
-}
-
-export default createModel

+ 2 - 0
src/mol-gl/renderable.ts

@@ -6,10 +6,12 @@
 
 import PointRenderable from './renderable/point'
 import MeshRenderable from './renderable/mesh'
+import { Program } from './webgl/program';
 
 export interface Renderable<T> {
     draw: () => void
     name: string
+    program: Program
     update: (newProps: T) => void
     dispose: () => void
 }

+ 6 - 3
src/mol-gl/renderable/mesh.ts

@@ -23,7 +23,7 @@ namespace Mesh {
         normal?: ValueCell<Float32Array>
         id: ValueCell<Float32Array>
 
-        color: ValueCell<ColorData>
+        color: ColorData
         transform: ValueCell<Float32Array>
         index: ValueCell<Uint32Array>
 
@@ -37,12 +37,14 @@ namespace Mesh {
         const defs: RenderItemProps = {
             ...getBaseDefs(props),
             shaderCode: addShaderDefines(getBaseDefines(props), MeshShaderCode),
-            drawMode: 'triangles'
+            drawMode: 'triangles',
+            elementsKind: 'uint32'
         }
         const values: RenderItemState = {
             ...getBaseValues(props),
             drawCount: props.indexCount * 3,
-            instanceCount: props.instanceCount
+            instanceCount: props.instanceCount,
+            elements: props.index.ref.value
         }
 
         let renderItem = createRenderItem(ctx, defs, values)
@@ -53,6 +55,7 @@ namespace Mesh {
                 renderItem.draw()
             },
             name: 'mesh',
+            get program () { return renderItem.program },
             update: (newProps: Props) => {
                 console.log('Updating mesh renderable')
             },

+ 4 - 7
src/mol-gl/renderable/point.ts

@@ -23,8 +23,8 @@ namespace Point {
         position: ValueCell<Float32Array>
         id: ValueCell<Float32Array>
 
-        size: ValueCell<SizeData>
-        color: ValueCell<ColorData>
+        size: SizeData
+        color: ColorData
         transform: ValueCell<Float32Array>
 
         instanceCount: number
@@ -56,13 +56,10 @@ namespace Point {
             draw: () => {
                 renderItem.draw()
             },
-            name: 'mesh',
+            name: 'point',
+            get program () { return renderItem.program },
             update: (newProps: Props) => {
                 console.log('Updating point renderable')
-                // const newUniforms = updateBaseUniforms(regl, uniforms, newProps, curProps)
-                // const newUniforms = { ...uniforms, color: 0xFF4411 }
-                // console.log(newUniforms)
-                // command({ uniforms: newUniforms })
             },
             dispose: () => {
                 renderItem.dispose()

+ 33 - 26
src/mol-gl/renderable/util.ts

@@ -33,9 +33,9 @@ export function createColorTexture (n: number): TextureImage {
     return { array: new Uint8Array(length), width, height }
 }
 
-export function getColorDefines(color: ValueCell<ColorData>) {
+export function getColorDefines(color: ColorData) {
     const defines: ShaderDefines = {}
-    switch (color.ref.value.type) {
+    switch (color.type) {
         case 'uniform': defines.UNIFORM_COLOR = ''; break;
         case 'attribute': defines.ATTRIBUTE_COLOR = ''; break;
         case 'element': defines.ELEMENT_COLOR = ''; break;
@@ -45,9 +45,9 @@ export function getColorDefines(color: ValueCell<ColorData>) {
     return defines
 }
 
-export function getSizeDefines(size: ValueCell<SizeData>) {
+export function getSizeDefines(size: SizeData) {
     const defines: ShaderDefines = {}
-    switch (size.ref.value.type) {
+    switch (size.type) {
         case 'uniform': defines.UNIFORM_SIZE = ''; break;
         case 'attribute': defines.ATTRIBUTE_SIZE = ''; break;
     }
@@ -71,8 +71,8 @@ interface BaseProps {
     id: ValueCell<Float32Array>
     transform: ValueCell<Float32Array>
 
-    size?: ValueCell<SizeData>
-    color: ValueCell<ColorData>
+    size?: SizeData
+    color: ColorData
 }
 
 export function getBaseUniformDefs(props: BaseProps) {
@@ -81,18 +81,25 @@ export function getBaseUniformDefs(props: BaseProps) {
         view: 'm4',
         projection: 'm4',
 
+        pixelRatio: 'f',
+        viewportHeight: 'f',
+
+        // light_position: 'v3',
+        light_color: 'v3',
+        light_ambient: 'v3',
+
         objectId: 'i',
         instanceCount: 'i',
         elementCount: 'i'
     }
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
+        // uniformDefs.colorTex = 't2'
         uniformDefs.colorTexSize = 'v2'
-        uniformDefs.colorTex = 't2'
     } else if (color.type === 'uniform') {
         uniformDefs.color = 'v3'
     }
-    const size = props.size ? props.size.ref.value : undefined
+    const size = props.size
     if (size && size.type === 'uniform') {
         uniformDefs.size = 'f'
     }
@@ -104,15 +111,15 @@ export function getBaseUniformValues(props: BaseProps) {
     const uniformValues: UniformValues = {
         objectId, instanceCount, elementCount
     }
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
-        const { width, height } = color.value.ref.value
-        uniformValues.colorTex = new ImageData(new Uint8ClampedArray(color.value.ref.value.array), width, height)
+        const { width, height } = color.data.ref.value
+        // uniformValues.colorTex = color.value.ref.value.array
         uniformValues.colorTexSize = Vec2.create(width, height)
     } else if (color.type === 'uniform') {
-        uniformValues.color = color.value as Vec3
+        uniformValues.color = color.data as Vec3
     }
-    const size = props.size ? props.size.ref.value : undefined
+    const size = props.size
     if (size && size.type === 'uniform') {
         uniformValues.size = size.value
     }
@@ -122,20 +129,20 @@ export function getBaseUniformValues(props: BaseProps) {
 export function getBaseAttributeDefs(props: BaseProps) {
     const attributeDefs: AttributeDefs = {
         instanceId: { kind: 'float32', itemSize: 1, divisor: 1 },
-        position: { kind: 'float32', itemSize: 1, divisor: 0 },
+        position: { kind: 'float32', itemSize: 3, divisor: 0 },
         elementId: { kind: 'float32', itemSize: 1, divisor: 0 },
         transform: { kind: 'float32', itemSize: 16, divisor: 1 },
     }
     if (props.normal) {
-        attributeDefs.normal = { kind: 'float32', itemSize: 3, divisor:0 }
+        attributeDefs.normal = { kind: 'float32', itemSize: 3, divisor: 0 }
     }
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'attribute') {
-        attributeDefs.color = { kind: 'float32', itemSize: 3, divisor:0 }
+        attributeDefs.color = { kind: 'float32', itemSize: 3, divisor: 0 }
     }
-    const size = props.size ? props.size.ref.value : undefined
+    const size = props.size
     if (size && size.type === 'attribute') {
-        attributeDefs.size = { kind: 'float32', itemSize: 1, divisor:0 }
+        attributeDefs.size = { kind: 'float32', itemSize: 1, divisor: 0 }
     }
     return attributeDefs
 }
@@ -152,11 +159,11 @@ export function getBaseAttributeValues(props: BaseProps) {
     if (normal) {
         attributeValues.normal = normal.ref.value
     }
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'attribute') {
-        attributeValues.color = color.value.ref.value
+        attributeValues.color = color.data.ref.value
     }
-    const size = props.size ? props.size.ref.value : undefined
+    const size = props.size
     if (size && size.type === 'attribute') {
         attributeValues.size = size.value.ref.value
     }
@@ -165,7 +172,7 @@ export function getBaseAttributeValues(props: BaseProps) {
 
 export function getBaseTextureDefs(props: BaseProps) {
     const textureDefs: TextureDefs = {}
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
         textureDefs.colorTex = true
     }
@@ -174,9 +181,9 @@ export function getBaseTextureDefs(props: BaseProps) {
 
 export function getBaseTextureValues(props: BaseProps) {
     const textureValues: TextureValues = {}
-    const color = props.color.ref.value
+    const color = props.color
     if (color.type === 'instance' || color.type === 'element' || color.type === 'element-instance') {
-        textureValues.colorTex = color.value.ref.value
+        textureValues.colorTex = color.data.ref.value
     }
     return textureValues
 }

+ 36 - 34
src/mol-gl/renderer.ts

@@ -10,6 +10,7 @@ import { Camera } from 'mol-view/camera/base';
 
 import Scene, { RenderObject } from './scene';
 import { Context } from './webgl/context';
+import { Mat4, Vec3 } from 'mol-math/linear-algebra';
 
 export interface RendererStats {
     elementsCount: number
@@ -32,46 +33,50 @@ interface Renderer {
     dispose: () => void
 }
 
-// function getPixelRatio() {
-//     return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
-// }
+function getPixelRatio() {
+    return (typeof window !== 'undefined') ? window.devicePixelRatio : 1
+}
 
 namespace Renderer {
     export function create(ctx: Context, camera: Camera): Renderer {
         const { gl } = ctx
         const scene = Scene.create(ctx)
 
-        // const baseContext = regl({
-        //     context: {
-        //         model: Mat4.identity(),
-        //         transform: Mat4.identity(),
-        //         view: camera.view,
-        //         projection: camera.projection,
-        //     },
-        //     uniforms: {
-        //         pixelRatio: getPixelRatio(),
-        //         viewportHeight: regl.context('viewportHeight'),
-
-        //         model: regl.context('model' as any),
-        //         transform: regl.context('transform' as any),
-        //         view: regl.context('view' as any),
-        //         projection: regl.context('projection' as any),
-
-        //         'light.position': Vec3.create(0, 0, -100),
-        //         'light.color': Vec3.create(1.0, 1.0, 1.0),
-        //         'light.ambient': Vec3.create(0.5, 0.5, 0.5),
-        //         'light.falloff': 0,
-        //         'light.radius': 500
-        //     }
-        // })
+        const model = Mat4.identity()
+        const viewport = Viewport.create(0, 0, 0, 0)
+        const pixelRatio = getPixelRatio()
+
+        // const light_position = Vec3.create(0, 0, -100)
+        const light_color = Vec3.create(1.0, 1.0, 1.0)
+        const light_ambient = Vec3.create(0.5, 0.5, 0.5)
 
         const draw = () => {
             // TODO clear color
-            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
+            gl.enable(gl.DEPTH_TEST)
 
             // TODO painters sort, filter visible, filter picking, visibility culling?
+            let currentProgramId = -1
             scene.forEach((r, o) => {
-                if (o.visible) r.draw()
+                if (o.visible) {
+                    if (currentProgramId !== r.program.id) {
+                        r.program.use()
+                        r.program.setUniforms({
+                            model,
+                            view: camera.view,
+                            projection: camera.projection,
+
+                            pixelRatio,
+                            viewportHeight: viewport.height,
+
+                            // light_position,
+                            light_color,
+                            light_ambient,
+                        })
+                        currentProgramId = r.program.id
+                    }
+                    r.draw()
+                }
             })
         }
 
@@ -89,16 +94,13 @@ namespace Renderer {
                 scene.clear()
             },
             draw,
-            setViewport: (viewport: Viewport) => {
+            setViewport: (newViewport: Viewport) => {
+                Viewport.copy(viewport, newViewport)
                 gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height)
             },
             get stats() {
                 return {
-                    // elementsCount: regl.stats.elementsCount,
-                    // bufferCount: regl.stats.bufferCount,
-                    // textureCount: regl.stats.textureCount,
-                    // shaderCount: regl.stats.shaderCount,
-                    // renderableCount: scene.count
+                    renderableCount: scene.count
                 } as any
             },
             dispose: () => {

+ 9 - 19
src/mol-gl/shader/mesh.frag

@@ -6,15 +6,9 @@
 
 precision highp float;
 
-struct Light {
-    vec3 position;
-    vec3 color;
-    vec3 ambient;
-    float falloff;
-    float radius;
-};
-
-uniform Light light;
+// uniform vec3 light_position;
+uniform vec3 light_color;
+uniform vec3 light_ambient;
 uniform mat4 view;
 
 varying vec3 vNormal, vViewPosition;
@@ -35,22 +29,18 @@ void main() {
     #pragma glslify: import('./chunks/color-assign-material.glsl')
 
     // determine surface to light direction
-    // vec4 lightPosition = view * vec4(light.position, 1.0);
-    vec4 lightPosition = vec4(vec3(0.0, 0.0, -10000.0), 1.0);
-    vec3 lightVector = lightPosition.xyz - vViewPosition;
-
-    // calculate attenuation
-    // float lightDistance = length(lightVector);
-    float falloff = 1.0; // attenuation(light.radius, light.falloff, lightDistance);
+    // vec4 lightPosition = view * vec4(light_position, 1.0);
+    // vec3 lightVector = lightPosition.xyz - vViewPosition;
+    vec3 lightVector = vViewPosition;
 
     vec3 L = normalize(lightVector); // light direction
     vec3 V = normalize(vViewPosition); // eye direction
     vec3 N = normalize(-vNormal); // surface normal
 
     // compute our diffuse & specular terms
-    float specular = calculateSpecular(L, V, N, shininess) * specularScale * falloff;
-    vec3 diffuse = light.color * calculateDiffuse(L, V, N, roughness, albedo) * falloff;
-    vec3 ambient = light.ambient;
+    float specular = calculateSpecular(L, V, N, shininess) * specularScale;
+    vec3 diffuse = light_color * calculateDiffuse(L, V, N, roughness, albedo);
+    vec3 ambient = light_ambient;
 
     // add the lighting
     vec3 finalColor = material * (diffuse + ambient) + specular;

+ 1 - 1
src/mol-gl/shader/point.frag

@@ -10,5 +10,5 @@ precision highp float;
 
 void main(){
     #pragma glslify: import('./chunks/color-assign-material.glsl')
-    gl_FragColor = vec4(material, 1);
+    gl_FragColor = vec4(material, 1.0);
 }

+ 6 - 5
src/mol-gl/webgl/buffer.ts

@@ -117,7 +117,7 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte
             gl.bindBuffer(_bufferType, _buffer)
             gl.bufferSubData(_bufferType, offset * _bpe, array.subarray(offset, offset + count))
         },
-        
+
         destroy: () => {
             gl.bindBuffer(_bufferType, _buffer)
             // set size to 1 before deleting
@@ -128,7 +128,7 @@ export function createBuffer(ctx: Context, array: ArrayType, itemSize: BufferIte
 }
 
 export type AttributeDefs = {
-    [k: string]: { kind: ArrayKind, itemSize: BufferItemSize, divisor: number } 
+    [k: string]: { kind: ArrayKind, itemSize: BufferItemSize, divisor: number }
 }
 export type AttributeValues = { [k: string]: ArrayType }
 export type AttributeBuffers = { [k: string]: AttributeBuffer }
@@ -151,13 +151,14 @@ export function createAttributeBuffer<T extends ArrayType, S extends BufferItemS
             if (itemSize === 16) {
                 for (let i = 0; i < 4; ++i) {
                     gl.enableVertexAttribArray(location + i)
-                    gl.vertexAttribPointer(location + i, 4, _dataType, false, 4 * _bpe, i * _bpe)
+                    gl.vertexAttribPointer(location + i, 4, _dataType, false, 4 * 4 * _bpe, i * 4 * _bpe)
+                    angleInstancedArrays.vertexAttribDivisorANGLE(location + i, divisor)
                 }
             } else {
                 gl.enableVertexAttribArray(location)
                 gl.vertexAttribPointer(location, itemSize, _dataType, false, 0, 0)
+                angleInstancedArrays.vertexAttribDivisorANGLE(location, divisor)
             }
-            angleInstancedArrays.vertexAttribDivisorANGLE(location, divisor)
         }
     }
 }
@@ -171,7 +172,7 @@ export function createAttributeBuffers<T extends AttributeDefs>(ctx: Context, pr
 }
 
 export type ElementsType = Uint16Array | Uint32Array
-export type ElementsKind = 'uint16' | 'unit32'
+export type ElementsKind = 'uint16' | 'uint32'
 
 export interface ElementsBuffer extends Buffer {
     bind: () => void

+ 11 - 5
src/mol-gl/webgl/context.ts

@@ -39,14 +39,15 @@ function unbindResources (gl: WebGLRenderingContext) {
     gl.bindFramebuffer(gl.FRAMEBUFFER, null)
 }
 
-type RequiredExtensions = {
+type Extensions = {
     angleInstancedArrays: ANGLE_instanced_arrays
-    oesElementIndexUint: OES_element_index_uint
+    oesElementIndexUint: OES_element_index_uint | null
+    oesVertexArrayObject: OES_vertex_array_object | null
 }
 
 export interface Context {
     gl: WebGLRenderingContext
-    extensions: RequiredExtensions
+    extensions: Extensions
     shaderCache: ShaderCache
     programCache: ProgramCache
     destroy: () => void
@@ -59,11 +60,16 @@ export function createContext(gl: WebGLRenderingContext): Context {
     }
     const oesElementIndexUint = gl.getExtension('OES_element_index_uint')
     if (oesElementIndexUint === null) {
-        throw new Error('Could not get "OES_element_index_uint" extension')
+        console.warn('Could not get "OES_element_index_uint" extension')
     }
+    const oesVertexArrayObject = gl.getExtension('OES_vertex_array_object')
+    if (oesVertexArrayObject === null) {
+        console.log('Could not get "OES_vertex_array_object" extension')
+    }
+
     return {
         gl,
-        extensions: { angleInstancedArrays, oesElementIndexUint },
+        extensions: { angleInstancedArrays, oesElementIndexUint, oesVertexArrayObject },
         shaderCache: createShaderCache(),
         programCache: createProgramCache(),
         destroy: () => {

+ 20 - 10
src/mol-gl/webgl/program.ts

@@ -8,12 +8,16 @@ import { ShaderCode } from '../shader-code'
 import { Context } from './context';
 import { getUniformSetters, UniformDefs, UniformValues } from './uniform';
 import {AttributeDefs, AttributeBuffers } from './buffer';
-import { TextureId, TextureDefs, TextureUniforms, Textures } from './texture';
+import { TextureId, TextureDefs, TextureUniformDefs, Textures } from './texture';
 import { createReferenceCache, ReferenceCache } from 'mol-util/reference-cache';
+import { idFactory } from 'mol-util/id-factory';
+
+const getNextProgramId = idFactory()
 
 export interface Program {
     readonly id: number
 
+    use: () => void
     setUniforms: (uniformValues: UniformValues) => void
     bindAttributes: (attribueBuffers: AttributeBuffers) => void
     bindTextures: (textures: Textures) => void
@@ -29,16 +33,18 @@ function getAttributeLocations(ctx: Context, program: WebGLProgram, attributeDef
     gl.useProgram(program)
     Object.keys(attributeDefs).forEach(k => {
         const loc = gl.getAttribLocation(program, k)
-        gl.enableVertexAttribArray(loc)
+        if (loc === -1) {
+            console.info(`Could not get attribute location for '${k}'`)
+        }
         locations[k] = loc
     })
     return locations
 }
 
-function getTextureUniforms(textures: TextureDefs) {
-    const textureUniforms: TextureUniforms = {}
-    Object.keys(textureUniforms).forEach(k => textureUniforms[k] = 't2')
-    return textureUniforms
+function getTextureUniformDefs(textureDefs: TextureDefs) {
+    const textureUniformDefs: TextureUniformDefs = {}
+    Object.keys(textureDefs).forEach(k => textureUniformDefs[k] = 't2')
+    return textureUniformDefs
 }
 
 export interface ProgramProps {
@@ -66,14 +72,17 @@ export function createProgram(ctx: Context, props: ProgramProps): Program {
 
     const uniformSetters = getUniformSetters(ctx, program, uniformDefs)
     const attributeLocations = getAttributeLocations(ctx, program, attributeDefs)
-    const textureUniforms = getTextureUniforms(textureDefs)
-    const textureUniformSetters = getUniformSetters(ctx, program, textureUniforms)
+    const textureUniformDefs = getTextureUniformDefs(textureDefs)
+    const textureUniformSetters = getUniformSetters(ctx, program, textureUniformDefs)
 
     let destroyed = false
 
     return {
-        id: 0,
+        id: getNextProgramId(),
 
+        use: () => {
+            gl.useProgram(program)
+        },
         setUniforms: (uniformValues: UniformValues) => {
             Object.keys(uniformValues).forEach(k => {
                 const value = uniformValues[k]
@@ -82,7 +91,8 @@ export function createProgram(ctx: Context, props: ProgramProps): Program {
         },
         bindAttributes: (attribueBuffers: AttributeBuffers) => {
             Object.keys(attribueBuffers).forEach(k => {
-                attribueBuffers[k].bind(attributeLocations[k])
+                const loc = attributeLocations[k]
+                if (loc !== -1) attribueBuffers[k].bind(loc)
             })
         },
         bindTextures: (textures: Textures) => {

+ 20 - 7
src/mol-gl/webgl/render-item.ts

@@ -9,6 +9,7 @@ import { AttributeDefs, AttributeValues, createAttributeBuffers, createElementsB
 import { TextureDefs, TextureValues, createTextures } from './texture';
 import { Context } from './context';
 import { ShaderCode } from '../shader-code';
+import { Program } from './program';
 
 export type DrawMode = 'points' | 'lines' | 'line-strip' | 'line-loop' | 'triangles' | 'triangle-strip' | 'triangle-fan'
 
@@ -27,7 +28,7 @@ export function getDrawMode(ctx: Context, drawMode: DrawMode) {
 
 export type RenderItemProps = {
     shaderCode: ShaderCode
-    
+
     uniformDefs: UniformDefs
     attributeDefs: AttributeDefs
     textureDefs: TextureDefs
@@ -49,6 +50,7 @@ export type RenderItemState = {
 export interface RenderItem {
     readonly hash: string
     readonly programId: number
+    readonly program: Program
 
     update: (state: RenderItemState) => void
 
@@ -58,18 +60,25 @@ export interface RenderItem {
 
 export function createRenderItem(ctx: Context, props: RenderItemProps, state: RenderItemState): RenderItem {
     const { programCache } = ctx
-    const { angleInstancedArrays } = ctx.extensions
+    const { angleInstancedArrays, oesVertexArrayObject } = ctx.extensions
     const { shaderCode, uniformDefs, attributeDefs, textureDefs, elementsKind } = props
     const { attributeValues, textureValues, uniformValues, elements } = state
-    
+
     const hash = JSON.stringify(props)
     const drawMode = getDrawMode(ctx, props.drawMode)
     const programRef = programCache.get(ctx, { shaderCode, uniformDefs, attributeDefs, textureDefs })
     const program = programRef.value
 
-    const attributeBuffers = createAttributeBuffers(ctx, attributeDefs, attributeValues)
     const textures = createTextures(ctx, textureDefs, textureValues)
-    
+    const attributeBuffers = createAttributeBuffers(ctx, attributeDefs, attributeValues)
+
+    let vertexArray: WebGLVertexArrayObjectOES
+    if (oesVertexArrayObject) {
+        vertexArray = oesVertexArrayObject.createVertexArrayOES()
+        oesVertexArrayObject.bindVertexArrayOES(vertexArray)
+        program.bindAttributes(attributeBuffers)
+    }
+
     let elementsBuffer: ElementsBuffer
     if (elements && elementsKind) {
         elementsBuffer = createElementsBuffer(ctx, elements)
@@ -80,16 +89,20 @@ export function createRenderItem(ctx: Context, props: RenderItemProps, state: Re
     return {
         hash,
         programId: program.id,
+        program,
 
         draw: () => {
             program.setUniforms(uniformValues)
-            program.bindAttributes(attributeBuffers)
+            if (oesVertexArrayObject) {
+                oesVertexArrayObject.bindVertexArrayOES(vertexArray)
+            } else {
+                program.bindAttributes(attributeBuffers)
+            }
             program.bindTextures(textures)
             if (elementsBuffer) {
                 angleInstancedArrays.drawElementsInstancedANGLE(drawMode, drawCount, elementsBuffer._dataType, 0, instanceCount);
             } else {
                 angleInstancedArrays.drawArraysInstancedANGLE(drawMode, 0, drawCount, instanceCount)
-                // gl.drawArrays(drawMode, 0, drawCount)
             }
         },
         update: (state: RenderItemState) => {

+ 7 - 3
src/mol-gl/webgl/texture.ts

@@ -16,7 +16,7 @@ export interface Texture {
 export type TextureId = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
 
 export type TextureDefs = { [k: string]: true }
-export type TextureUniforms = { [k: string]: 't2' }
+export type TextureUniformDefs = { [k: string]: 't2' }
 export type TextureValues = { [k: string]: TextureImage }
 export type Textures = { [k: string]: Texture }
 
@@ -30,17 +30,21 @@ export function createTexture(ctx: Context): Texture {
     const _textureType = gl.TEXTURE_2D
     const _magFilter = gl.NEAREST
     const _minFilter = gl.NEAREST
-    const _format = gl.RGBA
+    const _format = gl.RGB
     const _arrayType = gl.UNSIGNED_BYTE
 
     return {
         load: (image: TextureImage) => {
             const { array, width, height } = image
             gl.bindTexture(_textureType, texture)
-            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)
+            // unpack alignment of 1 since we use textures only for data
+            gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
             gl.texImage2D(_textureType, 0, _format, width, height, 0, _format, _arrayType, array)
             gl.texParameteri(_textureType, gl.TEXTURE_MAG_FILTER, _magFilter)
             gl.texParameteri(_textureType, gl.TEXTURE_MIN_FILTER, _minFilter)
+            // clamp-to-edge needed for non-power-of-two textures
+            gl.texParameteri(_textureType, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+            gl.texParameteri(_textureType, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             gl.bindTexture(_textureType, null)
         },
         bind: (id: TextureId) => {

+ 3 - 3
src/mol-gl/webgl/uniform.ts

@@ -6,6 +6,7 @@
 
 import { Mat3, Mat4, Vec2, Vec3, Vec4 } from 'mol-math/linear-algebra'
 import { Context } from './context';
+import { TextureImage } from '../renderable/util';
 
 export type UniformKindValue = {
     'f': number
@@ -18,7 +19,7 @@ export type UniformKindValue = {
     't2': number
 }
 export type UniformKind = keyof UniformKindValue
-export type UniformType = number | Vec2 | Vec3 | Vec4 | Mat3 | Mat4 | ImageData
+export type UniformType = number | Vec2 | Vec3 | Vec4 | Mat3 | Mat4 | TextureImage
 
 export type UniformDefs = { [k: string]: UniformKind }
 export type UniformValues = { [k: string]: UniformType }
@@ -28,7 +29,7 @@ export function createUniformSetter(ctx: Context, program: WebGLProgram, name: s
     const { gl } = ctx
     const location = gl.getUniformLocation(program, name)
     if (location === null) {
-        throw new Error(`Could not get WebGL uniform location for '${name}'`)
+        console.info(`Could not get WebGL uniform location for '${name}'`)
     }
     switch (kind) {
         case 'f': return (value: number) => gl.uniform1f(location, value)
@@ -39,7 +40,6 @@ export function createUniformSetter(ctx: Context, program: WebGLProgram, name: s
         case 'm3': return (value: Mat3) => gl.uniformMatrix3fv(location, false, value)
         case 'm4': return (value: Mat4) => gl.uniformMatrix4fv(location, false, value)
     }
-    throw new Error('Should never happen')
 }
 
 export function getUniformSetters(ctx: Context, program: WebGLProgram, uniforms: UniformDefs) {

+ 10 - 0
src/mol-util/id-factory.ts

@@ -0,0 +1,10 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+export function idFactory() {
+    let _nextId = 0
+    return () => _nextId++
+}