95 lines
2.9 KiB
JavaScript
95 lines
2.9 KiB
JavaScript
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 }
|