WebGL masking issue fixed
WebGL mask objects can now be nested within masked objects
This commit is contained in:
parent
932ca80032
commit
85f1bd6557
9 changed files with 233 additions and 36 deletions
|
@ -4114,6 +4114,7 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
|
||||||
|
|
||||||
PIXI.deactivatePrimitiveShader();
|
PIXI.deactivatePrimitiveShader();
|
||||||
|
|
||||||
|
|
||||||
// return to default shader...
|
// return to default shader...
|
||||||
// PIXI.activateShader(PIXI.defaultShader);
|
// PIXI.activateShader(PIXI.defaultShader);
|
||||||
}
|
}
|
||||||
|
@ -5774,6 +5775,12 @@ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flip = false;
|
||||||
|
var maskStack = [];
|
||||||
|
var maskPosition = 0;
|
||||||
|
|
||||||
|
//var usedMaskStack = [];
|
||||||
|
|
||||||
PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
|
PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -5785,24 +5792,27 @@ PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projec
|
||||||
{
|
{
|
||||||
if(filterBlock.data instanceof Array)
|
if(filterBlock.data instanceof Array)
|
||||||
{
|
{
|
||||||
//var filter = filterBlock.data[0];
|
this.filterManager.pushFilter(filterBlock);
|
||||||
//console.log(filter)
|
|
||||||
this.filterManager.pushFilter(filterBlock);//filter);
|
|
||||||
// ok so..
|
// ok so..
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
maskPosition++;
|
||||||
|
|
||||||
|
maskStack.push(filterBlock)
|
||||||
|
|
||||||
gl.enable(gl.STENCIL_TEST);
|
gl.enable(gl.STENCIL_TEST);
|
||||||
|
|
||||||
gl.colorMask(false, false, false, false);
|
gl.colorMask(false, false, false, false);
|
||||||
gl.stencilFunc(gl.ALWAYS,1,0xff);
|
|
||||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
|
gl.stencilFunc(gl.ALWAYS,1,1);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
|
||||||
|
|
||||||
PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
|
PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
|
||||||
|
|
||||||
gl.colorMask(true, true, true, true);
|
gl.colorMask(true, true, true, true);
|
||||||
gl.stencilFunc(gl.NOTEQUAL,0,0xff);
|
gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
|
||||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5811,11 +5821,26 @@ PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projec
|
||||||
if(filterBlock.data instanceof Array)
|
if(filterBlock.data instanceof Array)
|
||||||
{
|
{
|
||||||
this.filterManager.popFilter();
|
this.filterManager.popFilter();
|
||||||
// PIXI.popShader();
|
|
||||||
// gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
var maskData = maskStack.pop(filterBlock)
|
||||||
|
|
||||||
|
|
||||||
|
if(maskData)
|
||||||
|
{
|
||||||
|
gl.colorMask(false, false, false, false);
|
||||||
|
|
||||||
|
gl.stencilFunc(gl.ALWAYS,1,1);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
|
||||||
|
|
||||||
|
PIXI.WebGLGraphics.renderGraphics(maskData.data, projection);
|
||||||
|
|
||||||
|
gl.colorMask(true, true, true, true);
|
||||||
|
gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||||
|
};
|
||||||
|
|
||||||
gl.disable(gl.STENCIL_TEST);
|
gl.disable(gl.STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -27,14 +27,14 @@
|
||||||
bg.position.x = 620/2;
|
bg.position.x = 620/2;
|
||||||
bg.position.y = 380/2;
|
bg.position.y = 380/2;
|
||||||
|
|
||||||
stage.addChild(bg);
|
//stage.addChild(bg);
|
||||||
|
|
||||||
|
|
||||||
var bgFront = PIXI.Sprite.fromImage("SceneRotate.jpg");
|
var bgFront = PIXI.Sprite.fromImage("SceneRotate.jpg");
|
||||||
bgFront.anchor.x = 0.5;
|
bgFront.anchor.x = 0.5;
|
||||||
bgFront.anchor.y = 0.5;
|
bgFront.anchor.y = 0.5;
|
||||||
|
|
||||||
stage.addChild(bgFront);
|
//stage.addChild(bgFront);
|
||||||
|
|
||||||
// create a renderer instance
|
// create a renderer instance
|
||||||
var renderer = PIXI.autoDetectRenderer(620, 380);
|
var renderer = PIXI.autoDetectRenderer(620, 380);
|
||||||
|
@ -53,15 +53,21 @@
|
||||||
|
|
||||||
var mask1 = new PIXI.Graphics();
|
var mask1 = new PIXI.Graphics();
|
||||||
mask1.beginFill(0);
|
mask1.beginFill(0);
|
||||||
mask1.drawRect(0, 0, 100, 100)
|
mask1.drawRect(0, 0, 150, 100)
|
||||||
|
|
||||||
bgFront.mask = mask1;
|
bgFront.mask = mask1;
|
||||||
|
|
||||||
var mask2 = new PIXI.Graphics();
|
var mask2 = new PIXI.Graphics();
|
||||||
mask2.beginFill(0);
|
mask2.beginFill(0);
|
||||||
mask2.drawRect(500, 100, 100, 100)
|
mask2.drawRect(20, 50, 300, 100)
|
||||||
|
|
||||||
bg.mask = mask2;
|
var container = new PIXI.DisplayObjectContainer();
|
||||||
|
stage.addChild(container);
|
||||||
|
container.addChild(bg);
|
||||||
|
container.addChild(bgFront)
|
||||||
|
|
||||||
|
|
||||||
|
container.mask = mask2;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
stage.click = stage.tap = function()
|
stage.click = stage.tap = function()
|
||||||
|
|
138
examples/example 14 - Masking/index nested masks.html
Normal file
138
examples/example 14 - Masking/index nested masks.html
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>pixi.js example 14 - Masking</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="../../bin/pixi.dev.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
// create an new instance of a pixi stage
|
||||||
|
var stage = new PIXI.Stage(0xFFFFFF, true);
|
||||||
|
|
||||||
|
stage.interactive = true;
|
||||||
|
|
||||||
|
var bg = PIXI.Sprite.fromImage("BGrotate.jpg");
|
||||||
|
bg.anchor.x = 0.5;
|
||||||
|
bg.anchor.y = 0.5;
|
||||||
|
|
||||||
|
bg.position.x = 620/2;
|
||||||
|
bg.position.y = 380/2;
|
||||||
|
|
||||||
|
//stage.addChild(bg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//stage.addChild(bgFront);
|
||||||
|
|
||||||
|
// create a renderer instance
|
||||||
|
var renderer = PIXI.autoDetectRenderer(620, 380);
|
||||||
|
|
||||||
|
renderer.view.style.position = "absolute"
|
||||||
|
renderer.view.style.marginLeft = "-310px";
|
||||||
|
renderer.view.style.marginTop = "-190px";
|
||||||
|
renderer.view.style.top = "50%";
|
||||||
|
renderer.view.style.left = "50%";
|
||||||
|
renderer.view.style.display = "block";
|
||||||
|
|
||||||
|
// add render view to DOM
|
||||||
|
document.body.appendChild(renderer.view);
|
||||||
|
|
||||||
|
// lets create moving shape
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var mask2 = new PIXI.Graphics();
|
||||||
|
mask2.beginFill(0);
|
||||||
|
mask2.drawCircle(620/2, 380/2, 300)
|
||||||
|
|
||||||
|
var container = new PIXI.DisplayObjectContainer();
|
||||||
|
stage.addChild(container);
|
||||||
|
container.addChild(bg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
container.mask = mask2;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for (var i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
var bear = PIXI.Sprite.fromImage("panda.png");
|
||||||
|
|
||||||
|
var mask1 = new PIXI.Graphics();
|
||||||
|
mask1.beginFill(0);
|
||||||
|
mask1.drawRect(20, 40, 100, 100)
|
||||||
|
bear.mask = mask1;
|
||||||
|
bear.addChild(mask1);
|
||||||
|
container.addChild(bear);
|
||||||
|
|
||||||
|
bear.position.x = i * 50;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
|
||||||
|
stage.click = stage.tap = function()
|
||||||
|
{
|
||||||
|
if(!container.filter)
|
||||||
|
{
|
||||||
|
container.mask = thing;
|
||||||
|
PIXI.runList(stage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
container.mask = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a pixi Logo!
|
||||||
|
*/
|
||||||
|
var logo = PIXI.Sprite.fromImage("../../logo_small.png")
|
||||||
|
stage.addChild(logo);
|
||||||
|
|
||||||
|
logo.anchor.x = 1;
|
||||||
|
logo.position.x = 620
|
||||||
|
logo.scale.x = logo.scale.y = 0.5;
|
||||||
|
logo.position.y = 320
|
||||||
|
logo.interactive = true;
|
||||||
|
logo.buttonMode = true;
|
||||||
|
|
||||||
|
logo.click = logo.tap = function()
|
||||||
|
{
|
||||||
|
window.open("https://github.com/GoodBoyDigital/pixi.js", "_blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
var help = new PIXI.Text("Click to turn masking on / off.", {font:"bold 12pt Arial", fill:"white"});
|
||||||
|
help.position.y = 350;
|
||||||
|
help.position.x = 10;
|
||||||
|
stage.addChild(help);
|
||||||
|
|
||||||
|
requestAnimFrame(animate);
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
|
||||||
|
bg.rotation += 0.01;
|
||||||
|
|
||||||
|
count += 0.1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
renderer.render(stage);
|
||||||
|
requestAnimFrame( animate );
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -133,7 +133,7 @@
|
||||||
count += 0.1;
|
count += 0.1;
|
||||||
|
|
||||||
thing.clear();
|
thing.clear();
|
||||||
thing.lineStyle(5, 0x16f1ff, 1);
|
|
||||||
thing.beginFill(0x8bc5ff, 0.4);
|
thing.beginFill(0x8bc5ff, 0.4);
|
||||||
thing.moveTo(-120 + Math.sin(count) * 20, -100 + Math.cos(count)* 20);
|
thing.moveTo(-120 + Math.sin(count) * 20, -100 + Math.cos(count)* 20);
|
||||||
thing.lineTo(120 + Math.cos(count) * 20, -100 + Math.sin(count)* 20);
|
thing.lineTo(120 + Math.cos(count) * 20, -100 + Math.sin(count)* 20);
|
||||||
|
@ -142,6 +142,9 @@
|
||||||
thing.lineTo(-120 + Math.sin(count) * 20, -100 + Math.cos(count)* 20);
|
thing.lineTo(-120 + Math.sin(count) * 20, -100 + Math.cos(count)* 20);
|
||||||
thing.rotation = count * 0.1;
|
thing.rotation = count * 0.1;
|
||||||
|
|
||||||
|
//var mask1 = new PIXI.Graphics();
|
||||||
|
|
||||||
|
|
||||||
renderer.render(stage);
|
renderer.render(stage);
|
||||||
requestAnimFrame( animate );
|
requestAnimFrame( animate );
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
var gui = new dat.GUI({
|
var gui = new dat.GUI({
|
||||||
//height : 5 * 32 - 1,
|
//height : 5 * 32 - 1,
|
||||||
|
|
||||||
width : 350
|
//width : 350
|
||||||
});
|
});
|
||||||
|
|
||||||
var blurFilter = new PIXI.BlurFilter();
|
var blurFilter = new PIXI.BlurFilter();
|
||||||
|
|
|
@ -80,6 +80,7 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
|
||||||
|
|
||||||
PIXI.deactivatePrimitiveShader();
|
PIXI.deactivatePrimitiveShader();
|
||||||
|
|
||||||
|
|
||||||
// return to default shader...
|
// return to default shader...
|
||||||
// PIXI.activateShader(PIXI.defaultShader);
|
// PIXI.activateShader(PIXI.defaultShader);
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,12 @@ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flip = false;
|
||||||
|
var maskStack = [];
|
||||||
|
var maskPosition = 0;
|
||||||
|
|
||||||
|
//var usedMaskStack = [];
|
||||||
|
|
||||||
PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
|
PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -295,24 +301,27 @@ PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projec
|
||||||
{
|
{
|
||||||
if(filterBlock.data instanceof Array)
|
if(filterBlock.data instanceof Array)
|
||||||
{
|
{
|
||||||
//var filter = filterBlock.data[0];
|
this.filterManager.pushFilter(filterBlock);
|
||||||
//console.log(filter)
|
|
||||||
this.filterManager.pushFilter(filterBlock);//filter);
|
|
||||||
// ok so..
|
// ok so..
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
maskPosition++;
|
||||||
|
|
||||||
|
maskStack.push(filterBlock)
|
||||||
|
|
||||||
gl.enable(gl.STENCIL_TEST);
|
gl.enable(gl.STENCIL_TEST);
|
||||||
|
|
||||||
gl.colorMask(false, false, false, false);
|
gl.colorMask(false, false, false, false);
|
||||||
gl.stencilFunc(gl.ALWAYS,1,0xff);
|
|
||||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
|
gl.stencilFunc(gl.ALWAYS,1,1);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
|
||||||
|
|
||||||
PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
|
PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
|
||||||
|
|
||||||
gl.colorMask(true, true, true, true);
|
gl.colorMask(true, true, true, true);
|
||||||
gl.stencilFunc(gl.NOTEQUAL,0,0xff);
|
gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
|
||||||
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,11 +330,26 @@ PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projec
|
||||||
if(filterBlock.data instanceof Array)
|
if(filterBlock.data instanceof Array)
|
||||||
{
|
{
|
||||||
this.filterManager.popFilter();
|
this.filterManager.popFilter();
|
||||||
// PIXI.popShader();
|
|
||||||
// gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
var maskData = maskStack.pop(filterBlock)
|
||||||
|
|
||||||
|
|
||||||
|
if(maskData)
|
||||||
|
{
|
||||||
|
gl.colorMask(false, false, false, false);
|
||||||
|
|
||||||
|
gl.stencilFunc(gl.ALWAYS,1,1);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
|
||||||
|
|
||||||
|
PIXI.WebGLGraphics.renderGraphics(maskData.data, projection);
|
||||||
|
|
||||||
|
gl.colorMask(true, true, true, true);
|
||||||
|
gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
|
||||||
|
gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
|
||||||
|
};
|
||||||
|
|
||||||
gl.disable(gl.STENCIL_TEST);
|
gl.disable(gl.STENCIL_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue