Browse Source

完成GLTexture

master
blobt 4 years ago
parent
commit
348613c54e
  1. 11
      src/App.tsx
  2. 29
      src/render/math/Util.ts
  3. 3
      src/render/math/index.ts
  4. 138
      src/render/webgl/WebGLTexture.ts

11
src/App.tsx

@ -1,18 +1,9 @@
import React from 'react'; import React from 'react';
import './App.css'; import './App.css';
import { vec3, vec4 } from "./render/math"; import { vec3, vec4 } from "./render/math";
import {} from "./render/webgl/WebGLTexture";
// eslint-disable-next-line
function App() {
let a: vec3 = new vec3([1, 1, 1]);
let b: vec3 = new vec3([3, 2, 1]);
let c: vec3 = new vec3([2, 3, 1]);
let d: vec3 = new vec3([1, 2, 3]);
let ab: vec3 = vec3.difference(b, a);
function App() {
ab.print();
return ( return (
<div className="App"> <div className="App">
sasa sasa

29
src/render/math/Util.ts

@ -0,0 +1,29 @@
export class Util {
/**
* x是否是2的n次方x是不是1248163264.....
* @param x
* @returns
*/
public static isPowerOfTwo(x: number) {
return (x & (x - 1)) === 0;
}
/**
* 2n次方数
* x为34
* x为44
* x为58
* @param x
* @returns
*/
public static getNextPowerOfTwo(x: number): number {
if (x <= 0) {
throw new Error("参数必须要大于0!")
}
--x;
for (var i = 1; i < 32; i <<= 1) {
x = x | x >> i;
}
return x + 1;
}
}

3
src/render/math/index.ts

@ -2,4 +2,5 @@ export * from './Vec2';
export * from './Vec3'; export * from './Vec3';
export * from './Vec4'; export * from './Vec4';
export * from './Mat4'; export * from './Mat4';
export * from './Quat';
export * from './Quat';
export * from './Util';

138
src/render/webgl/WebGLTexture.ts

@ -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
* 2n次方的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);
}
} }
Loading…
Cancel
Save