Fix renderer batcher API, setBlendMode PMA, and plugin registration#1332
Fix renderer batcher API, setBlendMode PMA, and plugin registration#1332
Conversation
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>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
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
setBlendModewith apremultipliedAlphaflag and remove internalglparameter. - Base/Canvas renderer and application: add base
Renderer#setBlendMode+GPURendererproperty and removeas any/unused context usage in app header/resize. - Plugin system: derive plugin registration names using
pluginClass.namebefore falling back to parsingtoString().
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.
| 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; |
There was a problem hiding this comment.
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.
| * @param {string} [mode="normal"] - blend mode | ||
| * @param {boolean} [premultipliedAlpha=true] - whether textures use premultiplied alpha (WebGL only) | ||
| */ | ||
| setBlendMode(mode = "normal") { |
There was a problem hiding this comment.
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.
| setBlendMode(mode = "normal") { | |
| setBlendMode(mode = "normal", premultipliedAlpha = true) { // premultipliedAlpha is unused in the base renderer |
| const pluginName = | ||
| name || pluginClass.name || pluginClass.toString().match(/ (\w+)/)![1]; |
There was a problem hiding this comment.
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.
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 cleanupsetBlendMode()now accepts apremultipliedAlphaparameter (defaulttrue) for correct blending with non-premultiplied texturesgl/contextparameters fromsetBlendMode()on both WebGL and Canvas renderersBase Renderer
setBlendMode()method to baseRendererclass for TypeScript compatibilityGPURendererproperty to baseRendererclassrenderer as anycasts inheader.tsandresize.tscontextvariable fromresize.tsPlugin
plugin.register()now usespluginClass.namefor name derivation before falling back totoString()regex, fixing class name extraction when bundlers strip class names (caused "plugin extends already registered" errors)Test plan
🤖 Generated with Claude Code