cables_dev/cables/src/core/cgp/cgp_texture.js
import { Logger } from "cables-shared-client";
import CgTexture from "../cg/cg_texture.js";
export default class Texture extends CgTexture
{
constructor(_cgp, options = {})
{
super(options);
if (!_cgp) throw new Error("no cgp");
this._log = new Logger("cgp_texture");
this._cgp = _cgp;
// this.id = CABLES.uuid();
this.gpuTexture = null;
this.gpuTextureDescriptor = null;
options = options || {};
this.name = options.name || "unknown";
this._cgp.on("deviceChange", () =>
{
// this.reInit();
});
}
/**
* set texture data from an image/canvas object
* @function initTexture
* @memberof Texture
* @instance
* @param {Object} img image
* @param {Number} filter
*/
initTexture(img, filter)
{
this.width = img.width;
this.height = img.height;
const textureType = "rgba8unorm";
this._cgp.pushErrorScope("inittexture", { "logger": this._log });
this.gpuTextureDescriptor = {
"size": { "width": img.width, "height": img.height },
"format": textureType,
"usage": GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
};
this.gpuTexture = this._cgp.device.createTexture(this.gpuTextureDescriptor);
this._cgp.device.queue.copyExternalImageToTexture({ "source": img }, { "texture": this.gpuTexture }, this.gpuTextureDescriptor.size);
this._cgp.popErrorScope();
return this.gpuTexture;
}
dispose()
{
console.log("todo dispose");
}
getInfo()
{
const tex = this;
const obj = {};
obj.name = tex.name;
obj.size = tex.width + " x " + tex.height;
obj.textureType = tex.textureType;
return obj;
}
createView()
{
if (!this.gpuTexture)
{
console.log("no gputexture...");
return null;
}
return this.gpuTexture.createView();
}
/**
* @function initFromData
* @memberof Texture
* @instance
* @description create texturem from rgb data
* @param {Array<Number>} data rgb color array [r,g,b,a,r,g,b,a,...]
* @param {Number} w width
* @param {Number} h height
* @param {Number} filter
* @param {Number} wrap
*/
initFromData(data, w, h, filter, wrap)
{
if (!w || !h) this._log.error("texture size is 0");
this.width = w;
this.height = h;
this.gpuTexture = this._cgp.device.createTexture(
{
"size": [w, h],
"format": "rgba8unorm",
"usage": GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
});
this._cgp.device.queue.writeTexture(
{ "texture": this.gpuTexture },
data,
{ "bytesPerRow": w * 4 },
{ "width": w, "height": h });
}
}
/**
* @function load
* @static
* @memberof Texture
* @description load an image from an url
* @param {Context} cgp
* @param {String} url
* @param {Function} onFinished
* @param {Object} settings
* @return {Texture}
*/
Texture.load = function (cgp, url, onFinished, settings)
{
fetch(url).then((response) =>
{
const texture = new Texture(cgp, { "name": url });
response.blob().then((blob) =>
{
createImageBitmap(blob).then((imgBitmap) =>
{
texture.initTexture(imgBitmap);
if (onFinished)onFinished(texture);
else console.log("Texture.load no onFinished callback");
}).catch((err) =>
{
if (onFinished)onFinished(cgp.getErrorTexture());
});
});
});
};