初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,415 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
import { RecyclePool } from '../memop';
import enums from '../enums';
import { Vec2, Vec4, Mat3, Mat4, Color, Vec3 } from '../../core/value-types';
import ProgramLib from './program-lib';
import View from './view';
import gfx from '../gfx';
let _m4_tmp = new Mat4();
let _stageInfos = new RecyclePool(() => {
return {
stage: null,
items: null,
};
}, 8);
let _float2_pool = new RecyclePool(() => {
return new Float32Array(2);
}, 8);
let _float3_pool = new RecyclePool(() => {
return new Float32Array(3);
}, 8);
let _float4_pool = new RecyclePool(() => {
return new Float32Array(4);
}, 8);
let _float9_pool = new RecyclePool(() => {
return new Float32Array(9);
}, 8);
let _float16_pool = new RecyclePool(() => {
return new Float32Array(16);
}, 8);
let _float64_pool = new RecyclePool(() => {
return new Float32Array(64);
}, 8);
let _int2_pool = new RecyclePool(() => {
return new Int32Array(2);
}, 8);
let _int3_pool = new RecyclePool(() => {
return new Int32Array(3);
}, 8);
let _int4_pool = new RecyclePool(() => {
return new Int32Array(4);
}, 8);
let _int64_pool = new RecyclePool(() => {
return new Int32Array(64);
}, 8);
export default class Base {
/**
* @param {gfx.Device} device
* @param {Object} opts
* @param {gfx.Texture2D} opts.defaultTexture
* @param {gfx.TextureCube} opts.defaultTextureCube
*/
constructor (device, opts) {
this._device = device;
this._programLib = new ProgramLib(device);
this._opts = opts;
this._type2defaultValue = {
[enums.PARAM_INT]: 0,
[enums.PARAM_INT2]: new Vec2(0, 0),
[enums.PARAM_INT3]: new Vec3(0, 0, 0),
[enums.PARAM_INT4]: new Vec4(0, 0, 0, 0),
[enums.PARAM_FLOAT]: 0.0,
[enums.PARAM_FLOAT2]: new Vec2(0, 0),
[enums.PARAM_FLOAT3]: new Vec3(0, 0, 0),
[enums.PARAM_FLOAT4]: new Vec4(0, 0, 0, 0),
[enums.PARAM_COLOR4]: new Color(0, 0, 0, 1),
[enums.PARAM_MAT3]: new Mat3(),
[enums.PARAM_MAT4]: new Mat4(),
[enums.PARAM_TEXTURE_2D]: opts.defaultTexture,
[enums.PARAM_TEXTURE_CUBE]: opts.defaultTextureCube,
};
this._stage2fn = {};
this._usedTextureUnits = 0;
this._viewPools = new RecyclePool(() => {
return new View();
}, 8);
this._drawItemsPools = new RecyclePool(() => {
return {
model: null,
node: null,
ia: null,
effect: null,
defines: null,
uniforms: null
};
}, 100);
this._stageItemsPools = new RecyclePool(() => {
return new RecyclePool(() => {
return {
model: null,
node: null,
ia: null,
effect: null,
defines: null,
passes: [],
sortKey: -1,
uniforms: null
};
}, 100);
}, 16);
this._definesChanged = false;
}
_resetTextuerUnit () {
this._usedTextureUnits = 0;
}
_allocTextureUnit () {
const device = this._device;
let unit = this._usedTextureUnits;
if (unit >= device._caps.maxTextureUnits) {
console.warn(`Trying to use ${unit} texture units while this GPU supports only ${device._caps.maxTextureUnits}`);
}
this._usedTextureUnits += 1;
return unit;
}
_registerStage (name, fn) {
this._stage2fn[name] = fn;
}
clear () {
this._programLib.clear();
this.reset();
}
reset () {
this._viewPools.reset();
this._stageItemsPools.reset();
this._definesChanged = false;
}
_requestView () {
return this._viewPools.add();
}
_render (view, scene) {
const device = this._device;
// setup framebuffer
device.setFrameBuffer(view._framebuffer);
// setup viewport
device.setViewport(
view._rect.x,
view._rect.y,
view._rect.w,
view._rect.h
);
// setup clear
let clearOpts = {};
if (view._clearFlags & enums.CLEAR_COLOR) {
clearOpts.color = Vec4.toArray([], view._color);
}
if (view._clearFlags & enums.CLEAR_DEPTH) {
clearOpts.depth = view._depth;
}
if (view._clearFlags & enums.CLEAR_STENCIL) {
clearOpts.stencil = view._stencil;
}
device.clear(clearOpts);
// get all draw items
this._drawItemsPools.reset();
for (let i = 0; i < scene._models.length; ++i) {
let model = scene._models.data[i];
// filter model by view
if ((model._cullingMask & view._cullingMask) === 0) {
continue;
}
let drawItem = this._drawItemsPools.add();
model.extractDrawItem(drawItem);
}
// dispatch draw items to different stage
_stageInfos.reset();
for (let i = 0; i < view._stages.length; ++i) {
let stage = view._stages[i];
let stageItems = this._stageItemsPools.add();
stageItems.reset();
for (let j = 0; j < this._drawItemsPools.length; ++j) {
let drawItem = this._drawItemsPools.data[j];
let passes = drawItem.effect.stagePasses[stage];
if (!passes || passes.length === 0) continue;
let stageItem = stageItems.add();
stageItem.passes = passes;
stageItem.model = drawItem.model;
stageItem.node = drawItem.node;
stageItem.ia = drawItem.ia;
stageItem.effect = drawItem.effect;
stageItem.defines = drawItem.defines;
stageItem.sortKey = -1;
stageItem.uniforms = drawItem.uniforms;
}
let stageInfo = _stageInfos.add();
stageInfo.stage = stage;
stageInfo.items = stageItems;
}
// render stages
for (let i = 0; i < _stageInfos.length; ++i) {
let info = _stageInfos.data[i];
let fn = this._stage2fn[info.stage];
fn(view, info.items);
}
}
_setProperty (prop) {
const device = this._device;
let param = prop.value;
if (param === undefined) {
param = prop.val;
}
if (param === undefined) {
param = this._type2defaultValue[prop.type];
}
if (param === undefined) {
console.warn(`Failed to set technique property ${prop.name}, value not found.`);
return;
}
if (
prop.type === enums.PARAM_TEXTURE_2D ||
prop.type === enums.PARAM_TEXTURE_CUBE
) {
if (Array.isArray(param)) {
if (param.length > prop.count) {
console.error(`Failed to set property [${prop.name}] : The length of texture array [${param.length}] is bigger than [${prop.count}].`);
return;
}
let slots = _int64_pool.add();
for (let index = 0; index < param.length; ++index) {
slots[index] = this._allocTextureUnit();
}
device.setTextureArray(prop.name, param, slots);
} else {
device.setTexture(prop.name, param, this._allocTextureUnit());
}
} else {
if (prop.directly) {
device.setUniformDirectly(prop.name, param);
}
else {
device.setUniform(prop.name, param);
}
}
}
_draw (item) {
const device = this._device;
const programLib = this._programLib;
const { node, ia, passes, effect } = item;
// reset the pool
// NOTE: we can use drawCounter optimize this
// TODO: should be configurable
_float2_pool.reset();
_float3_pool.reset();
_float4_pool.reset();
_float9_pool.reset();
_float16_pool.reset();
_float64_pool.reset();
_int2_pool.reset();
_int3_pool.reset();
_int4_pool.reset();
_int64_pool.reset();
// set common uniforms
// TODO: try commit this depends on effect
// {
node.getWorldMatrix(_m4_tmp);
device.setUniform('cc_matWorld', Mat4.toArray(_float16_pool.add(), _m4_tmp));
// let wq = node.getWorldRotation(cc.quat());
Mat4.invert(_m4_tmp, _m4_tmp);
Mat4.transpose(_m4_tmp, _m4_tmp);
device.setUniform('cc_matWorldIT', Mat4.toArray(_float16_pool.add(), _m4_tmp));
// }
let defines = this._defines;
// for each pass
for (let i = 0; i < passes.length; ++i) {
let pass = passes[i];
if (this._definesChanged) {
pass._programKey = null;
}
let count = ia.count;
// set vertex buffer
if (ia._vertexBuffer) {
device.setVertexBuffer(0, ia._vertexBuffer);
}
// set index buffer
if (ia._indexBuffer) {
device.setIndexBuffer(ia._indexBuffer);
}
// set primitive type
device.setPrimitiveType(ia._primitiveType);
// set program
Object.setPrototypeOf(defines, pass._defines);
let program = programLib.getProgram(pass, defines, effect.name);
device.setProgram(program);
let uniforms = program._uniforms;
let variants = pass._properties;
for (let j = 0; j < uniforms.length; j++) {
let prop = variants[uniforms[j].name];
if (prop !== undefined)
this._setProperty(prop);
}
// cull mode
device.setCullMode(pass._cullMode);
// blend
if (pass._blend) {
device.enableBlend();
device.setBlendFuncSep(
pass._blendSrc,
pass._blendDst,
pass._blendSrcAlpha,
pass._blendDstAlpha
);
device.setBlendEqSep(
pass._blendEq,
pass._blendAlphaEq
);
device.setBlendColor32(pass._blendColor);
}
// depth test & write
if (pass._depthTest) {
device.enableDepthTest();
device.setDepthFunc(pass._depthFunc);
}
if (pass._depthWrite) {
device.enableDepthWrite();
}
// stencil
device.setStencilTest(pass._stencilTest);
if (pass._stencilTest === gfx.STENCIL_ENABLE) {
// front
device.setStencilFuncFront(
pass._stencilFuncFront,
pass._stencilRefFront,
pass._stencilMaskFront
);
device.setStencilOpFront(
pass._stencilFailOpFront,
pass._stencilZFailOpFront,
pass._stencilZPassOpFront,
pass._stencilWriteMaskFront
);
// back
device.setStencilFuncBack(
pass._stencilFuncBack,
pass._stencilRefBack,
pass._stencilMaskBack
);
device.setStencilOpBack(
pass._stencilFailOpBack,
pass._stencilZFailOpBack,
pass._stencilZPassOpBack,
pass._stencilWriteMaskBack
);
}
// draw pass
device.draw(ia._start, count);
this._resetTextuerUnit();
}
}
}

