|
@@ -37,6 +37,8 @@
|
|
|
getTexureWidth(texture: WebGLTexture): number;
|
|
|
getTexureHeight(texture: WebGLTexture): number;
|
|
|
setTextureSampling(texture: WebGLTexture, filter: number): void; // filter is a NativeFilter.XXXX value.
|
|
|
+ setTextureWrapMode(texture: WebGLTexture, addressModeU: number, addressModeV: number, addressModeW: number): void; // addressModes are NativeAddressMode.XXXX values.
|
|
|
+ setTexture(uniform: WebGLUniformLocation, texture: Nullable<WebGLTexture>): void;
|
|
|
deleteTexture(texture: Nullable<WebGLTexture>): void;
|
|
|
|
|
|
drawIndexed(fillMode: number, indexStart: number, indexCount: number): void;
|
|
@@ -67,6 +69,15 @@
|
|
|
public static readonly MINLINEAR_MAGPOINT_MIPPOINT = 10;
|
|
|
}
|
|
|
|
|
|
+ class NativeAddressMode {
|
|
|
+ // Must match AddressMode enum in SpectreEngine.h.
|
|
|
+ public static readonly WRAP = 0;
|
|
|
+ public static readonly MIRROR = 1;
|
|
|
+ public static readonly CLAMP = 2;
|
|
|
+ public static readonly BORDER = 3;
|
|
|
+ public static readonly MIRROR_ONCE = 4;
|
|
|
+ }
|
|
|
+
|
|
|
/** @hidden */
|
|
|
declare var nativeEngineInterop: INativeEngineInterop;
|
|
|
|
|
@@ -211,7 +222,7 @@
|
|
|
data instanceof ArrayBuffer) {
|
|
|
floatArray = new Float32Array(data);
|
|
|
} else {
|
|
|
- floatArray = new Float32Array((<ArrayBufferView>data).buffer);
|
|
|
+ floatArray = new Float32Array((data as ArrayBufferView).buffer);
|
|
|
}
|
|
|
|
|
|
const buffer = this._interop.createVertexBuffer(floatArray);
|
|
@@ -752,7 +763,7 @@
|
|
|
if (scene) {
|
|
|
scene._removePendingData(texture);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
texture.onLoadedObservable.notifyObservers(texture);
|
|
|
texture.onLoadedObservable.clear();
|
|
|
};
|
|
@@ -806,6 +817,20 @@
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Returns a NativeAddressMode.XXX value.
|
|
|
+ private _getAddressMode(wrapMode: number): number {
|
|
|
+ switch (wrapMode) {
|
|
|
+ case Engine.TEXTURE_WRAP_ADDRESSMODE:
|
|
|
+ return NativeAddressMode.WRAP;
|
|
|
+ case Engine.TEXTURE_CLAMP_ADDRESSMODE:
|
|
|
+ return NativeAddressMode.CLAMP;
|
|
|
+ case Engine.TEXTURE_MIRROR_ADDRESSMODE:
|
|
|
+ return NativeAddressMode.MIRROR;
|
|
|
+ default:
|
|
|
+ throw new Error("Unexpected wrap mode: " + wrapMode + ".");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public createRenderTargetTexture(size: any, options: boolean | RenderTargetCreationOptions): InternalTexture {
|
|
|
let fullOptions = new RenderTargetCreationOptions();
|
|
|
|
|
@@ -898,6 +923,67 @@
|
|
|
throw new Error("updateDynamicVertexBuffer not yet implemented.")
|
|
|
}
|
|
|
|
|
|
+ // TODO: Refactor to share more logic with base Engine implementation.
|
|
|
+ protected _setTexture(channel: number, texture: Nullable<BaseTexture>, isPartOfTextureArray = false, depthStencilTexture = false): boolean {
|
|
|
+ let uniform = this._boundUniforms[channel];
|
|
|
+ if (!uniform) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Not ready?
|
|
|
+ if (!texture) {
|
|
|
+ if (this._boundTexturesCache[channel] != null) {
|
|
|
+ this._activeChannel = channel;
|
|
|
+ this._interop.setTexture(uniform, null);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Video
|
|
|
+ if ((<VideoTexture>texture).video) {
|
|
|
+ this._activeChannel = channel;
|
|
|
+ (<VideoTexture>texture).update();
|
|
|
+ } else if (texture.delayLoadState === Engine.DELAYLOADSTATE_NOTLOADED) { // Delay loading
|
|
|
+ texture.delayLoad();
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ let internalTexture: InternalTexture;
|
|
|
+ if (depthStencilTexture) {
|
|
|
+ internalTexture = (<RenderTargetTexture>texture).depthStencilTexture!;
|
|
|
+ }
|
|
|
+ else if (texture.isReady()) {
|
|
|
+ internalTexture = <InternalTexture>texture.getInternalTexture();
|
|
|
+ }
|
|
|
+ else if (texture.isCube) {
|
|
|
+ internalTexture = this.emptyCubeTexture;
|
|
|
+ }
|
|
|
+ else if (texture.is3D) {
|
|
|
+ internalTexture = this.emptyTexture3D;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ internalTexture = this.emptyTexture;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!internalTexture._webGLTexture) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ this._activeChannel = channel;
|
|
|
+
|
|
|
+ this._interop.setTextureWrapMode(
|
|
|
+ internalTexture._webGLTexture,
|
|
|
+ this._getAddressMode(texture.wrapU),
|
|
|
+ this._getAddressMode(texture.wrapV),
|
|
|
+ this._getAddressMode(texture.wrapR));
|
|
|
+ // TODO: Implement setting anisotropic filtering level.
|
|
|
+ //this._interop.setTextureAnisotropicLevel(internalTexture._webGLTexture, ???);
|
|
|
+
|
|
|
+ this._interop.setTexture(uniform, internalTexture._webGLTexture);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
protected _bindTextureDirectly(target: number, texture: Nullable<InternalTexture>, forTextureDataUpdate = false, force = false): boolean {
|
|
|
if (this._boundTexturesCache[this._activeChannel] !== texture) {
|
|
|
this._boundTexturesCache[this._activeChannel] = texture;
|