phaserjs / phaserjs/phaser

Drawing a Spine GameObject to RenderTexture/DynamicTexture draws it to the wrong location; can cause WebGL Invalid Operation warnings if anything else is drawn to the RT/DT at the same time

Open
#6,948 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

🐛 3rd Party Lib Bug 🐛 Spine 🕹️ Game Object
Dominant language
JavaScript
Stars
40.3k
Forks
7.2k
PR merge metrics
No merged PRs in 30d

Description

Version

  • Phaser Version: 3.86.0 and Spine 3.8/4.1
  • Operating system: Windows 11
  • Browser: Chrome, Edge, Firefox

Description

Drawing a Spine GameObject to a RenderTexture/DynamicTexture results in the Spine not showing up at the correct location within the RT/DT. If you happen to draw something else to the RT/DT at the same time (such as an Image), you get WebGL Invalid Operation: bufferSubData: no buffer warnings, and some/all of the things you tried to draw to the RT/DT will not show up in the RT/DT.

Example Test Code

The following code will demonstrate the issue:

// in your scene preload function
preload()
{
    // load your spine objects
    this.load.spine("spinekey", "spine.json", "spine.atlas", true);
}

create()
{
    // add an image
    this.add.image(0,0, "key", "frame");
    
    // add a spine object - I tested using Spine 3.8 and Spine 4.1 versions
    this.add.spine(400, 500, "spinekey", "animation", true);

    const dt = this.textures.addDynamicTexture("dt", this.scale.width, this.scale.height);
    dt.draw(this.children);

    // add the DT to the screen to view it
    this.add.image(0,0,"dt").setOrigin(0)
}

Additional Information

If you comment out add the "image" in the above code, you won't get the INVALID_OPERATION warning, but the Spine won't be drawn to the same spot it is on the screen.

You can get a "correct" version of the screen/DT by using a snapshot instead:

// in create
this.renderer.snapshot(snapshot => {
    this.textures.addImage("snapshot", snapshot);
    this.add.image(0,0,"snapshot").setOrigin(0);
})

I don't know how helpful it will be, but here is the stacktrace that the warning gives.

flush	@	phaser.js:178112
flush	@	phaser.js:175171
flush	@	phaser.js:181016
setBlendMode	@	phaser.js:181198
rebind	@	phaser.js:175877
SpineGameObjectWebGLRenderer	@	SpineWebGLPlugin.js:16238
batchGameObject	@	phaser.js:213566
batchGroup	@	phaser.js:213496
batchList	@	phaser.js:213454
batchDraw	@	phaser.js:213260
draw	@	phaser.js:212873

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the example using DynamicTexture.draw(this.children), an Image, and a Spine object, then inspect the SpineGameObjectWebGLRenderer entry in SpineWebGLPlugin.js and the RenderTexture/DynamicTexture drawing path. Compare the result with the renderer.snapshot example. Done means the Spine appears at the correct location and drawing it with other objects produces no WebGL Invalid Operation warnings.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.