|
@ -1,4 +1,5 @@ |
|
|
import { EGLTexWrapType } from "../common"; |
|
|
import { EGLTexWrapType } from "../common"; |
|
|
|
|
|
import { Util } from "../math"; |
|
|
import { GLHelper } from "./WebGLHepler"; |
|
|
import { GLHelper } from "./WebGLHepler"; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -14,6 +15,29 @@ export class GLTexture { |
|
|
public target: number; //gl.TEXTURE_2D
|
|
|
public target: number; //gl.TEXTURE_2D
|
|
|
public name: string; //纹理的名称
|
|
|
public name: string; //纹理的名称
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* @var |
|
|
|
|
|
*/ |
|
|
|
|
|
public static readonly Colors: string[] = [ |
|
|
|
|
|
'aqua', //浅绿色
|
|
|
|
|
|
'black', //黑色
|
|
|
|
|
|
'blue', //蓝色
|
|
|
|
|
|
'fuchsia', //紫红色
|
|
|
|
|
|
'gray', //灰色
|
|
|
|
|
|
'green', //绿色
|
|
|
|
|
|
'lime', //绿黄色
|
|
|
|
|
|
'maroon', //褐红色
|
|
|
|
|
|
'navy', //海军蓝
|
|
|
|
|
|
'olive', //橄榄色
|
|
|
|
|
|
'orange', //橙色
|
|
|
|
|
|
'purple', //紫色
|
|
|
|
|
|
'red', //红色
|
|
|
|
|
|
'silver', //银灰色
|
|
|
|
|
|
'teal', //蓝绿色
|
|
|
|
|
|
'yellow', //黄色
|
|
|
|
|
|
'white' //白色
|
|
|
|
|
|
]; |
|
|
|
|
|
|
|
|
public constructor(gl: WebGLRenderingContext, name: string = '') { |
|
|
public constructor(gl: WebGLRenderingContext, name: string = '') { |
|
|
this.gl = gl; |
|
|
this.gl = gl; |
|
|
this.isMipmap = false; |
|
|
this.isMipmap = false; |
|
@ -32,12 +56,91 @@ export class GLTexture { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 判断是否是2的倍数 |
|
|
|
|
|
* @param x |
|
|
|
|
|
|
|
|
* 将非2的n次方的srcImage转换成2的n次方的CanvasRenderingContext2D对象 |
|
|
|
|
|
* 然后后续用来生成mipmap纹理 |
|
|
|
|
|
* @param srcImage |
|
|
* @returns |
|
|
* @returns |
|
|
*/ |
|
|
*/ |
|
|
public static isPowerOfTwo(x: number) { |
|
|
|
|
|
return (x & (x - 1)) === 0; |
|
|
|
|
|
|
|
|
public static createPowerOfTwoCanvas(srcImage: HTMLImageElement | HTMLCanvasElement): HTMLCanvasElement { |
|
|
|
|
|
let canvas: HTMLCanvasElement = document.createElement("canvas"); |
|
|
|
|
|
canvas.width = Util.getNextPowerOfTwo(srcImage.width); |
|
|
|
|
|
canvas.height = Util.getNextPowerOfTwo(srcImage.height); |
|
|
|
|
|
|
|
|
|
|
|
let ctx: CanvasRenderingContext2D | null = canvas.getContext("2d"); |
|
|
|
|
|
if (ctx === null) { |
|
|
|
|
|
throw new Error("create canvasRenderingContext2D failed!"); |
|
|
|
|
|
} |
|
|
|
|
|
ctx.drawImage(srcImage, 0, 0, srcImage.width, srcImage.height, 0, 0, canvas.width, canvas.height); |
|
|
|
|
|
return canvas; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 发送纹理到显卡 |
|
|
|
|
|
* @param source |
|
|
|
|
|
* @param unit |
|
|
|
|
|
* @param mipmap |
|
|
|
|
|
*/ |
|
|
|
|
|
public upload(source: HTMLImageElement | HTMLCanvasElement, unit: number = 0, mipmap: boolean = false): void { |
|
|
|
|
|
|
|
|
|
|
|
//绑定要操作的texture,默认是0号texture
|
|
|
|
|
|
this.bind(unit); |
|
|
|
|
|
|
|
|
|
|
|
//翻转texture
|
|
|
|
|
|
this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL, 1); |
|
|
|
|
|
|
|
|
|
|
|
this.width = source.width; |
|
|
|
|
|
this.height = source.height; |
|
|
|
|
|
|
|
|
|
|
|
//生成mipmap纹理
|
|
|
|
|
|
if (mipmap === true) { |
|
|
|
|
|
let isWidthPowerOfTwo: boolean = Util.isPowerOfTwo(this.width); |
|
|
|
|
|
let isHeightPowerOfTwo: boolean = Util.isPowerOfTwo(this.height); |
|
|
|
|
|
if (isWidthPowerOfTwo === true && isHeightPowerOfTwo === true) { |
|
|
|
|
|
this.gl.texImage2D(this.target, 0, this.format, this.format, this.type, source); |
|
|
|
|
|
this.gl.generateMipmap(this.target); |
|
|
|
|
|
} else { |
|
|
|
|
|
let canvas: HTMLCanvasElement = GLTexture.createPowerOfTwoCanvas(source); |
|
|
|
|
|
this.gl.texImage2D(this.target, 0, this.format, this.format, this.type, canvas); |
|
|
|
|
|
GLHelper.checkGLError(this.gl); |
|
|
|
|
|
this.gl.generateMipmap(this.target); |
|
|
|
|
|
GLHelper.checkGLError(this.gl); |
|
|
|
|
|
this.width = canvas.width; |
|
|
|
|
|
this.height = canvas.height; |
|
|
|
|
|
} |
|
|
|
|
|
this.isMipmap = true; |
|
|
|
|
|
} else { |
|
|
|
|
|
this.isMipmap = false; |
|
|
|
|
|
this.gl.texImage2D(this.target, 0, this.format, this.format, this.type, source); |
|
|
|
|
|
} |
|
|
|
|
|
this.unbind(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static createDefaultTexture(gl: WebGLRenderingContext): GLTexture { |
|
|
|
|
|
let step: number = 4; |
|
|
|
|
|
let canvas: HTMLCanvasElement = document.createElement('canvas') as HTMLCanvasElement; |
|
|
|
|
|
canvas.width = 32 * step; |
|
|
|
|
|
canvas.height = 32 * step; |
|
|
|
|
|
|
|
|
|
|
|
let context: CanvasRenderingContext2D | null = canvas.getContext("2d"); |
|
|
|
|
|
if (context === null) { |
|
|
|
|
|
alert("离屏Canvas获取渲染上下文失败!") |
|
|
|
|
|
throw new Error("离屏Canvas获取渲染上下文失败!"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for (let i: number = 0; i < step; i++) { |
|
|
|
|
|
for (let j: number = 0; j < step; j++) { |
|
|
|
|
|
let idx: number = step * i + j; |
|
|
|
|
|
context.save(); |
|
|
|
|
|
context.fillStyle = GLTexture.Colors[idx]; |
|
|
|
|
|
context.fillRect(i * 32, j * 32, 32, 32); |
|
|
|
|
|
context.restore(); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let tex: GLTexture = new GLTexture(gl); |
|
|
|
|
|
tex.wrap(); |
|
|
|
|
|
tex.upload(canvas); |
|
|
|
|
|
return tex; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
@ -72,4 +175,31 @@ export class GLTexture { |
|
|
} |
|
|
} |
|
|
this.gl.texParameteri(this.target, this.gl.TEXTURE_MIN_FILTER, magLinear ? this.gl.LINEAR : this.gl.NEAREST); |
|
|
this.gl.texParameteri(this.target, this.gl.TEXTURE_MIN_FILTER, magLinear ? this.gl.LINEAR : this.gl.NEAREST); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 绑定texture |
|
|
|
|
|
* @param uint |
|
|
|
|
|
*/ |
|
|
|
|
|
public bind(uint: number = 0): void { |
|
|
|
|
|
if (this.texture !== null) { |
|
|
|
|
|
this.gl.activeTexture(this.gl.TEXTURE0 + uint); |
|
|
|
|
|
this.gl.bindTexture(this.target, this.texture); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 解除textture绑定 |
|
|
|
|
|
*/ |
|
|
|
|
|
public unbind(): void { |
|
|
|
|
|
if (this.texture) { |
|
|
|
|
|
this.gl.bindTexture(this.target, null); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 清除纹理 |
|
|
|
|
|
*/ |
|
|
|
|
|
public destory(): void { |
|
|
|
|
|
this.gl.deleteTexture(this.texture); |
|
|
|
|
|
} |
|
|
} |
|
|
} |