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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { AbstractEngine } from "../../Engines/abstractEngine";
import type { IOfflineProvider } from "../../Offline/IOfflineProvider";

declare module "../abstractEngine" {
// eslint-disable-next-line @typescript-eslint/naming-convention
export interface AbstractEngine {
/**
* @internal
*/
_loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: false): Promise<string>;
_loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: true): Promise<ArrayBuffer>;
_loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean): Promise<string | ArrayBuffer>;
}
}

AbstractEngine.prototype._loadFileAsync = async function (url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean): Promise<any> {
return await new Promise<string | ArrayBuffer>((resolve, reject) => {
this._loadFile(
url,
(data) => {
resolve(data);
},
undefined,
offlineProvider,
useArrayBuffer,
(request, exception) => {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject(exception);
}
);
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { _GetCompatibleTextureLoader } from "core/Materials/Textures/Loaders/textureLoaderManager";
import { AbstractEngine } from "../abstractEngine";

AbstractEngine.GetCompatibleTextureLoader = _GetCompatibleTextureLoader;
2 changes: 2 additions & 0 deletions packages/dev/core/src/Engines/AbstractEngine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ export * from "./abstractEngine.renderPass";
export * from "./abstractEngine.texture";
export * from "./abstractEngine.alpha";
export * from "./abstractEngine.views";
export * from "./abstractEngine.loadFile";
export * from "./abstractEngine.textureLoaders";
1 change: 1 addition & 0 deletions packages/dev/core/src/Engines/Native/Extensions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./nativeEngine.cubeTexture";
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { InternalTexture, InternalTextureSource } from "../../../Materials/Textures/internalTexture";
import { Texture } from "../../../Materials/Textures/texture";
import { CreateRadianceImageDataArrayBufferViews, GetEnvInfo, UploadEnvSpherical } from "../../../Misc/environmentTextureTools";
import type { IWebRequest } from "../../../Misc/interfaces/iWebRequest";
import type { Scene } from "../../../scene";
import type { Nullable } from "../../../types";
import { Constants } from "../../constants";
import { ThinNativeEngine } from "../../thinNativeEngine";

declare module "../../../Engines/thinNativeEngine" {
// eslint-disable-next-line @typescript-eslint/naming-convention
export interface ThinNativeEngine {
/**
* Creates a cube texture
* @param rootUrl defines the url where the files to load is located
* @param scene defines the current scene
* @param files defines the list of files to load (1 per face)
* @param noMipmap defines a boolean indicating that no mipmaps shall be generated (false by default)
* @param onLoad defines an optional callback raised when the texture is loaded
* @param onError defines an optional callback raised if there is an issue to load the texture
* @param format defines the format of the data
* @param forcedExtension defines the extension to use to pick the right loader
* @param createPolynomials if a polynomial sphere should be created for the cube texture
* @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
* @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
* @param fallback defines texture to use while falling back when (compressed) texture file not found.
* @param loaderOptions options to be passed to the loader
* @param useSRGBBuffer defines if the texture must be loaded in a sRGB GPU buffer (if supported by the GPU).
* @param buffer defines the data buffer to load instead of loading the rootUrl
* @returns the cube texture as an InternalTexture
*/
createCubeTexture(
rootUrl: string,
scene: Nullable<Scene>,
files: Nullable<string[]>,
noMipmap?: boolean,
onLoad?: Nullable<(data?: any) => void>,
onError?: Nullable<(message?: string, exception?: any) => void>,
format?: number,
forcedExtension?: any,
createPolynomials?: boolean,
lodScale?: number,
lodOffset?: number,
fallback?: Nullable<InternalTexture>,
loaderOptions?: any,
useSRGBBuffer?: boolean,
buffer?: Nullable<ArrayBufferView>
): InternalTexture;
}
}

ThinNativeEngine.prototype.createCubeTexture = function (
rootUrl: string,
scene: Nullable<Scene>,
files: Nullable<string[]>,
noMipmap?: boolean,
onLoad: Nullable<(data?: any) => void> = null,
onError: Nullable<(message?: string, exception?: any) => void> = null,
format?: number,
forcedExtension: any = null,
createPolynomials = false,
lodScale: number = 0,
lodOffset: number = 0,
fallback: Nullable<InternalTexture> = null,
loaderOptions?: any,
useSRGBBuffer = false,
buffer: Nullable<ArrayBufferView> = null
): InternalTexture {
const texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);
texture.isCube = true;
texture.url = rootUrl;
texture.generateMipMaps = !noMipmap;
texture._lodGenerationScale = lodScale;
texture._lodGenerationOffset = lodOffset;
texture._useSRGBBuffer = this._getUseSRGBBuffer(useSRGBBuffer, !!noMipmap);

if (!this._doNotHandleContextLost) {
texture._extension = forcedExtension;
texture._files = files;
texture._buffer = buffer;
}

const lastDot = rootUrl.lastIndexOf(".");
const extension = forcedExtension ? forcedExtension : lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "";

// TODO: use texture loader to load env files?
if (extension === ".env") {
const onloaddata = (data: ArrayBufferView) => {
const info = GetEnvInfo(data)!;
texture.width = info.width;
texture.height = info.width;

UploadEnvSpherical(texture, info);

const specularInfo = info.specular;
if (!specularInfo) {
throw new Error(`Nothing else parsed so far`);
}

texture._lodGenerationScale = specularInfo.lodGenerationScale;
const imageData = CreateRadianceImageDataArrayBufferViews(data, info);

texture.format = Constants.TEXTUREFORMAT_RGBA;
texture.type = Constants.TEXTURETYPE_UNSIGNED_BYTE;
texture.generateMipMaps = true;
texture.getEngine().updateTextureSamplingMode(Texture.TRILINEAR_SAMPLINGMODE, texture);
texture._isRGBD = true;
texture.invertY = true;

this._engine.loadCubeTextureWithMips(
texture._hardwareTexture!.underlyingResource,
imageData,
false,
texture._useSRGBBuffer,
() => {
texture.isReady = true;
if (onLoad) {
onLoad();
}
},
() => {
throw new Error("Could not load a native cube texture.");
}
);
};

if (buffer) {
onloaddata(buffer);
} else if (files && files.length === 6) {
throw new Error(`Multi-file loading not allowed on env files.`);
} else {
const onInternalError = (request?: IWebRequest, exception?: any) => {
if (onError && request) {
onError(request.status + " " + request.statusText, exception);
}
};

this._loadFile(
rootUrl,
(data) => {
onloaddata(new Uint8Array(data as ArrayBuffer, 0, (data as ArrayBuffer).byteLength));
},
undefined,
undefined,
true,
onInternalError
);
}
} else {
if (!files || files.length !== 6) {
throw new Error("Cannot load cubemap because 6 files were not defined");
}

// Reorder from [+X, +Y, +Z, -X, -Y, -Z] to [+X, -X, +Y, -Y, +Z, -Z].
const reorderedFiles = [files[0], files[3], files[1], files[4], files[2], files[5]];
// eslint-disable-next-line github/no-then
Promise.all(reorderedFiles.map(async (file) => await this._loadFileAsync(file, undefined, true).then((data) => new Uint8Array(data, 0, data.byteLength))))
// eslint-disable-next-line github/no-then
.then(async (data) => {
return await new Promise<void>((resolve, reject) => {
this._engine.loadCubeTexture(texture._hardwareTexture!.underlyingResource, data, !noMipmap, true, texture._useSRGBBuffer, resolve, reject);
});
})
// eslint-disable-next-line github/no-then
.then(
() => {
texture.isReady = true;
if (onLoad) {
onLoad();
}
},
(error) => {
if (onError) {
onError(`Failed to load cubemap: ${error.message}`, error);
}
}
);
}

this._internalTexturesCache.push(texture);

return texture;
};
8 changes: 4 additions & 4 deletions packages/dev/core/src/Engines/Native/nativePipelineContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import type { Nullable } from "../../types";
import type { Effect } from "../../Materials/effect";
import type { IMatrixLike, IVector2Like, IVector3Like, IVector4Like, IColor3Like, IColor4Like, IQuaternionLike } from "../../Maths/math.like";
import type { IPipelineContext } from "../IPipelineContext";
import type { NativeEngine } from "../nativeEngine";
import type { NativeProgram } from "./nativeInterfaces";
import type { AbstractEngine } from "../abstractEngine";
import type { NativeShaderProcessingContext } from "./nativeShaderProcessingContext";
import type { ThinNativeEngine } from "../thinNativeEngine";

export class NativePipelineContext implements IPipelineContext {
public isCompiled: boolean = false;
Expand Down Expand Up @@ -36,11 +36,11 @@ export class NativePipelineContext implements IPipelineContext {
return null;
}

private _engine: NativeEngine;
private _engine: ThinNativeEngine;
private _valueCache: { [key: string]: any } = {};
private _uniforms: { [key: string]: Nullable<WebGLUniformLocation> };

constructor(engine: NativeEngine, isAsync: boolean, shaderProcessingContext: Nullable<NativeShaderProcessingContext>) {
constructor(engine: ThinNativeEngine, isAsync: boolean, shaderProcessingContext: Nullable<NativeShaderProcessingContext>) {
this._engine = engine;
this.isAsync = isAsync;
this.shaderProcessingContext = shaderProcessingContext;
Expand Down Expand Up @@ -86,7 +86,7 @@ export class NativePipelineContext implements IPipelineContext {
}

public setEngine(engine: AbstractEngine): void {
this._engine = engine as NativeEngine;
this._engine = engine as ThinNativeEngine;
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Nullable } from "../../types";
import type { TextureSize } from "../../Materials/Textures/textureCreationOptions";
import { RenderTargetWrapper } from "../renderTargetWrapper";
import type { NativeEngine } from "../nativeEngine";
import type { NativeFramebuffer } from "./nativeInterfaces";
import type { ThinNativeEngine } from "../thinNativeEngine";

export class NativeRenderTargetWrapper extends RenderTargetWrapper {
public override readonly _engine: NativeEngine;
public override readonly _engine: ThinNativeEngine;

// eslint-disable-next-line @typescript-eslint/naming-convention
private __framebuffer: Nullable<NativeFramebuffer> = null;
Expand Down Expand Up @@ -34,7 +34,7 @@ export class NativeRenderTargetWrapper extends RenderTargetWrapper {
this.__framebufferDepthStencil = framebufferDepthStencil;
}

constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: NativeEngine) {
constructor(isMulti: boolean, isCube: boolean, size: TextureSize, engine: ThinNativeEngine) {
super(isMulti, isCube, size, engine);
this._engine = engine;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { NativeEngine } from "../nativeEngine";
import { ThinNativeEngine } from "../thinNativeEngine";
import type { NativeData } from "./nativeDataStream";
import { NativeDataStream } from "./nativeDataStream";
import type { INative } from "./nativeInterfaces";

// eslint-disable-next-line @typescript-eslint/naming-convention
declare const _native: INative;

NativeEngine._createNativeDataStream = function () {
ThinNativeEngine._createNativeDataStream = function () {
if (_native.NativeDataStream.VALIDATION_ENABLED) {
return new ValidatedNativeDataStream();
} else {
Expand Down
15 changes: 13 additions & 2 deletions packages/dev/core/src/Engines/abstractEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import { Constants } from "./constants";
import { Observable } from "../Misc/observable";
import { EngineFunctionContext, _LoadFile } from "./abstractEngine.functions";
import type { Material } from "core/Materials/material";
import { _GetCompatibleTextureLoader } from "core/Materials/Textures/Loaders/textureLoaderManager";
import type { IInternalTextureLoader } from "../Materials/Textures/Loaders/internalTextureLoader";

/**
* Defines the interface used by objects working like Scene
Expand Down Expand Up @@ -1589,7 +1589,7 @@ export abstract class AbstractEngine {
extension = extension.split("?")[0];
}

const loaderPromise = _GetCompatibleTextureLoader(extension, mimeType);
const loaderPromise = AbstractEngine.GetCompatibleTextureLoader(extension, mimeType);

if (scene) {
scene.addPendingData(texture);
Expand Down Expand Up @@ -2823,4 +2823,15 @@ export abstract class AbstractEngine {
* @returns frame number
*/
public static QueueNewFrame: (func: () => void, requester?: any) => number = QueueNewFrame;

/**
* @internal
* Function used to get the correct texture loader for a specific extension.
* @param extension defines the file extension of the file being loaded
* @param mimeType defines the optional mime type of the file being loaded
* @returns the IInternalTextureLoader or null if it wasn't found
*/
public static GetCompatibleTextureLoader(_extension: string, _mimeType?: string): Nullable<Promise<IInternalTextureLoader>> {
return null;
}
}
30 changes: 2 additions & 28 deletions packages/dev/core/src/Engines/engine.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { Nullable } from "../types";
import type { Scene } from "../scene";
import { InternalTexture, InternalTextureSource } from "../Materials/Textures/internalTexture";
import type { IOfflineProvider } from "../Offline/IOfflineProvider";
import type { ILoadingScreen } from "../Loading/loadingScreen";
import { EngineStore } from "./engineStore";
import type { WebGLPipelineContext } from "./WebGL/webGLPipelineContext";
Expand Down Expand Up @@ -34,6 +33,8 @@ import "./AbstractEngine/abstractEngine.states";
import "./AbstractEngine/abstractEngine.stencil";
import "./AbstractEngine/abstractEngine.renderPass";
import "./AbstractEngine/abstractEngine.texture";
import "./AbstractEngine/abstractEngine.loadFile";
import "./AbstractEngine/abstractEngine.textureLoaders";

import type { PostProcess } from "../PostProcesses/postProcess";
import { AbstractEngine } from "./abstractEngine";
Expand Down Expand Up @@ -542,33 +543,6 @@ export class Engine extends ThinEngine {
gl.disable(gl.SCISSOR_TEST);
}

/**
* @internal
*/
public async _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: false): Promise<string>;
public async _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: true): Promise<ArrayBuffer>;

/**
* @internal
*/
public async _loadFileAsync(url: string, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {
return await new Promise((resolve, reject) => {
this._loadFile(
url,
(data) => {
resolve(data);
},
undefined,
offlineProvider,
useArrayBuffer,
(request, exception) => {
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
reject(exception);
}
);
});
}

/**
* Gets the source code of the vertex shader associated with a specific webGL program
* @param program defines the program to use
Expand Down
1 change: 1 addition & 0 deletions packages/dev/core/src/Engines/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from "./engineCapabilities";
export * from "./instancingAttributeInfo";
export * from "./abstractEngine";
export * from "./thinEngine";
export * from "./thinNativeEngine";
export * from "./engine";
export * from "./engineStore";
export * from "./nullEngine";
Expand Down
Loading