import Resource from '../resource' class Texture { static async fromFile (gl, file, flip, filtering, repeat) { const image = await Resource.loadImage(file) return Texture.createTexture2D(gl, image, flip, filtering, repeat) } static createTexture2D (gl, img, flip = false, filtering, repeat = gl.REPEAT) { const tex = gl.createTexture() gl.bindTexture(gl.TEXTURE_2D, tex) gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flip) gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, repeat) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, repeat) if (filtering) { gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filtering) gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filtering) } else { gl.generateMipmap(gl.TEXTURE_2D) } gl.bindTexture(gl.TEXTURE_2D, null) const oTex = new Texture() oTex.type = gl.TEXTURE_2D oTex.id = tex return oTex } static createTextureCubeMap (gl, img) { if (!img || img.length !== 6) throw new Error('createTextureCubeMap() requires six images!') const tex = gl.createTexture() gl.bindTexture(gl.TEXTURE_CUBE_MAP, tex) gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false) gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[0]) gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[1]) gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[2]) gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[3]) gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[4]) gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img[5]) gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR) gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR) gl.bindTexture(gl.TEXTURE_CUBE_MAP, null) const oTex = new Texture() oTex.type = gl.TEXTURE_CUBE_MAP oTex.id = tex return oTex } } class Material { constructor (textures) { this.textures = textures } async loadTextures (gl) { if (this.textures) { for (const ti in this.textures) { const tex = this.textures[ti] if (!(tex instanceof Texture)) { const result = await Texture.fromFile(gl, tex, true) this.textures[ti] = result } } } } apply (gl, shader) { // TODO: lighting related things // Load textures if (!this.textures || !this.textures.length) return for (const i in this.textures) { const tex = this.textures[i] if (tex && tex instanceof Texture) { gl.activeTexture(gl.TEXTURE0 + parseInt(i)) gl.bindTexture(tex.type, tex.id) } } } } export { Texture, Material }