Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions packages/dev/core/src/Engines/Native/nativeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { ErrorCodes, RuntimeError } from "core/Misc/error";
import { Logger } from "core/Misc/logger";
import { Constants } from "../constants";
import { type INative } from "./nativeInterfaces";
import { VertexBuffer } from "core/Buffers/buffer.pure";
Expand Down Expand Up @@ -299,6 +300,18 @@ export function getNativeStencilDepthPass(opPass: number): number {
}
}

const _warnedUnsupportedAlphaModes = new Set<number>();

// Some alpha modes were introduced alongside newer Babylon Native features. When running against an older
// native binary the corresponding _native.Engine constant is undefined; warn once and fall back to ALPHA_ONEONE.
function _getFallbackAlphaMode(mode: number, unsupportedName: string): number {
if (!_warnedUnsupportedAlphaModes.has(mode)) {
_warnedUnsupportedAlphaModes.add(mode);
Logger.Warn(`Alpha mode ${unsupportedName} is not supported by this version of Babylon Native; falling back to ALPHA_ONEONE.`);
}
return _native.Engine.ALPHA_ONEONE;
}

export function getNativeAlphaMode(mode: number): number {
switch (mode) {
case Constants.ALPHA_DISABLE:
Expand All @@ -315,6 +328,10 @@ export function getNativeAlphaMode(mode: number): number {
return _native.Engine.ALPHA_MAXIMIZED;
case Constants.ALPHA_ONEONE:
return _native.Engine.ALPHA_ONEONE;
case Constants.ALPHA_ONEONE_ONEONE:
return _native.Engine.ALPHA_ONEONE_ONEONE ?? _getFallbackAlphaMode(mode, "ALPHA_ONEONE_ONEONE");
case Constants.ALPHA_LAYER_ACCUMULATE:
return _native.Engine.ALPHA_LAYER_ACCUMULATE ?? _getFallbackAlphaMode(mode, "ALPHA_LAYER_ACCUMULATE");
case Constants.ALPHA_PREMULTIPLIED:
return _native.Engine.ALPHA_PREMULTIPLIED;
case Constants.ALPHA_PREMULTIPLIED_PORTERDUFF:
Expand Down
10 changes: 10 additions & 0 deletions packages/dev/core/src/Engines/Native/nativeInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,14 @@ export interface INativeEngine {
samples: number,
layer?: number
): NativeFramebuffer;
createMultiFrameBuffer?(
textures: NativeTexture[],
width: number,
height: number,
generateStencilBuffer: boolean,
generateDepthBuffer: boolean,
samples: number
): NativeFramebuffer;

getRenderWidth(): number;
getRenderHeight(): number;
Expand Down Expand Up @@ -293,6 +301,8 @@ interface INativeEngineConstructor {
readonly ALPHA_MULTIPLY: number;
readonly ALPHA_MAXIMIZED: number;
readonly ALPHA_ONEONE: number;
readonly ALPHA_ONEONE_ONEONE?: number;
readonly ALPHA_LAYER_ACCUMULATE?: number;
readonly ALPHA_PREMULTIPLIED: number;
readonly ALPHA_PREMULTIPLIED_PORTERDUFF: number;
readonly ALPHA_INTERPOLATE: number;
Expand Down
14 changes: 14 additions & 0 deletions packages/dev/core/src/Engines/Native/nativeRenderTargetWrapper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Nullable } from "../../types";
import { type InternalTexture } from "../../Materials/Textures/internalTexture";
import { type TextureSize } from "../../Materials/Textures/textureCreationOptions";
import { RenderTargetWrapper } from "../renderTargetWrapper";
import { type NativeFramebuffer } from "./nativeInterfaces";
Expand Down Expand Up @@ -57,6 +58,19 @@ export class NativeRenderTargetWrapper extends RenderTargetWrapper {
this._engine = engine;
}

public override setTexture(texture: InternalTexture, index: number = 0, disposePrevious: boolean = true): void {
const previous = this.textures?.[index];
super.setTexture(texture, index, disposePrevious);

// bgfx binds a fixed attachment set when a framebuffer is created and cannot re-point an individual
// attachment the way GL's framebufferTexture2D can. When a multi render target attachment is swapped
// after creation (e.g. the OIT depth-peeling renderer replaces every attachment via
// MultiRenderTarget.setInternalTexture), recreate the whole framebuffer from the new attachment set.
if (this.isMulti && this.textures?.[index] !== previous) {
this._engine._createMultiRenderTargetFramebuffer(this);
}
}

public override dispose(disposeOnlyFramebuffers = false): void {
if (this.__framebuffers) {
// Releases all six per-face framebuffers (face 0 is aliased by __framebuffer, so
Expand Down
Loading