View File

@@ -0,0 +1,13 @@
let RenderQueue = {
OPAQUE: 0,
TRANSPARENT: 1,
OVERLAY: 2
};
let PassStage = {
DEFAULT: 1,
FORWARD: 2,
SHADOWCAST: 4
};
export { RenderQueue, PassStage };

View File

@@ -0,0 +1,35 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
import gfx from '../gfx';
export default class InputAssembler {
constructor(vb, ib, pt = gfx.PT_TRIANGLES) {
this._vertexBuffer = vb;
this._indexBuffer = ib;
this._primitiveType = pt;
this._start = 0;
this._count = -1;
// TODO: instancing data
// this._stream = 0;
}
/**
* @property {Number} count The number of indices or vertices to dispatch in the draw call.
*/
get count() {
if (this._count !== -1) {
return this._count;
}
if (this._indexBuffer) {
return this._indexBuffer.count;
}
if (this._vertexBuffer) {
return this._vertexBuffer.count;
}
return 0;
}
}

View File

@@ -0,0 +1,246 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
import gfx from '../gfx';
import enums from '../enums';
import ValueType from '../../core/value-types/value-type';
export default class Pass {
constructor (name, detailName, programName, stage, properties = {}, defines = {}) {
this._name = name;
this._detailName = detailName;
this._programName = programName;
this._programKey = null;
this._stage = stage;
this._properties = properties;
this._defines = defines;
this._propertyNames = Object.keys(properties)
this._defineNames = Object.keys(defines)
// cullmode
this._cullMode = gfx.CULL_BACK;
// blending
this._blend = false;
this._blendEq = gfx.BLEND_FUNC_ADD;
this._blendAlphaEq = gfx.BLEND_FUNC_ADD;
this._blendSrc = gfx.BLEND_SRC_ALPHA;
this._blendDst = gfx.BLEND_ONE_MINUS_SRC_ALPHA;
this._blendSrcAlpha = gfx.BLEND_SRC_ALPHA;
this._blendDstAlpha = gfx.BLEND_ONE_MINUS_SRC_ALPHA;
this._blendColor = 0xffffffff;
// depth
this._depthTest = false;
this._depthWrite = false;
this._depthFunc = gfx.DS_FUNC_LESS,
// stencil
this._stencilTest = gfx.STENCIL_INHERIT;
// front
this._stencilFuncFront = gfx.DS_FUNC_ALWAYS;
this._stencilRefFront = 0;
this._stencilMaskFront = 0xff;
this._stencilFailOpFront = gfx.STENCIL_OP_KEEP;
this._stencilZFailOpFront = gfx.STENCIL_OP_KEEP;
this._stencilZPassOpFront = gfx.STENCIL_OP_KEEP;
this._stencilWriteMaskFront = 0xff;
// back
this._stencilFuncBack = gfx.DS_FUNC_ALWAYS;
this._stencilRefBack = 0;
this._stencilMaskBack = 0xff;
this._stencilFailOpBack = gfx.STENCIL_OP_KEEP;
this._stencilZFailOpBack = gfx.STENCIL_OP_KEEP;
this._stencilZPassOpBack = gfx.STENCIL_OP_KEEP;
this._stencilWriteMaskBack = 0xff;
}
setCullMode (cullMode = gfx.CULL_BACK) {
this._cullMode = cullMode;
}
setBlend (
enabled = false,
blendEq = gfx.BLEND_FUNC_ADD,
blendSrc = gfx.BLEND_SRC_ALPHA,
blendDst = gfx.BLEND_ONE_MINUS_SRC_ALPHA,
blendAlphaEq = gfx.BLEND_FUNC_ADD,
blendSrcAlpha = gfx.BLEND_SRC_ALPHA,
blendDstAlpha = gfx.BLEND_ONE_MINUS_SRC_ALPHA,
blendColor = 0xffffffff
) {
this._blend = enabled;
this._blendEq = blendEq;
this._blendSrc = blendSrc;
this._blendDst = blendDst;
this._blendAlphaEq = blendAlphaEq;
this._blendSrcAlpha = blendSrcAlpha;
this._blendDstAlpha = blendDstAlpha;
this._blendColor = blendColor;
}
setDepth (
depthTest = false,
depthWrite = false,
depthFunc = gfx.DS_FUNC_LESS
) {
this._depthTest = depthTest;
this._depthWrite = depthWrite;
this._depthFunc = depthFunc;
}
setStencilFront (
enabled = gfx.STENCIL_INHERIT,
stencilFunc = gfx.DS_FUNC_ALWAYS,
stencilRef = 0,
stencilMask = 0xff,
stencilFailOp = gfx.STENCIL_OP_KEEP,
stencilZFailOp = gfx.STENCIL_OP_KEEP,
stencilZPassOp = gfx.STENCIL_OP_KEEP,
stencilWriteMask = 0xff
) {
this._stencilTest = enabled;
this._stencilFuncFront = stencilFunc;
this._stencilRefFront = stencilRef;
this._stencilMaskFront = stencilMask;
this._stencilFailOpFront = stencilFailOp;
this._stencilZFailOpFront = stencilZFailOp;
this._stencilZPassOpFront = stencilZPassOp;
this._stencilWriteMaskFront = stencilWriteMask;
}
setStencilEnabled (stencilTest = gfx.STENCIL_INHERIT) {
this._stencilTest = stencilTest;
}
setStencilBack (
stencilTest = gfx.STENCIL_INHERIT,
stencilFunc = gfx.DS_FUNC_ALWAYS,
stencilRef = 0,
stencilMask = 0xff,
stencilFailOp = gfx.STENCIL_OP_KEEP,
stencilZFailOp = gfx.STENCIL_OP_KEEP,
stencilZPassOp = gfx.STENCIL_OP_KEEP,
stencilWriteMask = 0xff
) {
this._stencilTest = stencilTest;
this._stencilFuncBack = stencilFunc;
this._stencilRefBack = stencilRef;
this._stencilMaskBack = stencilMask;
this._stencilFailOpBack = stencilFailOp;
this._stencilZFailOpBack = stencilZFailOp;
this._stencilZPassOpBack = stencilZPassOp;
this._stencilWriteMaskBack = stencilWriteMask;
}
setStage (stage) {
this._stage = stage;
}
setProperties (properties) {
this._properties = properties;
}
getProperty (name) {
if (!this._properties[name]) {
return;
}
return this._properties[name].value;
}
setProperty (name, value, directly) {
let prop = this._properties[name];
if (!prop) {
return false;
}
prop.directly = directly;
if (Array.isArray(value)) {
let array = prop.value;
if (array.length !== value.length) {
cc.warnID(9105, this._name, name);
return;
}
for (let i = 0; i < value.length; i++) {
array[i] = value[i];
}
}
else {
if (value && !ArrayBuffer.isView(value)) {
if (prop.type === enums.PARAM_TEXTURE_2D) {
prop.value = value.getImpl();
}
else if (value instanceof ValueType) {
value.constructor.toArray(prop.value, value);
}
else {
if (typeof value === 'object') {
cc.warnID(9106, this._name, name);
}
prop.value = value;
}
}
else {
prop.value = value;
}
}
return true;
}
getDefine (name) {
return this._defines[name];
}
define (name, value, force) {
let oldValue = this._defines[name];
if (!force && oldValue === undefined) {
return false;
}
if (oldValue !== value) {
this._defines[name] = value;
this._programKey = null;
}
return true;
}
clone () {
let pass = new Pass(this._programName);
Object.assign(pass, this);
let newProperties = {};
let properties = this._properties;
for (let name in properties) {
let prop = properties[name];
let newProp = newProperties[name] = {};
let value = prop.value;
if (Array.isArray(value)) {
newProp.value = value.concat();
}
else if (ArrayBuffer.isView(value)) {
newProp.value = new value.__proto__.constructor(value);
}
else {
newProp.value = value;
}
for (let name in prop) {
if (name === 'value') continue;
newProp[name] = prop[name];
}
}
pass._properties = newProperties;
pass._defines = Object.assign({}, this._defines);
pass._propertyNames = this._propertyNames;
pass._defineNames = this._defineNames;
return pass;
}
}

