uniform.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**
  2. * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  3. *
  4. * @author Alexander Rose <alexander.rose@weirdbyte.de>
  5. */
  6. import { Mat3, Mat4, Vec2, Vec3, Vec4 } from '../../mol-math/linear-algebra';
  7. import { ValueCell } from '../../mol-util';
  8. import { GLRenderingContext } from './compat';
  9. import { RenderableSchema } from '../../mol-gl/renderable/schema';
  10. import { ValueOf } from '../../mol-util/type-helpers';
  11. export type UniformKindValue = {
  12. 'b': boolean; 'b[]': boolean[]
  13. 'f': number; 'f[]': number[]
  14. 'i': number; 'i[]': number[]
  15. 'v2': Vec2; 'v2[]': number[]
  16. 'v3': Vec3; 'v3[]': number[]
  17. 'v4': Vec4; 'v4[]': number[]
  18. 'm3': Mat3; 'm3[]': number[]
  19. 'm4': Mat4; 'm4[]': number[]
  20. 't': number; 't[]': number[]
  21. }
  22. export type UniformKind = keyof UniformKindValue
  23. export type UniformType = ValueOf<UniformKindValue>
  24. export type UniformValues = { [k: string]: ValueCell<UniformType> }
  25. export type UniformsList = [string, ValueCell<UniformType>][]
  26. export function getUniformType(gl: GLRenderingContext, kind: UniformKind) {
  27. switch (kind) {
  28. case 'b': case 'b[]': return gl.BOOL;
  29. case 'f': case 'f[]': return gl.FLOAT;
  30. case 'i': case 'i[]': return gl.INT;
  31. case 'v2': case 'v2[]': return gl.FLOAT_VEC2;
  32. case 'v3': case 'v3[]': return gl.FLOAT_VEC3;
  33. case 'v4': case 'v4[]': return gl.FLOAT_VEC4;
  34. case 'm3': case 'm3[]': return gl.FLOAT_MAT3;
  35. case 'm4': case 'm4[]': return gl.FLOAT_MAT4;
  36. default: console.error(`unknown uniform kind '${kind}'`);
  37. }
  38. }
  39. export type UniformSetter = (gl: GLRenderingContext, location: number, value: any) => void
  40. export type UniformSetters = { [k: string]: UniformSetter }
  41. function uniform1f (gl: GLRenderingContext, location: number, value: any) { gl.uniform1f(location, value); }
  42. function uniform1fv (gl: GLRenderingContext, location: number, value: any) { gl.uniform1fv(location, value); }
  43. function uniform1i (gl: GLRenderingContext, location: number, value: any) { gl.uniform1i(location, value); }
  44. function uniform1iv (gl: GLRenderingContext, location: number, value: any) { gl.uniform1iv(location, value); }
  45. function uniform2fv (gl: GLRenderingContext, location: number, value: any) { gl.uniform2fv(location, value); }
  46. function uniform3fv (gl: GLRenderingContext, location: number, value: any) { gl.uniform3fv(location, value); }
  47. function uniform4fv (gl: GLRenderingContext, location: number, value: any) { gl.uniform4fv(location, value); }
  48. function uniformMatrix3fv (gl: GLRenderingContext, location: number, value: any) { gl.uniformMatrix3fv(location, false, value); }
  49. function uniformMatrix4fv (gl: GLRenderingContext, location: number, value: any) { gl.uniformMatrix4fv(location, false, value); }
  50. function getUniformSetter(kind: UniformKind): UniformSetter {
  51. switch (kind) {
  52. case 'f': return uniform1f;
  53. case 'f[]': return uniform1fv;
  54. case 'i': case 't': case 'b': return uniform1i;
  55. case 'i[]': case 't[]': case 'b[]': return uniform1iv;
  56. case 'v2': case 'v2[]': return uniform2fv;
  57. case 'v3': case 'v3[]': return uniform3fv;
  58. case 'v4': case 'v4[]': return uniform4fv;
  59. case 'm3': case 'm3[]': return uniformMatrix3fv;
  60. case 'm4': case 'm4[]': return uniformMatrix4fv;
  61. }
  62. }
  63. export function getUniformSetters(schema: RenderableSchema) {
  64. const setters: UniformSetters = {};
  65. Object.keys(schema).forEach(k => {
  66. const spec = schema[k];
  67. if (spec.type === 'uniform') {
  68. setters[k] = getUniformSetter(spec.kind);
  69. } else if (spec.type === 'texture') {
  70. setters[k] = getUniformSetter('t');
  71. }
  72. });
  73. return setters;
  74. }
  75. export function getUniformGlslType(kind: UniformKind): string {
  76. switch (kind) {
  77. case 'f': return 'float';
  78. case 'i': return 'int';
  79. case 't': return 'sampler2D';
  80. case 'b': return 'bool';
  81. case 'v2': return 'vec2';
  82. case 'v3': return 'vec3';
  83. case 'v4': return 'vec4';
  84. case 'm3': return 'mat3';
  85. case 'm4': return 'mat4';
  86. }
  87. throw new Error(`${kind} has no primitive GLSL type.`);
  88. }
  89. export function isUniformValueScalar(kind: UniformKind): boolean {
  90. switch (kind) {
  91. case 'f':
  92. case 'i':
  93. case 'b':
  94. return true;
  95. default:
  96. return false;
  97. }
  98. }