Sign in to follow this  
Jerorx

Capturing very large stage as image

Recommended Posts

I'm trying to capture the map of my game as a png image. The map is composed of 32x32 tiles, has a width of 1500 tiles and a height of 1140 tiles (48000x36480 pixels in total).

I don't actually display it in full, but by "chunks". Each chunk has a dimension of 30x20 tiles, and consists in a PIXI.Container object storing one sprite for each tile of the chunk (in multiple layers). There are 2850 chunks in total.

The map is quite big, and displaying all chunks simultaneously makes the browser crash. In any case, capturing the whole map at once wouldn't be possible I think because its dimensions would exceed WebGl MAX_TEXTURE_SIZE parameter. So my goal instead is to display batches of a few hundred chunks, one batch at a time, and capture them in pictures. I don't mind having my world map split in multiple pictures, on the contrary.

So the process consists in the following steps (slightly simplified):
 

for(var i = 0; i < last_batch; i++){
    removeAll(); // removes currently displayed chunks, if any
    displayBatch(i); // displays 200 chunks of interest
    captureScene(); // captures the scene as an image
}

Here is my captureScene() method:


captureScene(){
    Engine.renderer.extract.canvas(Engine.stage).toBlob(function(b){
        var a = document.createElement('a');
        document.body.append(a);
        a.download = 'map.png';
        a.href = URL.createObjectURL(b);
        a.click();
        a.remove();
    }, 'image/png');
};

It works, except that (in both the latest Chrome and Firefox quantum), after a few batches it eventually crashes ("WebGl has lost context") so that I never manage to capture everything. Even with batches of 25 chunks instead of 200, it eventually crashes.

I was wondering if any of you might have ideas to improve this process, or an altogether different solution, based on your experience and knowledge of Pixi. Maybe there is a more efficient way to capture the scene? Alternatively, any tips that could help me diagnose better why it is crashing are also welcome.

In case you are wondering, here are the steps I perform when removing a chunk:

chunk.destroy({
        children: true,
        texture: false,
        baseTexture: false
});
Engine.stage.removeChild(chunk);

I destroy the objects but preserve the textures son they can be reused for subsequent batches. Again, let me know if you see any improvements on this front (in terms of memory management for example).

I'm interested in any comments!

Share this post


Link to post
Share on other sites

Wonderful, now it works! Thanks!

While I am at it, I now have a question. The image extraction ignores the scale parameter of the stage (or the resolution parameter of the renderer). Even if I display the chunks at 0.01 scale, the generated pictures will be full size (e.g. the width for a batch of 15 chunks will be 14400 instead of the intended 144). Is there a way to make the extraction take the scale into account?

Share this post


Link to post
Share on other sites

I'm sorry but I don't get it! You mean I should use a different root container than what I am using now (or do you denote something else by "root")? Could you elaborate? I really don't see what I could do regarding the root container. At the moment I'm already changing the scale parameters of the root container (e.g. stage.scale.x = 0.1, stage.scale.y = 0.1), and visually it works, but is not reflected in the extraction.

Thanks for your great help so far! 

 

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.