* draw all objects visible in this viewport * @ignore
(renderer: Renderer, container: Container)
| 947 | * @ignore |
| 948 | */ |
| 949 | override draw(renderer: Renderer, container: Container): void { |
| 950 | // cast to any to access canvas/webgl renderer-specific methods not on base Renderer |
| 951 | const r = renderer as any; |
| 952 | const isNonDefault = !this.isDefault; |
| 953 | // for non-default cameras, compensate for the world container's |
| 954 | // centering offset (applied inside container.draw via renderer.translate) |
| 955 | const containerOffsetX = isNonDefault ? container.pos.x : 0; |
| 956 | const containerOffsetY = isNonDefault ? container.pos.y : 0; |
| 957 | const translateX = this.pos.x + this.offset.x + containerOffsetX; |
| 958 | const translateY = this.pos.y + this.offset.y + containerOffsetY; |
| 959 | |
| 960 | // sync the built-in colorMatrix: append as final pass if non-identity |
| 961 | if (!this.colorMatrix.isIdentity()) { |
| 962 | if (!this._colorMatrixEffect) { |
| 963 | this._colorMatrixEffect = new ColorMatrixEffect(renderer as any); |
| 964 | } |
| 965 | this._colorMatrixEffect.reset().multiply(this.colorMatrix); |
| 966 | this.postEffects.push(this._colorMatrixEffect); |
| 967 | } |
| 968 | |
| 969 | // post-effect: bind FBO if shader effects are set (WebGL only) |
| 970 | const usePostEffect = r.beginPostEffect(this); |
| 971 | |
| 972 | // apply the world-to-camera-view transform on the container. |
| 973 | // Camera2d translates by -camera.pos; Camera3d overrides this |
| 974 | // hook to additionally apply the camera's rotation (pitch / yaw) |
| 975 | // in the correct order (R⁻¹ ∘ T(-pos), via post-multiplication). |
| 976 | this._applyContainerViewTransform(container, translateX, translateY); |
| 977 | |
| 978 | this.preDraw(r); |
| 979 | |
| 980 | // clip to camera viewport on screen (skip when rendering to FBO — |
| 981 | // the FBO itself defines the render area) |
| 982 | if (!usePostEffect) { |
| 983 | r.clipRect(this.screenX, this.screenY, this.width, this.height); |
| 984 | } |
| 985 | |
| 986 | // set camera projection for non-default cameras |
| 987 | if (isNonDefault) { |
| 988 | this._setupNonDefaultProjection(renderer); |
| 989 | } else { |
| 990 | renderer.setProjection(this.projectionMatrix); |
| 991 | } |
| 992 | |
| 993 | // Upload active Light2d instances for the lit sprite pipeline. |
| 994 | // Done here — after `setProjection()` (which can flush the |
| 995 | // current batch) and before `container.draw()` walks the world |
| 996 | // tree — so the lights are guaranteed to apply to every lit quad |
| 997 | // pushed by the upcoming draw walk. Stage stays renderer-agnostic |
| 998 | // (just exposes the raw lights set + ambient color); the renderer |
| 999 | // decides how to encode them. Canvas's `setLightUniforms` is a |
| 1000 | // no-op. |
| 1001 | const stage = state.current(); |
| 1002 | renderer.setLightUniforms( |
| 1003 | stage?._activeLights, |
| 1004 | stage?.ambientLightingColor, |
| 1005 | translateX, |
| 1006 | translateY, |
no test coverage detected