@icanvas/renderer
Version:
这是icanvas的渲染模块
131 lines (129 loc) • 3.81 kB
JavaScript
let booleanArray = function(size) {
const array = new Array(size);
for (let i = 0; i < array.length; i++) array[i] = false;
return array;
};
export const DefaultValues = function(type, size) {
switch (type) {
case 'float':
case 'int':
case 'sampler2D':
case 'sampler2DArray':
return 0;
case 'vec2':
return new Float32Array(2 * size);
case 'vec3':
return new Float32Array(3 * size);
case 'vec4':
return new Float32Array(4 * size);
case 'ivec2':
return new Int32Array(2 * size);
case 'ivec3':
return new Int32Array(3 * size);
case 'ivec4':
return new Int32Array(4 * size);
case 'bool':
return false;
case 'bvec2':
return booleanArray(2 * size);
case 'bvec3':
return booleanArray(3 * size);
case 'bvec4':
return booleanArray(4 * size);
case 'mat2':
return new Float32Array([1, 0, 0, 1]);
case 'mat3':
return new Float32Array([1, 0, 0, 0, 1, 0, 0, 0, 1]);
case 'mat4':
return new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]);
}
return null;
};
const GL_TABLE = { STATE: false };
export const GetType = function(type, gl) {
if (GL_TABLE.STATE) return GL_TABLE[type];
GL_TABLE[gl.FLOAT] = 'float';
GL_TABLE[gl.FLOAT_VEC2] = 'vec2';
GL_TABLE[gl.FLOAT_VEC3] = 'vec3';
GL_TABLE[gl.FLOAT_VEC4] = 'vec4';
GL_TABLE[gl.INT] = 'int';
GL_TABLE[gl.INT_VEC2] = 'ivec2';
GL_TABLE[gl.INT_VEC3] = 'ivec3';
GL_TABLE[gl.INT_VEC4] = 'ivec4';
GL_TABLE[gl.BOOL] = 'bool';
GL_TABLE[gl.BOOL_VEC2] = 'bvec2';
GL_TABLE[gl.BOOL_VEC3] = 'bvec3';
GL_TABLE[gl.BOOL_VEC4] = 'bvec4';
GL_TABLE[gl.FLOAT_MAT2] = 'mat2';
GL_TABLE[gl.FLOAT_MAT3] = 'mat3';
GL_TABLE[gl.FLOAT_MAT4] = 'mat4';
GL_TABLE[gl.SAMPLER_2D] = 'sampler2D';
GL_TABLE[gl.SAMPLER_CUBE] = 'samplerCube';
GL_TABLE[gl.SAMPLER_2D_ARRAY] = 'sampler2DArray';
GL_TABLE.STATE = true;
return GL_TABLE[type];
};
const GL_SIZE = {
float: 1,
vec2: 2,
vec3: 3,
vec4: 4,
int: 1,
ivec2: 2,
ivec3: 3,
ivec4: 4,
bool: 1,
bvec2: 2,
bvec3: 3,
bvec4: 4,
mat2: 4,
mat3: 9,
mat4: 16,
sampler2D: 1,
};
export const GetSize = function(type) {
return GL_SIZE[type];
};
export const getAttributeData = function(gl, program) {
const attributes = {};
//遍历所有着色变量
for (let i = 0, l = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES); i < l; i++) {
//获取变量信息
const attribute = gl.getActiveAttrib(program, i);
attribute.typeName = GetType(attribute.type, gl);
attribute.useSize = GetSize(attribute.typeName);
attribute.id = gl.getAttribLocation(program, attribute.name);
attribute.isAttribute = true;
attributes[attribute.name] = attribute;
}
return attributes; //{变量名:{type:变量类型,name:变量名,size:变量大小}}
};
export const getUniformData = function(gl, program) {
const uniforms = {};
//遍历所有公共变量
for (let i = 0, l = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); i < l; i++) {
//获取变量信息
const uniform = gl.getActiveUniform(program, i);
uniform.typeName = GetType(uniform.type, gl);
uniform.namePrefix = uniform.name.replace(/\[.*?\]/, '');
uniform.value = DefaultValues(uniform.typeName);
// uniform.isArray = /\[.*?\]/.test(uniform.name);
uniform.id = gl.getUniformLocation(program, uniform.namePrefix);
// for (let i = 0; i < max; i++) uniform.id[i] = gl.getUniformLocation(program, uniform.namePrefix + '[' + i + ']');
uniforms[uniform.namePrefix] = uniform;
}
return uniforms;
};
export const CompileShader = function(gl, type, src) {
//生成并编译着色器
let shader = gl.createShader(type);
gl.shaderSource(shader, src);
gl.compileShader(shader);
//错误检查
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.warn(src);
console.error(gl.getShaderInfoLog(shader));
return null;
}
return shader;
};