From 5b2ec72ba412f8d6d5b511fd73674473b2acbd03 Mon Sep 17 00:00:00 2001 From: 1chandu Date: Sat, 7 Sep 2019 16:10:52 -0700 Subject: [PATCH] Add docs and, minor code cleanup --- .../core/transform/buffer-transform.md | 78 +++++++++++++++++++ .../core/transform/texture-transform.md | 67 ++++++++++++++++ .../src/lib/transform/buffer-transform.js | 11 ++- .../src/lib/transform/texture-transform.js | 42 +++++----- modules/core/src/lib/transform/transform.js | 6 +- .../lib/transform/buffer-transform.spec.js | 6 +- 6 files changed, 177 insertions(+), 33 deletions(-) create mode 100644 docs/api-reference/core/transform/buffer-transform.md create mode 100644 docs/api-reference/core/transform/texture-transform.md diff --git a/docs/api-reference/core/transform/buffer-transform.md b/docs/api-reference/core/transform/buffer-transform.md new file mode 100644 index 0000000000..876644967e --- /dev/null +++ b/docs/api-reference/core/transform/buffer-transform.md @@ -0,0 +1,78 @@ +# BufferTransform + +`BufferTransform` is an internal helper class for `Transform`, responsible for managing resources and state required for reading from and/or writing to `Buffer` objects. It auto creates `feedbackBufferes` when requested, creates `TransformFeedback` objects. Maintains all buffer bindings, when swapping is eanbled, two binding objects are created for easy switching of all WebGL resource binginds. + +NOTE: In following sections 'buffer transform' is used to refer to 'reading from and/or writing to `Buffer` objects'. + +## Constructor + +### Transform(gl : WebGL2RenderingContext, props: Object) + +* `gl` (`WebGLRenderingContext`) gl - context +* `props` (`Object`, Optional) - contains following data. + * `sourceBuffers` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding `Attribute`, `Buffer` or attribute descriptor object. + * `feedbackBuffers` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader varying and value is the corresponding `Buffer` object or buffer params object. If a buffer params object is specified, it will contain following fields, these can be used to capture data into the buffer at particular offset and size. + * `buffer`=(Buffer) - Buffer object to be bound. + * `byteOffset`=(Number, default: 0) - Byte offset that is used to start recording the data in the buffer. + * `byteSize`=(Number, default: remaining buffer size) - Size in bytes that is used for recording the data. + * `varyings` (`Array`, Optional) - Array of vertex shader varyings names. When not provided this can be deduced from `feedbackBuffers`. + + NOTE: If only reading from `Buffer` objects, above optional props doesn't have to be supplied during construction, but can be supplied using `update` method. If writing to `Buffer` objects, either `varyings` or `feedbackBuffers` must be supplied. + + +## Methods (Model props) + +### getDrawOptions(opts: Object) : Object + +Returns resources required when performing `Model.draw()` options. + +* `opts` (`Object`) - Any existing `opts.attributes` will be merged with new attributes. + +Returns an Object : {attributes, transformFeedback}. + +### updateModelProps(props: Object) : Object + +Updates input `props` object with data required for buffer transform. + + * `opts` (`Object`) - If writing to `Buffer` objects, `opts.varying` will be updated. + +Returns updated object. + +## Methods (Resource management) + +### setupResources(opts: Object) + +Sets up internal resources needed writing to buffers. + + * `opts` (`Object`) - contains following data. + * `model` (`Model`, Optional) - `Model` object that is used to perform draw operations. + +### swap() + +If `feedbackMap` is provided during construction, performs source and feedback buffers swap as per the `feedbackMap`. + +### update(props: Object) + +Updates buffer bindings for one or more source or feedback buffers. + + * `props` (`Object`) - contains following data. + * `sourceBuffers` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding `Attribute`, `Buffer` or attribute descriptor object. + * `feedbackBuffers` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader varying and value is the corresponding `Buffer` object or buffer params object. If a buffer params object is specified, it will contain following fields, these can be used to capture data into the buffer at particular offset and size. + * `buffer`=(Buffer) - Buffer object to be bound. + * `byteOffset`=(Number, default: 0) - Byte offset that is used to start recording the data in the buffer. + * `byteSize`=(Number, default: remaining buffer size) - Size in bytes that is used for recording the data. + + +## Methods (Accessors) + +### getBuffer(varyingName : String) : Buffer + +Returns current feedback buffer corresponding to given varying name. + + * `varyingName` (`String`) - varying name. + +### getData([options : Object]) : ArrayBufferView + +Reads and returns data from current feedback buffer corresponding to the given varying name. + + * `options.varyingName` (`String`, Optional) - when specified, first checks if there is a corresponding feedback buffer, if so reads data from this buffer and returns. When not specified, there must be target texture and data is read from this texture and returned. diff --git a/docs/api-reference/core/transform/texture-transform.md b/docs/api-reference/core/transform/texture-transform.md new file mode 100644 index 0000000000..e7fc5d0eac --- /dev/null +++ b/docs/api-reference/core/transform/texture-transform.md @@ -0,0 +1,67 @@ +# TextureTransform + +`TextureTransform` is an internal helper class for `Transform`, responsible for managing resources and state required for reading from and/or writing to `Texture` objects. It auto creates `Texture` objects when requested, creates `Framebuffer` objects. Maintains all texture bindings, when swapping is eanbled, two binding objects are created for easy switching of all WebGL resource binginds. + +NOTE: In following sections 'texture transform' is used to refer to 'reading from and/or writing to `Texture` objects'. + +## Constructor + +### Transform(gl : WebGL2RenderingContext, props: Object) + +* `gl` (`WebGLRenderingContext`) gl - context +* `props` (`Object`, Optional) - contains following data. + * `sourceTextures` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding `Texture` object. + * `targetTexture` (`Texture`|`String`, Optional) - `Texture` object to which data to be written. When it is a `String`, it must be one of the source texture attributes name, a new texture object is cloned from it. + * `targetTextureVarying` (`String`) : varying name used in vertex shader who's data should go into target texture. + * `swapTexture` (`String`) : source texture attribute name, that is swapped with target texture every time `swap()` is called. + * `fs` (`String`, Optional) - fragment shader string, when rendering to a texture, fragments can be processed using this custom shader, when not specified, pass through fragment shader will be used. + + +## Methods (Model props) + +### getDrawOptions(opts: Object) : Object + +Returns options required when performing `Model.draw()` options. + +* `opts` (`Object`) - Any existing `opts.attributes` , `opts.parameters`, and `opts.uniforms` will be merged with new values. + +Returns an Object : {attributes, framebuffer, uniforms, discard, parameters}. + +### updateModelProps(props: Object) : Object + +Updates input `props` object used to build `Model` object, with data required for texture transform. + + * `props` (`Object`) - props for building `Model` object, it will updated with required options (`{vs, fs, modules, uniforms, inject}`) for texture transform. + +Returns updated object. + +## Methods (Resource management) + +### swap() + +If `swapTexture` is provided during construction, performs source and feedback buffers swap as per the `swapTexture` mapping. + +### update(props: Object) + +Updates bindings for source and target texture. + + * `props` (`Object`) - contains following data. + * `sourceTextures` (`Object`, Optional) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding `Texture` object. + * `targetTexture` (`Texture`|`String`, Optional) - `Texture` object to which data to be written. When it is a `String`, it must be one of the source texture attributes name, a new texture object is cloned from it. + + +## Methods (Accessors) + +### getTargetTexture() : Texture + +Returns current target texture object. + +### getData([options : Object]) : ArrayBufferView + +Reads and returns data from current target texture. + + * `options.packed` (Boolean, Optional, Default: false) - When true, data is packed to the actual size varyings. When false return array contains 4 values (R, G, B and A) for each element. Un-used element value will be 0 for R, G and B and 1 for A channel. + +### getFramebuffer() : Framebuffer + +Returns current `Framebuffer` object. diff --git a/modules/core/src/lib/transform/buffer-transform.js b/modules/core/src/lib/transform/buffer-transform.js index 278fab85c1..d427ee4772 100644 --- a/modules/core/src/lib/transform/buffer-transform.js +++ b/modules/core/src/lib/transform/buffer-transform.js @@ -21,9 +21,12 @@ export default class BufferTransform { } } - getModelProps(props = {}) { + updateModelProps(props = {}) { const {varyings} = this; - return Object.assign({}, props, {varyings}); + if (varyings.length > 0) { + props = Object.assign({}, props, {varyings}); + } + return props; } getDrawOptions(opts = {}) { @@ -48,7 +51,7 @@ export default class BufferTransform { } // returns current feedbackBuffer of given name - getBuffer(varyingName = null) { + getBuffer(varyingName) { const {feedbackBuffers} = this.bindings[this.currentIndex]; const bufferOrParams = varyingName ? feedbackBuffers[varyingName] : null; if (!bufferOrParams) { @@ -57,7 +60,7 @@ export default class BufferTransform { return bufferOrParams instanceof Buffer ? bufferOrParams : bufferOrParams.buffer; } - getData({varyingName = null} = {}) { + getData({varyingName} = {}) { const buffer = this.getBuffer(varyingName); if (buffer) { return buffer.getData(); diff --git a/modules/core/src/lib/transform/texture-transform.js b/modules/core/src/lib/transform/texture-transform.js index 91ed17b402..e985b87068 100644 --- a/modules/core/src/lib/transform/texture-transform.js +++ b/modules/core/src/lib/transform/texture-transform.js @@ -41,7 +41,7 @@ export default class TextureTransform { Object.seal(this); } - getModelProps(props = {}) { + updateModelProps(props = {}) { const updatedModelProps = this._processVertexShader(props); return Object.assign({}, props, updatedModelProps); } @@ -68,7 +68,7 @@ export default class TextureTransform { targetTextureVarying: this.targetTextureVarying, targetTexture }); - Object.assign(uniforms, sizeUniforms, discard); + Object.assign(uniforms, sizeUniforms); } if (this.hasTargetTexture) { @@ -76,7 +76,7 @@ export default class TextureTransform { parameters.viewport = [0, 0, framebuffer.width, framebuffer.height]; } - return Object.assign(opts, {attributes, framebuffer, uniforms, discard, parameters}); + return {attributes, framebuffer, uniforms, discard, parameters}; } swap() { @@ -98,29 +98,25 @@ export default class TextureTransform { return targetTexture; } - getData({varyingName = null, packed = false} = {}) { - if (!varyingName || varyingName === this.targetTextureVarying) { - const {framebuffer} = this.bindings[this.currentIndex]; - const pixels = readPixelsToArray(framebuffer); + getData({packed = false} = {}) { + const {framebuffer} = this.bindings[this.currentIndex]; + const pixels = readPixelsToArray(framebuffer); - if (!packed) { - return pixels; - } + if (!packed) { + return pixels; + } - // readPixels returns 4 elements for each pixel, pack the elements when requested - const ArrayType = pixels.constructor; - const channelCount = typeToChannelCount(this.targetTextureType); - const packedPixels = new ArrayType((pixels.length * channelCount) / 4); - let packCount = 0; - for (let i = 0; i < pixels.length; i += 4) { - for (let j = 0; j < channelCount; j++) { - packedPixels[packCount++] = pixels[i + j]; - } + // readPixels returns 4 elements for each pixel, pack the elements when requested + const ArrayType = pixels.constructor; + const channelCount = typeToChannelCount(this.targetTextureType); + const packedPixels = new ArrayType((pixels.length * channelCount) / 4); + let packCount = 0; + for (let i = 0; i < pixels.length; i += 4) { + for (let j = 0; j < channelCount; j++) { + packedPixels[packCount++] = pixels[i + j]; } - return packedPixels; } - - return null; + return packedPixels; } // returns current framebuffer object that is being used. @@ -320,6 +316,6 @@ export default class TextureTransform { this.hasSourceTextures || this.targetTextureVarying ? [transformModule].concat(props.modules || []) : props.modules; - return {vs, fs, modules, uniforms, inject: combinedInject, samplerTextureMap}; + return {vs, fs, modules, uniforms, inject: combinedInject}; } } diff --git a/modules/core/src/lib/transform/transform.js b/modules/core/src/lib/transform/transform.js index ad7cb5bc20..d3a4a5b174 100644 --- a/modules/core/src/lib/transform/transform.js +++ b/modules/core/src/lib/transform/transform.js @@ -96,7 +96,7 @@ export default class Transform { const {gl} = this; this._buildResourceTransforms(gl, props); - props = this._getModelProps(props); + props = this._updateModelProps(props); this.model = new Model( gl, Object.assign({}, props, { @@ -112,11 +112,11 @@ export default class Transform { /* eslint-enable no-unused-expressions */ } - _getModelProps(props) { + _updateModelProps(props) { let updatedProps = Object.assign({}, props); const resourceTransforms = [this.bufferTransform, this.textureTransform].filter(Boolean); for (const resourceTransform of resourceTransforms) { - updatedProps = resourceTransform.getModelProps(updatedProps); + updatedProps = resourceTransform.updateModelProps(updatedProps); } return updatedProps; } diff --git a/modules/core/test/lib/transform/buffer-transform.spec.js b/modules/core/test/lib/transform/buffer-transform.spec.js index 876c490bf2..bd0180ad55 100644 --- a/modules/core/test/lib/transform/buffer-transform.spec.js +++ b/modules/core/test/lib/transform/buffer-transform.spec.js @@ -98,7 +98,7 @@ test('WebGL#BufferTransform feedbackBuffer with referece', t => { t.end(); }); -test('WebGL#BufferTransform getModelProps', t => { +test('WebGL#BufferTransform updateModelProps', t => { const gl = fixture.gl2; if (!gl) { t.comment('WebGL2 not available, skipping tests'); @@ -119,7 +119,7 @@ test('WebGL#BufferTransform getModelProps', t => { }, varyings: cutomVaryings }); - let {varyings} = bt.getModelProps(); + let {varyings} = bt.updateModelProps(); t.deepEqual(varyings, cutomVaryings, 'should use custom varyings when provided'); bt.delete(); @@ -132,7 +132,7 @@ test('WebGL#BufferTransform getModelProps', t => { } }); - ({varyings} = bt.getModelProps({})); + ({varyings} = bt.updateModelProps({})); t.deepEqual( varyings, ['feedback'],