engine.uniformBuffer.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import { ThinEngine } from "../../Engines/thinEngine";
  2. import { FloatArray, Nullable } from '../../types';
  3. import { DataBuffer } from '../../Meshes/dataBuffer';
  4. import { WebGLDataBuffer } from '../../Meshes/WebGL/webGLDataBuffer';
  5. import { IPipelineContext } from '../IPipelineContext';
  6. import { WebGLPipelineContext } from '../WebGL/webGLPipelineContext';
  7. declare module "../../Engines/thinEngine" {
  8. export interface ThinEngine {
  9. /**
  10. * Create an uniform buffer
  11. * @see https://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
  12. * @param elements defines the content of the uniform buffer
  13. * @returns the webGL uniform buffer
  14. */
  15. createUniformBuffer(elements: FloatArray): DataBuffer;
  16. /**
  17. * Create a dynamic uniform buffer
  18. * @see https://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
  19. * @param elements defines the content of the uniform buffer
  20. * @returns the webGL uniform buffer
  21. */
  22. createDynamicUniformBuffer(elements: FloatArray): DataBuffer;
  23. /**
  24. * Update an existing uniform buffer
  25. * @see https://doc.babylonjs.com/features/webgl2#uniform-buffer-objets
  26. * @param uniformBuffer defines the target uniform buffer
  27. * @param elements defines the content to update
  28. * @param offset defines the offset in the uniform buffer where update should start
  29. * @param count defines the size of the data to update
  30. */
  31. updateUniformBuffer(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void;
  32. /**
  33. * Bind an uniform buffer to the current webGL context
  34. * @param buffer defines the buffer to bind
  35. */
  36. bindUniformBuffer(buffer: Nullable<DataBuffer>): void;
  37. /**
  38. * Bind a buffer to the current webGL context at a given location
  39. * @param buffer defines the buffer to bind
  40. * @param location defines the index where to bind the buffer
  41. * @param name Name of the uniform variable to bind
  42. */
  43. bindUniformBufferBase(buffer: DataBuffer, location: number, name: string): void;
  44. /**
  45. * Bind a specific block at a given index in a specific shader program
  46. * @param pipelineContext defines the pipeline context to use
  47. * @param blockName defines the block name
  48. * @param index defines the index where to bind the block
  49. */
  50. bindUniformBlock(pipelineContext: IPipelineContext, blockName: string, index: number): void;
  51. }
  52. }
  53. ThinEngine.prototype.createUniformBuffer = function(elements: FloatArray): DataBuffer {
  54. var ubo = this._gl.createBuffer();
  55. if (!ubo) {
  56. throw new Error("Unable to create uniform buffer");
  57. }
  58. let result = new WebGLDataBuffer(ubo);
  59. this.bindUniformBuffer(result);
  60. if (elements instanceof Float32Array) {
  61. this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.STATIC_DRAW);
  62. } else {
  63. this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(<number[]>elements), this._gl.STATIC_DRAW);
  64. }
  65. this.bindUniformBuffer(null);
  66. result.references = 1;
  67. return result;
  68. };
  69. ThinEngine.prototype.createDynamicUniformBuffer = function(elements: FloatArray): DataBuffer {
  70. var ubo = this._gl.createBuffer();
  71. if (!ubo) {
  72. throw new Error("Unable to create dynamic uniform buffer");
  73. }
  74. let result = new WebGLDataBuffer(ubo);
  75. this.bindUniformBuffer(result);
  76. if (elements instanceof Float32Array) {
  77. this._gl.bufferData(this._gl.UNIFORM_BUFFER, <Float32Array>elements, this._gl.DYNAMIC_DRAW);
  78. } else {
  79. this._gl.bufferData(this._gl.UNIFORM_BUFFER, new Float32Array(<number[]>elements), this._gl.DYNAMIC_DRAW);
  80. }
  81. this.bindUniformBuffer(null);
  82. result.references = 1;
  83. return result;
  84. };
  85. ThinEngine.prototype.updateUniformBuffer = function(uniformBuffer: DataBuffer, elements: FloatArray, offset?: number, count?: number): void {
  86. this.bindUniformBuffer(uniformBuffer);
  87. if (offset === undefined) {
  88. offset = 0;
  89. }
  90. if (count === undefined) {
  91. if (elements instanceof Float32Array) {
  92. this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, <Float32Array>elements);
  93. } else {
  94. this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, offset, new Float32Array(<number[]>elements));
  95. }
  96. } else {
  97. if (elements instanceof Float32Array) {
  98. this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, <Float32Array>elements.subarray(offset, offset + count));
  99. } else {
  100. this._gl.bufferSubData(this._gl.UNIFORM_BUFFER, 0, new Float32Array(<number[]>elements).subarray(offset, offset + count));
  101. }
  102. }
  103. this.bindUniformBuffer(null);
  104. };
  105. ThinEngine.prototype.bindUniformBuffer = function(buffer: Nullable<DataBuffer>): void {
  106. this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);
  107. };
  108. ThinEngine.prototype.bindUniformBufferBase = function(buffer: DataBuffer, location: number, name: string): void {
  109. this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);
  110. };
  111. ThinEngine.prototype.bindUniformBlock = function(pipelineContext: IPipelineContext, blockName: string, index: number): void {
  112. let program = (pipelineContext as WebGLPipelineContext).program!;
  113. var uniformLocation = this._gl.getUniformBlockIndex(program, blockName);
  114. this._gl.uniformBlockBinding(program, uniformLocation, index);
  115. };