Modify pixels in Graphics texture and set result back into the Graphics object? WebGL

Howdy all
I’m trying to use a Graphics object to draw various elements on the WebGL canvas. I then want to programmatically make per pixel changes to what was drawn, and have that updated texture set back into the Graphics object so the user can continue to draw on that existing Graphics texture.

Now I can pull the texture data from the Graphics object, modify it, but I cant get the last part to work, setting the updated pixel data back into the Graphics object texture.

I’ve created a JSFiddle demo here: https://jsfiddle.net/mq54u7oy/3/

First you’ll see a red square, drawn by a graphics object.
If you press S, it will create a sprite below which displays that Graphics texture. So you will now see 2 red squares.
Then if you press D, it will update the Graphics object texture to green. When this happens, the sprite colour changes to green as expected, but the Graphics object doesn’t, it stays red. I’ve also tried calling .setTexture on the graphics object at the end, but it changes from red to empty.

Is there a way to do this?

1 Like

Hi @Wavertron,
From the docs:

setTexture( [key] [, frame] [, mode])
Sets the texture frame this Graphics Object will use when drawing all shapes defined after calling this.
Phaser 3 API Documentation - Class: Graphics

You need to draw some shape after setTexture() to see the changes.
Example:
http://labs.phaser.io/edit.html?src=src/game%20objects\graphics\primitives\fill%20circle.js

Regards.

1 Like

Gave it a try, no luck.

Updated demo: https://jsfiddle.net/6ug0ywfe/2/

  • If I call graphics.setTexture() and draw a small blue square afterwards, the graphics object doesn’t update to a green square and drawing a blue square gives me a black one. So the graphics object is kind of broken after calling setTexture. (press S,D,F,G in the demo to see)

  • If I don’t call graphics.setTexture() and draw a small blue square afterwards, the graphics object continues to work but with the old texture ie still a red square, then a blue square appears. (press S,D,G in the demo to see). Interestingly the sprite backed by the graphics texture doesn’t change here, for some reason I actually thought that would dynamically update.

I guess this all tells me that when calling graphics.generateTexture() its creating a texture that is independent to what the graphics object is rendering. Which makes setTexture sound like what I need to use, to see it back into the graphics object. I wonder if that method is bugged, I can’t see any phaser lab examples using it and I can’t see what other purpose it might have. I’ll have to try digging into the phaser code (though I’ve not had much luck in the past with understanding its rendering process, its a little esoteric to me).

Hi @Wavertron,
Try this in your code code:

this.input.keyboard.on('keydown-F', () => {
    this.gfx.setTexture(this.gfxTxKey,0,2); // mode 2 : texture only
    this.gfx.fillRect(0,0,25,25);  // Uses the texture
    }, this);

Regards.

Ah thanks jjcapellan, I mucked around with that mode stuff earlier, but trying it again now in the my simple demo, I can see what graphics.setTexture is actually doing.

Ofcourse, it’s not doing what I expected, my mistake. I read the doco a few times but it didnt fully make sense to me until now, duh me… I incorrectly assumed that setTexture would update what was already rendered, already on screen. But no, graphics.setTexture sets the texture to what future draw operations will draw with (It also clears whatever was drawn prior). This also explains why future fillStyle setting has no effect, since it will be drawing the texture not the colour/style you specify. (The name “setTexture” is perhaps not the best, maybe it should be “fillTexture” or something like that, anyways)

So setTexture seems to work fine. Its an interesting feature, I wonder how it might be used… But alas its not what I’m trying to do.

Updated demo: https://jsfiddle.net/xk0jty23/1/ (press S,D, then G,F,G to see the change in drawing fill behaviour before/after setTexture).