UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

169 lines (130 loc) 4.76 kB
import { assert } from "../../../../core/assert.js"; import ImageFilter from "../../filter/ImageFilter.js"; import { sampler2d_flipY_in_place } from "../../filter/sampler2d_flipY_in_place.js"; import CopyShader from "../../postprocess/threejs/shaders/CopyShader.js"; import { WebGLRendererPool } from "../../render/RendererPool.js"; import { canvasDataToSampler } from "../canvasDataToSampler.js"; import { formatToChannelCount } from "../formatToChannelCount.js"; import { sampler2d_scale } from "./resize/sampler2d_scale.js"; import { Sampler2D } from "./Sampler2D.js"; import { sampler2d_ensure_uint8_RGBA } from "./sampler2d_ensure_uint8_RGBA.js"; const DEFAULT_TEXTURE_WIDTH = 512; const DEFAULT_TEXTURE_HEIGHT = 512; /** * * @param {THREE.DataTexture} texture * @param {number} channel_count * @param {number} _width * @param {number} _height * @returns {Sampler2D} */ function data_texture_to_sampler(texture, channel_count, _width, _height) { const source = new Sampler2D(texture.image.data, channel_count, texture.image.width, texture.image.height); let converted = sampler2d_ensure_uint8_RGBA(source); if (converted.width !== _width || converted.height !== _height) { const target = Sampler2D.uint8(4, _width, _height); sampler2d_scale(converted, target); converted = target; } return converted; } /** * * @param {THREE.Texture} texture * @param {number} channel_count * @param {number} _width * @param {number} _height * @returns {Sampler2D} */ function html_image_texture_to_sampler(texture, channel_count, _width, _height) { /** * * @type {Image} */ const img = texture.image; assert.isInstanceOf(img, Image, 'texture.image', 'Image'); const canvas = document.createElement('canvas'); canvas.width = _width; canvas.height = _height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, _width, _height); const result = Sampler2D.uint8(4, _width, _height); canvasDataToSampler(result, ctx); return result; } /** * * @param {Texture} texture * @param {number} [width] * @param {number} [height] * @param {boolean} [flipY] * @return {Sampler2D} */ export function convertTexture2Sampler2D( texture, width, height, flipY = true ) { let _height = height; let _width = width; const channel_count = formatToChannelCount(texture.format); if (_width === undefined || _height === undefined) { //figure out texture size const image = texture.image; if (image !== undefined && image !== null) { if (_width === undefined) { if (typeof image.width === "number") { _width = image.width; } else { _width = DEFAULT_TEXTURE_WIDTH; } } if (_height === undefined) { if (typeof image.height === "number") { _height = image.height; } else { _height = DEFAULT_TEXTURE_HEIGHT; } } } else { if (_width === undefined) { _width = DEFAULT_TEXTURE_WIDTH; } if (_height === undefined) { _height = DEFAULT_TEXTURE_HEIGHT; } } } let data; if (texture.isDataTexture === true) { // special case const converted = data_texture_to_sampler(texture, channel_count, _width, _height); data = converted.data; } else if (texture.image instanceof Image) { const converted = html_image_texture_to_sampler(texture, channel_count, _width, _height); data = converted.data; } else { const built = WebGLRendererPool.global.use(renderer => { const ctx = renderer.getContext(); //support for compressed textures ctx.getExtension("WEBGL_compressed_texture_s3tc"); return ImageFilter(renderer, _width, _height, { vertexShader: CopyShader.vertexShader, fragmentShader: CopyShader.fragmentShader, uniforms: { tDiffuse: { value: texture, type: 't' }, opacity: { value: 1.0 } } }); }); data = built.array; } if (flipY) { sampler2d_flipY_in_place(data, _width, _height); } return new Sampler2D(data, 4, _width, _height); }