omnivibe Posted December 29, 2014 Share Posted December 29, 2014 is there a way to batch together a bunch of renderTexture.render() calls so they all upload to the gpu at once? I'm guessing a for-loop to call a bunch of them is inefficient... Quote Link to comment Share on other sites More sharing options...
msha Posted December 29, 2014 Share Posted December 29, 2014 Put everything you need to render on a single DisplayObjectContainer and render that DOC once. Quote Link to comment Share on other sites More sharing options...
omnivibe Posted December 30, 2014 Author Share Posted December 30, 2014 Whups, sorry this was meant for Phaser Quote Link to comment Share on other sites More sharing options...
omnivibe Posted December 30, 2014 Author Share Posted December 30, 2014 Actually, I might just abandon Phaser and DIY with Pixi... seems like this community is far more active... By "put everything you need to render on a single DisplayObjectContainer", how can I do that with a single image? In my use case I have a single image which is a brush. I want to draw that brush around on the screen, i.e. by blitting it many times across a path. What would be the best way to do this? Quote Link to comment Share on other sites More sharing options...
omnivibe Posted December 30, 2014 Author Share Posted December 30, 2014 Here is how I ended up doing it with Pixi, following what you said... is this the fastest way? I guess I'm most concerned about needing to create the sprite and tint it each time... or is that an extremely fast operation? drawLine() will actually be called very often, to draw continuous lines/curves as the user drags their mouse across the screenvar stage;var renderer;var currentBrushName = 'myBrushName';var currentBrushColor = 0xFF0000;var drawLayer;var drawLayerContainer;var lastPosition = null;var isDrawing = false;function setupPIXI() {stage = new PIXI.Stage(0xffffff);renderer = PIXI.autoDetectRenderer(800,600);$("#game").append(renderer.view);drawLayer = new PIXI.RenderTexture(800, 600);drawLayerContainer = new PIXI.Sprite(drawLayer);stage.addChild(drawLayerContainer);}function mainGameLoop() {requestAnimFrame(mainGameLoop);renderer.render(stage);}function tintBrush() {currentBrushColor = parseInt("0x" + $("#brushColor").val(), 16);}function loadAssets() {function onAssetsLoaded() {drawLine(getLine(10,10,500,500));requestAnimFrame(mainGameLoop);}var loader = new PIXI.AssetLoader(['assets/images/atlas/brushes.json']);loader.onComplete = onAssetsLoaded;loader.load();}function getBrushSprite(point) {var spr = PIXI.Sprite.fromFrame(currentBrushName);spr.tint = currentBrushColor;spr.x = point.x;spr.y = point.y;return(spr);}function drawLine(line) {var spr;var idx;var point;var drawBuffer = new PIXI.DisplayObjectContainer();for (idx = 0; idx < line.length; idx++) {point = line[idx];spr = getBrushSprite(point);drawBuffer.addChild(spr);}drawLayer.render(drawBuffer);}$(document).ready(function () {setupPIXI();tintBrush();$("#brushColor").change(tintBrush);loadAssets();});//This will get a collection of PIXI.Points() along the coordinatesfunction getLine(x1, y1, x2, y2) {} Quote Link to comment Share on other sites More sharing options...
msha Posted December 31, 2014 Share Posted December 31, 2014 Actually, I might just abandon Phaser and DIY with Pixi... seems like this community is far more active...For painting app PIXI(or just canvas) would be better imho. Yeah, that should be fast enough. Possible optimization - reuse sprites(use object pool) and the DisplayObjectContainer instead re-creating them. Quote Link to comment Share on other sites More sharing options...
omnivibe Posted December 31, 2014 Author Share Posted December 31, 2014 OK, here is my updated code. Did some housekeeping too Any more ways to optimize? It's used like just the following, after preloading a spritesheet that contains myBrushName Used like:drawLayer = new DrawLayer(800,600);drawLayer.initBrush('myBrushName',0xFF0000);stage.addChild(drawLayer);...//when brush is changed call drawLayer.initBrush() againHere's the main code for DrawLayer:DrawLayer.prototype = new PIXI.DisplayObjectContainer();DrawLayer.prototype.constructor = DrawLayer;var BrushMode = { NONE: "none", DRAW: "draw", ERASE: "erase"}/* Brush Pool*/function BrushPool(_brushName, _brushColor) { this.brushName = _brushName; this.brushColor = _brushColor; this.sprites = []; this.grow(10);}BrushPool.prototype.grow = function(num) { var idx; var spr; for(idx = 0; idx < num; idx++) { spr = PIXI.Sprite.fromFrame(this.brushName); spr.tint = this.brushColor; spr.anchor.x = .5; spr.anchor.y = .5; this.sprites.push(spr); }}BrushPool.prototype.growTo = function(num) { var diff = num - this.sprites.length; if(diff > 0) { console.log("Growing by " + diff) this.grow(diff); }}BrushPool.prototype.getBrush = function(idx, point) { var spr = this.sprites[idx]; spr.x = point.x; spr.y = point.y; return(spr);}/* Draw Layer*/function DrawLayer(width, height) { PIXI.DisplayObjectContainer.call(this); this.interactive = true; this.renderTexture = new PIXI.RenderTexture(800, 600); this.spriteContainer = new PIXI.Sprite(this.renderTexture); this.displayBuffer = new PIXI.DisplayObjectContainer(); this.brushPool = null; this.brushMode = BrushMode.DRAW; this.isDrawing = false; this.lastMousePoint = new PIXI.Point(0,0); this.addChild(this.spriteContainer); this.mousedown = this.touchstart = function(data) { if(this.brushMode != BrushMode.NONE) { this.isDrawing = true; this.lastMousePoint.x = data.getLocalPosition(this.parent).x; this.lastMousePoint.y = data.getLocalPosition(this.parent).y; this.drawPoints([this.lastMousePoint]); } }; this.mouseup = this.mouseupoutside = this.touchend = this.touchendoutside = function(data) { this.isDrawing = false; }; this.mousemove = this.touchmove = function(data) { if(this.isDrawing) { var nextMousePoint = data.getLocalPosition(this.parent); this.drawPoints(this.getLine(this.lastMousePoint.x, this.lastMousePoint.y, nextMousePoint.x, nextMousePoint.y)); this.lastMousePoint = nextMousePoint; } };}DrawLayer.prototype.initBrush = function(brushName, brushColor) { this.brushPool = new BrushPool(brushName, brushColor);}DrawLayer.prototype.drawPoints = function(points) { var spr; var idx; if(this.displayBuffer.children.length) { this.displayBuffer.removeChildren(0, this.displayBuffer.children.length); } this.brushPool.growTo(points.length); for (idx = 0; idx < points.length; idx++) { spr = this.brushPool.getBrush(idx, points[idx]); this.displayBuffer.addChild(spr); } this.renderTexture.render(this.displayBuffer);}DrawLayer.prototype.getLine = function(x1, y1, x2, y2) { var line = [];//Adds an array of points from x1,y1 to x2,y2 to line//... return (line);} Quote Link to comment Share on other sites More sharing options...
msha Posted January 2, 2015 Share Posted January 2, 2015 Great. Does it work well?One more way to optimize that would be to use SpriteBatch instead of DOC, but then you would not be able to tint the sprites. Quote Link to comment Share on other sites More sharing options...
omnivibe Posted January 4, 2015 Author Share Posted January 4, 2015 Yeah I need to tint the sprites. Seems to work really well... though when I tried replacing the native PIXI touch with HammerJS, the placement of the sprites got all weird... i.e. spr.anchor.x = .5; needs to become spr.anchor.x = 1; on Desktop and spr.anchor.x = 2 on iPad. Any idea why that is and how to automate it to be right? Quote Link to comment Share on other sites More sharing options...
msha Posted January 4, 2015 Share Posted January 4, 2015 HammerJS gives you the position relative to window, are you converting it to local(relative to canvas element) position?You can use this function to convert the position: function globalToLocalPosition(globalPosition, element) { var offset = getOffset(element); return { x: globalPosition.x - offset.left, y: globalPosition.y - offset.top }; } function getOffset(el) { var _x = 0; var _y = 0; while (el && !isNaN(el.offsetLeft) && !isNaN(el.offsetTop)) { _x += el.offsetLeft - el.scrollLeft; _y += el.offsetTop - el.scrollTop; el = el.offsetParent; } return { left: _x, top: _y}; } Quote Link to comment Share on other sites More sharing options...
omnivibe Posted January 4, 2015 Author Share Posted January 4, 2015 That worked perfectly! Thanks Now I'm having trouble figuring out how to erase, hehe... if you have a minute to take a look at http://www.html5gamedevs.com/topic/10096-erase-from-rendertexture/ that would be a big help Quote Link to comment Share on other sites More sharing options...
msha Posted January 5, 2015 Share Posted January 5, 2015 You're welcome Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.