View File

@@ -0,0 +1,262 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
import gfx from '../gfx';
let _shdID = 0;
function _generateDefines(tmpDefines, defines) {
let results = [];
for (let i = 0; i < tmpDefines.length; i++) {
let name = tmpDefines[i].name;
let value = defines[name];
if (typeof value !== 'number') {
value = value ? 1 : 0;
}
results.push(`#define ${name} ${value}`);
}
return results.join('\n') + '\n';
}
function _replaceMacroNums(string, tmpDefines, defines) {
let tmp = string;
for (let i = 0; i < tmpDefines.length; i++) {
let name = tmpDefines[i].name;
let value = defines[name];
if (Number.isInteger(value)) {
let reg = new RegExp(name, 'g');
tmp = tmp.replace(reg, value);
}
}
return tmp;
}
function _unrollLoops(string) {
let pattern = /#pragma for (\w+) in range\(\s*(\d+)\s*,\s*(\d+)\s*\)([\s\S]+?)#pragma endFor/g;
function replace(match, index, begin, end, snippet) {
let unroll = '';
let parsedBegin = parseInt(begin);
let parsedEnd = parseInt(end);
if (parsedBegin.isNaN || parsedEnd.isNaN) {
console.error('Unroll For Loops Error: begin and end of range must be an int num.');
}
for (let i = parsedBegin; i < parsedEnd; ++i) {
unroll += snippet.replace(new RegExp(`{${index}}`, 'g'), i);
}
return unroll;
}
return string.replace(pattern, replace);
}
function _replaceHighp(string) {
return string.replace(/\bhighp\b/g, 'mediump');
}
export default class ProgramLib {
/**
* @param {gfx.Device} device
*/
constructor(device) {
this._device = device;
// register templates
this._templates = {};
this._cache = {};
this._checkPrecision();
}
clear () {
this._templates = {};
this._cache = {};
}
/**
* @param {string} name
* @param {string} vert
* @param {string} frag
* @param {Object[]} defines
*
* @example:
* // this object is auto-generated from your actual shaders
* let program = {
* name: 'foobar',
* vert: vertTmpl,
* frag: fragTmpl,
* defines: [
* { name: 'shadow', type: 'boolean' },
* { name: 'lightCount', type: 'number', min: 1, max: 4 }
* ],
* attributes: [{ name: 'a_position', type: 'vec3' }],
* uniforms: [{ name: 'color', type: 'vec4' }],
* extensions: ['GL_OES_standard_derivatives'],
* };
* programLib.define(program);
*/
define(prog) {
let { name, defines, glsl1 } = prog;
let { vert, frag } = glsl1 || prog;
if (this._templates[name]) {
// console.warn(`Failed to define shader ${name}: already exists.`);
return;
}
let id = ++_shdID;
// calculate option mask offset
let offset = 0;
for (let i = 0; i < defines.length; ++i) {
let def = defines[i];
let cnt = 1;
if (def.type === 'number') {
let range = def.range || [];
def.min = range[0] || 0;
def.max = range[1] || 4;
cnt = Math.ceil(Math.log2(def.max - def.min));
def._map = function (value) {
return (value - this.min) << this._offset;
}.bind(def);
} else { // boolean
def._map = function (value) {
if (value) {
return 1 << this._offset;
}
return 0;
}.bind(def);
}
def._offset = offset;
offset += cnt;
}
let uniforms = prog.uniforms || [];
if (prog.samplers) {
for (let i = 0; i < prog.samplers.length; i++) {
uniforms.push(prog.samplers[i])
}
}
if (prog.blocks) {
for (let i = 0; i < prog.blocks.length; i++) {
let defines = prog.blocks[i].defines;
let members = prog.blocks[i].members;
for (let j = 0; j < members.length; j++) {
uniforms.push({
defines,
name: members[j].name,
type: members[j].type,
})
}
}
}
// store it
this._templates[name] = {
id,
name,
vert,
frag,
defines,
attributes: prog.attributes,
uniforms,
extensions: prog.extensions
};
}
getTemplate(name) {
return this._templates[name];
}
/**
* Does this library has the specified program?
* @param {string} name
* @returns {boolean}
*/
hasProgram(name) {
return this._templates[name] !== undefined;
}
getKey(name, defines) {
let tmpl = this._templates[name];
let key = 0;
for (let i = 0; i < tmpl.defines.length; ++i) {
let tmplDefs = tmpl.defines[i];
let value = defines[tmplDefs.name];
if (value === undefined) {
continue;
}
key |= tmplDefs._map(value);
}
// return key << 8 | tmpl.id;
// key number maybe bigger than 32 bit, need use string to store value.
return tmpl.id + ':' + key;
}
getProgram(pass, defines, errPrefix) {
let key = pass._programKey = pass._programKey || this.getKey(pass._programName, defines);
let program = this._cache[key];
if (program) {
return program;
}
// get template
let tmpl = this._templates[pass._programName];
let customDef = _generateDefines(tmpl.defines, defines);
let vert = _replaceMacroNums(tmpl.vert, tmpl.defines, defines);
vert = customDef + _unrollLoops(vert);
if (!this._highpSupported) {
vert = _replaceHighp(vert);
}
let frag = _replaceMacroNums(tmpl.frag, tmpl.defines, defines);
frag = customDef + _unrollLoops(frag);
if (!this._highpSupported) {
frag = _replaceHighp(frag);
}
program = new gfx.Program(this._device, {
vert,
frag
});
let errors = program.link();
if (errors) {
let vertLines = vert.split('\n');
let fragLines = frag.split('\n');
let defineLength = tmpl.defines.length;
errors.forEach(err => {
let line = err.line - 1;
let originLine = err.line - defineLength;
let lines = err.type === 'vs' ? vertLines : fragLines;
// let source = ` ${lines[line-1]}\n>${lines[line]}\n ${lines[line+1]}`;
let source = lines[line];
let info = err.info || `Failed to compile ${err.type} ${err.fileID} (ln ${originLine}): \n ${err.message}: \n ${source}`;
cc.error(`${errPrefix} : ${info}`);
})
}
this._cache[key] = program;
return program;
}
_checkPrecision () {
let gl = this._device._gl;
let highpSupported = false;
if (gl.getShaderPrecisionFormat) {
let vertHighp = gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT);
let fragHighp = gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT);
highpSupported = (vertHighp && vertHighp.precision > 0) &&
(fragHighp && fragHighp.precision > 0);
}
if (!highpSupported) {
cc.warnID(9102);
}
this._highpSupported = highpSupported;
}
}

View File

@@ -0,0 +1,24 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
export default class Technique {
constructor(name, passes) {
this._name = name;
this._passes = passes;
}
get name () {
return this._name;
}
get passes() {
return this._passes;
}
clone () {
let passes = [];
for (let i = 0; i < this._passes.length; i++) {
passes.push(this._passes[i].clone());
}
return new Technique(this._name, passes);
}
}

View File

@@ -0,0 +1,80 @@
// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.
import { Vec3, Mat4, Vec4 } from '../../core/value-types';
import enums from '../enums';
let _m4_tmp = new Mat4();
let _genID = 0;
/**
* A representation of a single camera view
*/
export default class View {
/**
* Setup a default view
*/
constructor() {
this._id = _genID++;
// priority. the smaller one will be rendered first
this._priority = 0;
// viewport
this._rect = {
x: 0, y: 0, w: 1, h: 1
};
// TODO:
// this._scissor = {
// x: 0, y: 0, w: 1, h: 1
// };
// clear options
this._color = new Vec4(0.3, 0.3, 0.3, 1);
this._depth = 1;
this._stencil = 0;
this._clearFlags = enums.CLEAR_COLOR | enums.CLEAR_DEPTH;
this._clearModel = null;
// matrix
this._matView = cc.mat4();
this._matViewInv = cc.mat4();
this._matProj = cc.mat4();
this._matViewProj = cc.mat4();
this._matInvViewProj = cc.mat4();
// stages & framebuffer
this._stages = [];
this._cullingByID = false;
this._framebuffer = null;
this._shadowLight = null; // TODO: should not refer light in view.
this._cullingMask = 0xffffffff;
}
/**
* Get the view's forward direction
* @param {Vec3} out the receiving vector
* @returns {Vec3} the receiving vector
*/
getForward(out) {
let m = this._matView.m;
return Vec3.set(
out,
-m[2],
-m[6],
-m[10]
);
}
/**
* Get the view's observing location
* @param {Vec3} out the receiving vector
* @returns {Vec3} the receiving vector
*/
getPosition(out) {
Mat4.invert(_m4_tmp, this._matView);
return Mat4.getTranslation(out, _m4_tmp);
}
}