Skip to content

Commit

Permalink
Add docs and, minor code cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
1chandu committed Sep 7, 2019
1 parent a7d2a50 commit 5b2ec72
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 33 deletions.
78 changes: 78 additions & 0 deletions 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.
67 changes: 67 additions & 0 deletions 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.
11 changes: 7 additions & 4 deletions modules/core/src/lib/transform/buffer-transform.js
Expand Up @@ -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 = {}) {
Expand All @@ -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) {
Expand All @@ -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();
Expand Down
42 changes: 19 additions & 23 deletions modules/core/src/lib/transform/texture-transform.js
Expand Up @@ -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);
}
Expand All @@ -68,15 +68,15 @@ export default class TextureTransform {
targetTextureVarying: this.targetTextureVarying,
targetTexture
});
Object.assign(uniforms, sizeUniforms, discard);
Object.assign(uniforms, sizeUniforms);
}

if (this.hasTargetTexture) {
discard = false;
parameters.viewport = [0, 0, framebuffer.width, framebuffer.height];
}

return Object.assign(opts, {attributes, framebuffer, uniforms, discard, parameters});
return {attributes, framebuffer, uniforms, discard, parameters};
}

swap() {
Expand All @@ -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.
Expand Down Expand Up @@ -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};
}
}
6 changes: 3 additions & 3 deletions modules/core/src/lib/transform/transform.js
Expand Up @@ -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, {
Expand All @@ -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;
}
Expand Down
6 changes: 3 additions & 3 deletions modules/core/test/lib/transform/buffer-transform.spec.js
Expand Up @@ -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');
Expand All @@ -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();
Expand All @@ -132,7 +132,7 @@ test('WebGL#BufferTransform getModelProps', t => {
}
});

({varyings} = bt.getModelProps({}));
({varyings} = bt.updateModelProps({}));
t.deepEqual(
varyings,
['feedback'],
Expand Down

0 comments on commit 5b2ec72

Please sign in to comment.