Skip to content

Commit

Permalink
Merge pull request #45 from YunHsiao/gfx
Browse files Browse the repository at this point in the history
pass: rebuild with overrides
  • Loading branch information
jerrywwl committed Jan 14, 2019
2 parents 36f1d38 + 0855268 commit f09f802
Show file tree
Hide file tree
Showing 13 changed files with 122 additions and 19 deletions.
16 changes: 14 additions & 2 deletions cocos/3d/assets/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ import { Asset } from '../../assets/asset';
import { ccclass, property } from '../../core/data/class-decorator';
import { GFXBindingType } from '../../gfx/define';
import { Effect } from '../../renderer/core/effect';
import { Pass } from '../../renderer/core/pass';
import { EffectAsset } from './effect-asset';
import { Pass, IPassOverrides } from '../../renderer/core/pass';
import { EffectAsset, IPassInfo, ITechniqueInfo } from './effect-asset';

@ccclass('cc.Material')
export class Material extends Asset {
Expand Down Expand Up @@ -133,6 +133,18 @@ export class Material extends Asset {
this.update();
}

public rebuildWithOverrides (overrides: IPassOverrides, idx?: number) {
if (!this._passes || !this._effectAsset) { return; }
const passInfos = Effect.getPassInfos(this._effectAsset, this._techIdx);
if (idx === undefined) {
for (let i = 0; i < this._passes.length; i++) {
this._passes[i].rebuildWithOverrides(passInfos[i], overrides);
}
} else {
this._passes[idx].rebuildWithOverrides(passInfos[idx], overrides);
}
}

public update (asset: EffectAsset | string | null = this._effectAsset, keepProps: boolean = true) {
// get effect asset
if (typeof asset === 'string') {
Expand Down
3 changes: 2 additions & 1 deletion cocos/3d/framework/model-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export default class ModelComponent extends RenderableComponent {

set mesh(val) {
this._mesh = val;
this._updateModels();
}

/**
Expand Down Expand Up @@ -184,7 +185,7 @@ export default class ModelComponent extends RenderableComponent {
}

_updateModels() {
if (!this.enabled) return;
if (!this.node._scene) return;
let meshCount = this._mesh ? this._mesh.subMeshCount : 0;

for (let i = 0; i < meshCount; ++i) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export default class ParticleSystemRenderer extends RenderableComponent {
this.frameTile = cc.v2(1, 1);
this.attrs = new Array(5);

this.device = cc.game._renderContext;
this.device = cc.game._gfxDevice;
}

onInit() {
Expand Down
2 changes: 1 addition & 1 deletion cocos/3d/framework/skinning-model-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export default class SkinningModelComponent extends ModelComponent {
return;
}

if (cc.game._renderContext.allowFloatTexture()) {
if (cc.game._gfxDevice.allowFloatTexture()) {
this._jointsTexture = utils.createJointsTexture(this._skeleton);
this._jointMatricesData = new Float32Array(this._jointsTexture._width * this._jointsTexture._height * 4);
} else {
Expand Down
2 changes: 1 addition & 1 deletion cocos/3d/framework/skybox-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export default class SkyboxComponent extends Component {
onLoad() {
this._model.setNode(this.node);

let ia = renderer.createIA(cc.game._renderContext, box(2, 2, 2));
let ia = renderer.createIA(cc.game._gfxDevice, box(2, 2, 2));
this._model.setInputAssembler(ia);

if (!this._material) {
Expand Down
69 changes: 69 additions & 0 deletions cocos/3d/misc/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { renderer } from '../../renderer';
import find from '../../scene-graph/find';
import { Mesh, RenderingMesh } from '../assets/mesh';
import gfx from '../../renderer/gfx/index';
import { GFXPrimitiveMode } from '../../gfx/define';

/**
*
* @param {import("../assets/skeleton").default} skinning
*/
function createJointsTexture(skinning) {
const jointCount = skinning.joints.length;

// Set jointsTexture.
// A squared texture with side length N(N > 1) multiples of 2 can store
// 2 ^ (2 * N - 2) matrices.
// We support most 1024 joints.
let size;
if (jointCount > 1024) {
throw "To many joints(more than 1024).";
} else if (jointCount > 256) {
size = 64;
} else if (jointCount > 64) {
size = 32;
} else if (jointCount > 16) {
size = 16;
} else if (jointCount > 4) {
size = 8;
} else {
size = 4;
}

return new gfx.Texture2D(cc.game._gfxDevice, {
width: size,
height: size,
format: gfx.TEXTURE_FMT_RGBA32F,
minFilter: gfx.FILTER_NEAREST,
magFilter: gfx.FILTER_NEAREST,
wrapS: gfx.WRAP_CLAMP,
wrapT: gfx.WRAP_CLAMP,
mipmap: false
});
}

function createMesh(context, data) {
let ia = renderer.createIA(context, data);
let meshAsset = new Mesh();
const primitiveMode = data.primitiveMode === undefined ? GFXPrimitiveMode.TRIANGLE_LIST : data.primitiveMode;
meshAsset._renderingMesh = new RenderingMesh([{inputAssembler: ia, primitiveMode}], [], []);
meshAsset._minPosition = data.minPos;
meshAsset._maxPosition = data.maxPos;

return meshAsset;
}

/**
* @param {Uint8Array} buffer
*/
function toPPM(buffer, w, h) {
return `P3 ${w} ${h} 255\n${buffer.filter((e, i) => i % 4 < 3).toString()}\n`;
}

export default {
createJointsTexture,
createMesh,

find,
toPPM
};
2 changes: 1 addition & 1 deletion cocos/gfx/webgl/webgl-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ export class WebGLGFXDevice extends GFXDevice {

private _webGLRC: WebGLRenderingContext | null = null;
private _isAntialias: boolean = true;
private _isPremultipliedAlpha: boolean = false;
private _isPremultipliedAlpha: boolean = true;

private _extensions: string[] | null = null;
private _EXT_texture_filter_anisotropic: EXT_texture_filter_anisotropic | null = null;
Expand Down
2 changes: 1 addition & 1 deletion cocos/pipeline/testcase/test-model-stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export class TestModelStage extends RenderStage {
this._scene._scene = this._scene;
const modelCom = this._scene.addComponent('cc.ModelComponent');
modelCom.material = this._material;
modelCom.mesh = cc.utils.createMesh(cc.game._renderContext, cc.primitives.box({length: 1, width: 1, height: 1}));
modelCom.mesh = cc.utils.createMesh(cc.game._gfxDevice, cc.primitives.box({length: 1, width: 1, height: 1}));
this._model = modelCom._models[0];
this._scene.setRotationFromEuler(45, 45, 45);
this._scene._rot = this._scene._lrot;
Expand Down
6 changes: 5 additions & 1 deletion cocos/renderer/core/effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,13 @@ const getDefines = (name: string, prog: IShaderInfo) => {
};

export class Effect {
public static getPassInfos (effect: EffectAsset, techIdx: number) {
return effect.techniques[techIdx].passes;
}

public static parseEffect (effect: EffectAsset, info?: IEffectInfo) {
// techniques
const { techIdx, defines } = info || {} as IEffectInfo;
const { techIdx, defines } = info || {} as IEffectInfo;
const tech = effect.techniques[techIdx || 0];
const passNum = tech.passes.length;
const passes: Pass[] = new Array(passNum);
Expand Down
27 changes: 22 additions & 5 deletions cocos/renderer/core/pass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { GFXBindingType, GFXBufferUsageBit, GFXMemoryUsageBit, GFXPrimitiveMode,
import { GFXDevice } from '../../gfx/device';
import { GFXPipelineLayout } from '../../gfx/pipeline-layout';
import { GFXBlendState, GFXBlendTarget, GFXDepthStencilState,
GFXInputState, GFXPipelineState, GFXRasterizerState } from '../../gfx/pipeline-state';
GFXInputState, GFXPipelineState, GFXRasterizerState, IGFXPipelineStateInfo } from '../../gfx/pipeline-state';
import { GFXRenderPass } from '../../gfx/render-pass';
import { GFXSampler } from '../../gfx/sampler';
import { GFXShader } from '../../gfx/shader';
Expand All @@ -24,6 +24,13 @@ export interface IPassInfoFull extends IPassInfo {
globals: GFXBuffer;
}

export interface IPassOverrides {
bs: GFXBlendState;
dss: GFXDepthStencilState;
rs: GFXRasterizerState;
primitive: GFXPrimitiveMode;
}

const _type2fn = {
[GFXType.INT]: (a: Float32Array, v: any) => a[0] = v,
[GFXType.INT2]: (a: Float32Array, v: any) => vec2.array(a, v),
Expand Down Expand Up @@ -114,7 +121,7 @@ export class Pass {
if (!this._pipelineLayout) { console.error('create pipeline layout failed'); return; }
this._shader = info.shader;
this._renderPass = info.renderPass;
this.createPipelineState(info);
this._createPipelineState(info);

for (const u of info.blocks) {
if (builtinRE.test(u.name)) {
Expand Down Expand Up @@ -199,9 +206,18 @@ export class Pass {
(this._bindingLayout as GFXBindingLayout).bindSampler(binding, value);
}

public setStates (info: IPassInfo) {
public rebuildWithOverrides (info: Partial<IPassInfo>, overrides: IPassOverrides) {
if (this._pipelineState) { this._pipelineState.destroy(); }
this.createPipelineState(info);
const ors = Object.assign({}, overrides);
this._createPipelineState(info, (states) => {
Object.assign(states.rs, ors.rs);
Object.assign(states.dss, ors.dss);
for (let i = 0; i < ors.bs.targets.length; i++) {
Object.assign(states.bs.targets[i], ors.bs.targets[i]);
}
delete ors.bs.targets;
Object.assign(states.bs, ors.bs);
});
}

public destroy () {
Expand All @@ -224,7 +240,7 @@ export class Pass {
(this._bindingLayout as GFXBindingLayout).update();
}

protected createPipelineState (info: IPassInfo) {
protected _createPipelineState (info: Partial<IPassInfo>, override?: (states: IGFXPipelineStateInfo) => any) {
if (info.primitive) { this._primitive = info.primitive; }
if (info.stage) { this._stage = info.stage; }

Expand Down Expand Up @@ -252,6 +268,7 @@ export class Pass {
rs: Object.assign(new GFXRasterizerState(), info.rasterizerState),
shader: this._shader,
};
if (override) { override(stateInfo); }
if (this._pipelineState) {
this._pipelineState.initialize(stateInfo);
} else {
Expand Down
2 changes: 1 addition & 1 deletion cocos/renderer/scene/render-scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { intersect, ray, triangle } from '../../3d/geom-utils';
import { RecyclePool } from '../../3d/memop';
import { _createSceneFun, Root } from '../../core/root';
import { mat4, vec3 } from '../../core/vmath';
import { GFXPrimitiveMode } from '../../gfx/define';
import { Layers } from '../../scene-graph/layers';
import { Camera, ICameraInfo } from './camera';
import { Light } from './light';
import { Model } from './model';
import { GFXPrimitiveMode } from '../../gfx/define';

export interface IRenderSceneInfo {
name: string;
Expand Down
6 changes: 3 additions & 3 deletions cocos/renderer/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export function createIA(device, data) {
vfmt.push({ name: GFXAttributeName.ATTR_COLOR, format: GFXFormat.RGB32F });
}

let vb = cc.director.root.device.createBuffer({
let vb = device.createBuffer({
usage: GFXBufferUsageBit.VERTEX,
memUsage: GFXMemoryUsageBit.HOST | GFXMemoryUsageBit.DEVICE,
size: verts.length * 4,
Expand All @@ -46,7 +46,7 @@ export function createIA(device, data) {

vb.update(new Float32Array(verts));

let ib = cc.director.root.device.createBuffer({
let ib = device.createBuffer({
usage: GFXBufferUsageBit.INDEX,
memUsage: GFXMemoryUsageBit.HOST | GFXMemoryUsageBit.DEVICE,
size: data.indices.length * 2,
Expand All @@ -55,7 +55,7 @@ export function createIA(device, data) {

ib.update(new Uint16Array(data.indices));

return cc.director.root.device.createInputAssembler({
return device.createInputAssembler({
attributes: vfmt,
vertexBuffers: [vb],
indexBuffer: ib,
Expand Down
2 changes: 1 addition & 1 deletion playground/simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
modelNode.parent = scene;
const modelCom = modelNode.addComponent('cc.ModelComponent');
modelCom.material = material;
modelCom.mesh = cc.utils.createMesh(cc.game._renderContext, cc.primitives.box());
modelCom.mesh = cc.utils.createMesh(cc.game._gfxDevice, cc.primitives.box());
modelNode.setRotationFromEuler(45, 45, 45);

cc.director.runSceneImmediate(scene);
Expand Down

0 comments on commit f09f802

Please sign in to comment.