2
votes

I have THREE.Points with THREE.PointsMaterial. As a map I use generated dynamic cavas image. I need to re-render canvas on each frame.

my part of code:

function makeEnemyBaseLabel( n,d ) {
                var canvas = document.createElement('canvas');
                var context= canvas.getContext("2d");
                var w = 5;
                    context.canvas.width  = context.canvas.height = 128;

                    context.fillStyle = 'rgba(255,255,255,0.4)';
                    context.strokeStyle = 'rgba(255,255,255,0.5)';

                    context.beginPath();
                    context.moveTo(64-(w/2),64-w);
                    context.lineTo(64-w,64-w);
                    context.lineTo(64-w,64-(w/2));
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64-w,64+(w/2));
                    context.lineTo(64-w,64+w);
                    context.lineTo(64-(w/2),64+w);
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64+(w/2),64+w);
                    context.lineTo(64+w,64+w);
                    context.lineTo(64+w,64+(w/2));
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64+w,64-(w/2));
                    context.lineTo(64+w,64-w);
                    context.lineTo(64+(w/2),64-w);
                    context.stroke();


                        context.textAlign="center";
                        context.font = "Normal 10px Sans-Serif";
                        context.fillText(formatDistance(d), 64, 85);



                var texture = new THREE.Texture(canvas); 
                    texture.needsUpdate = true;
                    return new THREE.PointsMaterial( { visible: true, size: 128, color: 0xffffff, depthTest: false, depthWrite: false,  opacity: 1, sizeAttenuation: false,  transparent: true, map: texture } );

}
function updateEnemyBaseLabel( n,d,o ) {
                var canvas = document.createElement('canvas');
                var context= canvas.getContext("2d");
                var w = 5;
                    context.canvas.width  = context.canvas.height = 128;


                    if(d < 100) {
                         context.fillStyle = 'rgba(255,255,255,1)';
                         context.strokeStyle = 'rgba(255,255,255,1)';
                    } else 
                    if(d < 1000) {
                         context.fillStyle = 'rgba(255,255,255,0.6)';
                         context.strokeStyle = 'rgba(255,255,255,0.7)';
                    } else {
                         context.fillStyle = 'rgba(255,255,255,0.4)';
                         context.strokeStyle = 'rgba(255,255,255,0.5)';
                    }

                    context.beginPath();
                    context.moveTo(64-(w/2),64-w);
                    context.lineTo(64-w,64-w);
                    context.lineTo(64-w,64-(w/2));
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64-w,64+(w/2));
                    context.lineTo(64-w,64+w);
                    context.lineTo(64-(w/2),64+w);
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64+(w/2),64+w);
                    context.lineTo(64+w,64+w);
                    context.lineTo(64+w,64+(w/2));
                    context.stroke();
                    context.beginPath();
                    context.moveTo(64+w,64-(w/2));
                    context.lineTo(64+w,64-w);
                    context.lineTo(64+(w/2),64-w);
                    context.stroke();


                        context.textAlign="center";
                        context.font = "Normal 10px Sans-Serif";
                        context.fillText(formatDistance(d), 64, 85);


                    var texture = new THREE.Texture(canvas); 
                        texture.needsUpdate = true;
                        o.material.map = texture; 


}

var geometry = new THREE.Geometry();      
    geometry.vertices.push( new THREE.Vector3() );
enemyShipMesh = new THREE.Points( geometry, makeEnemyBaseLabel( 1,1 ) );
scene.add(enemyShipMesh)
..
..
update() {
    updateEnemyBaseLabel( 1,5,enemyShipMesh );
}

after some time i have a memory leak. I'm sure, that the reason is creating new and new textures in memory.

What is the best approach to update canvas in referenced object most optimal way?

I'm searching for something like :

var context = //new context without canvas creating?
context.fillText(formatDistance(d), 64, 85);

enemyShipMesh.material.map = context; // or most simple without creating a lot of new object each sec.
1

1 Answers

3
votes

You're creating a canvas and all at every update, once you've created a canvas and the texture, you can go with just the canvas context in your update function and set texture.needsUpdate = true afterwards.