Skip to content

Fix renderer batcher API, setBlendMode PMA, and plugin registration#1332

Merged
obiot merged 5 commits intomasterfrom
fix/renderer-and-plugin-fixes
Mar 29, 2026
Merged

Fix renderer batcher API, setBlendMode PMA, and plugin registration#1332
obiot merged 5 commits intomasterfrom
fix/renderer-and-plugin-fixes

Conversation

@obiot
Copy link
Copy Markdown
Member

@obiot obiot commented Mar 29, 2026

Summary

melonJS-only fixes (split from spine-plugin PR #1331):

WebGLRenderer

  • setBatcher() now rebinds the shared vertex buffer when switching batchers, allowing custom batchers with their own GL buffers to integrate without manual cleanup
  • setBlendMode() now accepts a premultipliedAlpha parameter (default true) for correct blending with non-premultiplied textures
  • Removed internal gl/context parameters from setBlendMode() on both WebGL and Canvas renderers

Base Renderer

  • Added setBlendMode() method to base Renderer class for TypeScript compatibility
  • Added GPURenderer property to base Renderer class
  • Removed renderer as any casts in header.ts and resize.ts
  • Removed unused context variable from resize.ts

Plugin

  • plugin.register() now uses pluginClass.name for name derivation before falling back to toString() regex, fixing class name extraction when bundlers strip class names (caused "plugin extends already registered" errors)

Test plan

  • All 1848 tests pass
  • No breaking changes — all new parameters have backward-compatible defaults

🤖 Generated with Claude Code

obiot and others added 4 commits March 29, 2026 09:48
setBatcher() now rebinds the renderer's shared vertex buffer before
activating a new batcher. This allows custom batchers that use their
own GL buffers (e.g. SpineBatcher) to integrate without manual cleanup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add setBlendMode() to base Renderer class for TypeScript compatibility
- Add GPURenderer property to base Renderer (WebGL overrides with GPU string)
- Remove renderer as-any casts in header.ts and resize.ts
- Remove unused context param from Canvas setBlendMode and resize.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
plugin.register() now uses pluginClass.name before falling back to
the toString() regex. Fixes class name extraction when bundlers
(e.g. esbuild) strip class names from minified output, which caused
"plugin extends already registered" errors when registering multiple plugins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 29, 2026 01:49
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts renderer APIs and plugin registration logic in melonjs to improve WebGL batcher switching, blend-mode handling (including a new premultiplied-alpha option), and TypeScript compatibility by reducing as any casts.

Changes:

  • WebGLRenderer: rebind shared vertex buffer on batcher switch; extend setBlendMode with a premultipliedAlpha flag and remove internal gl parameter.
  • Base/Canvas renderer and application: add base Renderer#setBlendMode + GPURenderer property and remove as any/unused context usage in app header/resize.
  • Plugin system: derive plugin registration names using pluginClass.name before falling back to parsing toString().

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/melonjs/src/video/webgl/webgl_renderer.js Rebinds shared VBO on batcher change; updates WebGL blend mode API and blend factors.
packages/melonjs/src/video/renderer.js Adds base setBlendMode and GPURenderer for TS compatibility / fewer casts.
packages/melonjs/src/video/canvas/canvas_renderer.js Removes context argument from setBlendMode and uses renderer context directly.
packages/melonjs/src/plugin/plugin.ts Improves plugin name derivation using pluginClass.name first.
packages/melonjs/src/application/resize.ts Removes unused context variable; calls renderer.setBlendMode directly.
packages/melonjs/src/application/header.ts Uses typed GPURenderer/depthTest without as any casts.
packages/melonjs/CHANGELOG.md Documents the fixes and API adjustments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +752 to +760
setBlendMode(mode = "normal", premultipliedAlpha = true) {
if (this.currentBlendMode !== mode) {
const gl = this.gl;
this.flush();
gl.enable(gl.BLEND);
this.currentBlendMode = mode;

// source factor depends on whether textures use premultiplied alpha
const srcAlpha = premultipliedAlpha ? gl.ONE : gl.SRC_ALPHA;
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setBlendMode(mode, premultipliedAlpha) only updates GL state when mode changes. If callers switch premultipliedAlpha (e.g. rendering non-PMA textures after PMA ones) while keeping the same mode, the blend func will not be updated and blending will be wrong. Consider tracking the last applied premultipliedAlpha (or last srcAlpha factor) and include it in the early-exit condition, or always reapply blendEquation/blendFunc when premultipliedAlpha differs.

Copilot uses AI. Check for mistakes.
* @param {string} [mode="normal"] - blend mode
* @param {boolean} [premultipliedAlpha=true] - whether textures use premultiplied alpha (WebGL only)
*/
setBlendMode(mode = "normal") {
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc for Renderer#setBlendMode documents an optional premultipliedAlpha parameter, but the method signature only declares mode. If this is meant to provide TypeScript compatibility with WebGLRenderer#setBlendMode(mode, premultipliedAlpha), the base method should accept the second optional parameter as well (even if it’s unused), otherwise TS users calling renderer.setBlendMode(mode, false) won’t type-check against the base class.

Suggested change
setBlendMode(mode = "normal") {
setBlendMode(mode = "normal", premultipliedAlpha = true) { // premultipliedAlpha is unused in the base renderer

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +99
const pluginName =
name || pluginClass.name || pluginClass.toString().match(/ (\w+)/)![1];
Copy link

Copilot AI Mar 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pluginName derivation can still produce incorrect names for anonymous classes. For example, plugin.register(class extends BasePlugin {}) yields pluginClass.name === "" and the regex on toString() will typically match "extends", causing collisions like "plugin extends already registered". Consider validating the derived name (and/or guarding against regex match failure) and throwing a clear error requiring an explicit name when it can’t be reliably derived.

Copilot uses AI. Check for mistakes.
@obiot obiot merged commit 65974d5 into master Mar 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants