Skip to content

Commit 90e1517

Browse files
author
David
committed
WebGLTexture support on filters
1 parent 7bd477f commit 90e1517

4 files changed

Lines changed: 67 additions & 15 deletions

File tree

src/easeljs/filters/AlphaMapFilter.js

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,16 @@ this.createjs = this.createjs || {};
6464
* @class AlphaMapFilter
6565
* @extends Filter
6666
* @constructor
67-
* @param {HTMLImageElement|HTMLCanvasElement} alphaMap The greyscale image (or canvas) to use as the alpha value for the
67+
* @param {HTMLImageElement|HTMLCanvasElement|WebGLTexture} alphaMap The greyscale image (or canvas) to use as the alpha value for the
6868
* result. This should be exactly the same dimensions as the target.
6969
**/
7070
function AlphaMapFilter(alphaMap) {
7171
this.Filter_constructor();
72-
72+
73+
if (!Filter.isValidImageSource(alphaMap)) {
74+
throw "Must provide valid image source for alpha map, see Filter.isValidImageSource";
75+
}
76+
7377
// public properties:
7478
/**
7579
* The greyscale image (or canvas) to use as the alpha value for the result. This should be exactly the same
@@ -107,6 +111,10 @@ this.createjs = this.createjs || {};
107111
"gl_FragColor = vec4(color.rgb, color.a * (alphaMap.r * ceil(alphaMap.a)));" +
108112
"}"
109113
);
114+
115+
if(alphaMap instanceof WebGLTexture) {
116+
this._mapTexture = alphaMap;
117+
}
110118
}
111119
var p = createjs.extend(AlphaMapFilter, createjs.Filter);
112120

@@ -120,7 +128,9 @@ this.createjs = this.createjs || {};
120128
gl.activeTexture(gl.TEXTURE1);
121129
gl.bindTexture(gl.TEXTURE_2D, this._mapTexture);
122130
stage.setTextureParams(gl);
123-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.alphaMap);
131+
if (this.alphaMap !== this._mapTexture) {
132+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.alphaMap);
133+
}
124134

125135
gl.uniform1i(
126136
gl.getUniformLocation(shaderProgram, "uAlphaSampler"),
@@ -148,11 +158,14 @@ this.createjs = this.createjs || {};
148158
p._applyFilter = function (imageData) {
149159
if (!this.alphaMap) { return true; }
150160
if (!this._prepAlphaMap()) { return false; }
151-
152-
// TODO: update to support scenarios where the target has different dimensions.
161+
153162
var data = imageData.data;
154163
var map = this._mapData;
155-
for(var i=0, l=data.length; i<l; i += 4) { data[i + 3] = map[i] || 0; }
164+
165+
166+
for(var i=0, l=data.length; i<l; i += 4) {
167+
data[i + 3] = map[i] || 0;
168+
}
156169

157170
return true;
158171
};

src/easeljs/filters/AlphaMaskFilter.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,15 @@ this.createjs = this.createjs || {};
6464
* @class AlphaMaskFilter
6565
* @extends Filter
6666
* @constructor
67-
* @param {HTMLImageElement|HTMLCanvasElement} mask
67+
* @param {HTMLImageElement|HTMLCanvasElement|WebGLTexture} mask
6868
**/
6969
function AlphaMaskFilter(mask) {
7070
this.Filter_constructor();
71-
71+
72+
if (!Filter.isValidImageSource(mask)) {
73+
throw "Must provide valid image source for alpha mask, see Filter.isValidImageSource";
74+
}
75+
7276
// public properties:
7377
/**
7478
* The image (or canvas) to use as the mask.
@@ -103,7 +107,9 @@ this.createjs = this.createjs || {};
103107
gl.activeTexture(gl.TEXTURE1);
104108
gl.bindTexture(gl.TEXTURE_2D, this._mapTexture);
105109
stage.setTextureParams(gl);
106-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.mask);
110+
if (this.mask !== this._mapTexture) {
111+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.mask);
112+
}
107113

108114
gl.uniform1i(
109115
gl.getUniformLocation(shaderProgram, "uAlphaSampler"),

src/easeljs/filters/DisplacementFilter.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ this.createjs = this.createjs||{};
6060
* @class DisplacementFilter
6161
* @extends Filter
6262
* @constructor
63-
* @param {Image|HTMLCanvasElement} dudvMap The horizontal blur radius in pixels.
63+
* @param {HTMLImageElement|HTMLCanvasElement|WebGLTexture} dudvMap The horizontal blur radius in pixels.
6464
* @param {Number} [distance=0] The absolute value of the maximum possible displacement from the original pixel.
6565
**/
6666
function DisplacementFilter(dudvMap, distance) {
6767
this.Filter_constructor();
6868

69-
if (!dudvMap || !(dudvMap instanceof HTMLCanvasElement || dudvMap instanceof Image)) {
70-
throw "Must provide valid image source for displacement map (this can be a canvas)";
69+
if (!Filter.isValidImageSource(dudvMap)) {
70+
throw "Must provide valid image source for displacement map, see Filter.isValidImageSource";
7171
}
7272

7373
// public properties:
@@ -107,11 +107,13 @@ this.createjs = this.createjs||{};
107107
"}"
108108
);
109109

110-
if (dudvMap instanceof HTMLCanvasElement) {
110+
if(dudvMap instanceof WebGLTexture) {
111+
this._mapTexture = dudvMap;
112+
} else if (dudvMap instanceof HTMLCanvasElement) {
111113
this._dudvCanvas = dudvMap;
112114
this._dudvCtx = dudvMap.getContext("2d");
113115
} else {
114-
var canvas = this._dudvCanvas = document.createElement("canvas");
116+
var canvas = this._dudvCanvas = createjs.createCanvas ? createjs.createCanvas() : document.createElement("canvas");
115117
canvas.width = dudvMap.width;
116118
canvas.height = dudvMap.height;
117119
(this._dudvCtx = canvas.getContext("2d")).drawImage(dudvMap);
@@ -128,7 +130,9 @@ this.createjs = this.createjs||{};
128130
gl.activeTexture(gl.TEXTURE1);
129131
gl.bindTexture(gl.TEXTURE_2D, this._mapTexture);
130132
stage.setTextureParams(gl);
131-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.dudvMap);
133+
if (this.dudvMap !== this._mapTexture) {
134+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.dudvMap);
135+
}
132136

133137
gl.uniform1i(
134138
gl.getUniformLocation(shaderProgram, "uDudvSampler"),

src/easeljs/filters/Filter.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,19 @@ this.createjs = this.createjs||{};
5555
* margins that need to be applied in order to fully display the filter. For example, the {{#crossLink "BlurFilter"}}{{/crossLink}}
5656
* will cause an object to feather outwards, resulting in a margin around the shape.
5757
*
58+
* Any filter that consumes an external image stretches the image to cover the cached bounds. If this is an undesired
59+
* visual result, then use an intermediary cache to properly size and layout your data before passing it to a filter.
60+
*
5861
* <h4>EaselJS Filters</h4>
5962
* EaselJS comes with a number of pre-built filters:
6063
* <ul>
64+
* <li>{{#crossLink "AberrationFilter"}}{{/crossLink}} : Shift the RGB components separately along a given vector</li>
6165
* <li>{{#crossLink "AlphaMapFilter"}}{{/crossLink}} : Map a greyscale image to the alpha channel of a display object</li>
6266
* <li>{{#crossLink "AlphaMaskFilter"}}{{/crossLink}}: Map an image's alpha channel to the alpha channel of a display object</li>
6367
* <li>{{#crossLink "BlurFilter"}}{{/crossLink}}: Apply vertical and horizontal blur to a display object</li>
6468
* <li>{{#crossLink "ColorFilter"}}{{/crossLink}}: Color transform a display object</li>
6569
* <li>{{#crossLink "ColorMatrixFilter"}}{{/crossLink}}: Transform an image using a {{#crossLink "ColorMatrix"}}{{/crossLink}}</li>
70+
* <li>{{#crossLink "DisplacementFilter"}}{{/crossLink}}: Create localized distortions in supplied display object</li>
6671
* </ul>
6772
*
6873
* @class Filter
@@ -106,6 +111,30 @@ this.createjs = this.createjs||{};
106111
}
107112
var p = Filter.prototype;
108113

114+
// static methods:
115+
/**
116+
* Check to see if an image source being provided is one that is valid.
117+
* <h4>Valid Sources:</h4>
118+
* <ul>
119+
* <li>Image Object</li>
120+
* <li>HTML Canvas Element</li>
121+
* <li>`.cacheCanvas` on an object with the same stage</li>
122+
* </ul>
123+
* WebGLTextures CANNOT be shared between multiple WebGL contexts. This means the only safe source for a WebGLTexture
124+
* is an object cached using the same StageGL as the object trying to use it in a filter. This function does not
125+
* enforce that restriction, as it is difficult or expensive to detect. The render will crash or fail to load the
126+
* image data if the rule isn't followed.
127+
* @param {HTMLImageElement|HTMLCanvasElement|WebGLTexture} src The element to check for validity
128+
* @return Boolean Whether the source is valid
129+
*/
130+
Filter.isValidImageSource = function(src) {
131+
return Boolean(src) && (
132+
src instanceof Image ||
133+
src instanceof WebGLTexture ||
134+
src instanceof HTMLCanvasElement
135+
);
136+
};
137+
109138
// public methods:
110139
/**
111140
* Provides padding values for this filter. That is, how much the filter will extend the visual bounds of an object it is applied to.

0 commit comments

Comments
 (0)