|
@@ -2,15 +2,58 @@ package hrt.prefab;
|
|
|
|
|
|
class Shader extends Prefab {
|
|
|
|
|
|
+ public function new(?parent) {
|
|
|
+ super(parent);
|
|
|
+ props = {};
|
|
|
+ }
|
|
|
+
|
|
|
public function makeShader( ?ctx : hrt.prefab.Context ) : hxsl.Shader {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- public function getShaderDefinition( ?ctx : hrt.prefab.Context ) : hxsl.SharedShader {
|
|
|
+ public function getShaderDefinition( ctx : hrt.prefab.Context ) : hxsl.SharedShader {
|
|
|
var s = makeShader(ctx);
|
|
|
return s == null ? null : @:privateAccess s.shader;
|
|
|
}
|
|
|
|
|
|
+ override function updateInstance(ctx: Context, ?propName) {
|
|
|
+ var shaderDef = getShaderDefinition(ctx);
|
|
|
+ if( ctx.custom == null || shaderDef == null )
|
|
|
+ return;
|
|
|
+ syncShaderVars(ctx.custom, shaderDef);
|
|
|
+ }
|
|
|
+
|
|
|
+ function syncShaderVars( shader : hxsl.Shader, shaderDef : hxsl.SharedShader ) {
|
|
|
+ for(v in shaderDef.data.vars) {
|
|
|
+ if(v.kind != Param)
|
|
|
+ continue;
|
|
|
+ var val : Dynamic = Reflect.field(props, v.name);
|
|
|
+ switch(v.type) {
|
|
|
+ case TVec(_, VFloat):
|
|
|
+ if(val != null)
|
|
|
+ val = h3d.Vector.fromArray(val);
|
|
|
+ else
|
|
|
+ val = new h3d.Vector();
|
|
|
+ case TSampler2D:
|
|
|
+ if( val != null )
|
|
|
+ val = hxd.res.Loader.currentInstance.load(val).toTexture();
|
|
|
+ else {
|
|
|
+ var childNoise = getOpt(hrt.prefab.l2d.NoiseGenerator, v.name);
|
|
|
+ if(childNoise != null)
|
|
|
+ val = childNoise.toTexture();
|
|
|
+ }
|
|
|
+ default:
|
|
|
+ }
|
|
|
+ if(val == null)
|
|
|
+ continue;
|
|
|
+ setShaderParam(shader,v,val);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function setShaderParam( shader:hxsl.Shader, v : hxsl.Ast.TVar, value : Dynamic ) {
|
|
|
+ Reflect.setProperty(shader, v.name, value);
|
|
|
+ }
|
|
|
+
|
|
|
override function makeInstance(ctx:Context):Context {
|
|
|
ctx = ctx.clone(this);
|
|
|
var shader = makeShader(ctx);
|
|
@@ -57,4 +100,59 @@ class Shader extends Prefab {
|
|
|
return ctx;
|
|
|
}
|
|
|
|
|
|
+ #if editor
|
|
|
+
|
|
|
+ override function edit( ectx : EditContext ) {
|
|
|
+ super.edit(ectx);
|
|
|
+
|
|
|
+ var ctx = ectx.getContext(this);
|
|
|
+ var shaderDef = getShaderDefinition(ctx);
|
|
|
+ if( shaderDef == null )
|
|
|
+ return;
|
|
|
+
|
|
|
+ var group = new hide.Element('<div class="group" name="Shader"></div>');
|
|
|
+ var props = [];
|
|
|
+ for(v in shaderDef.data.vars) {
|
|
|
+ if( v.kind != Param )
|
|
|
+ continue;
|
|
|
+ var prop = makeShaderType(v);
|
|
|
+ if( prop == null ) continue;
|
|
|
+ props.push({name: v.name, t: prop});
|
|
|
+ }
|
|
|
+ group.append(hide.comp.PropsEditor.makePropsList(props));
|
|
|
+ ectx.properties.add(group,this.props, function(pname) {
|
|
|
+ ectx.onChange(this, pname);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function makeShaderType( v : hxsl.Ast.TVar ) : hrt.prefab.Props.PropType {
|
|
|
+ var min : Null<Float> = null, max : Null<Float> = null;
|
|
|
+ if( v.qualifiers != null )
|
|
|
+ for( q in v.qualifiers )
|
|
|
+ switch( q ) {
|
|
|
+ case Range(rmin, rmax): min = rmin; max = rmax;
|
|
|
+ default:
|
|
|
+ }
|
|
|
+ return switch( v.type ) {
|
|
|
+ case TInt:
|
|
|
+ PInt(min == null ? null : Std.int(min), max == null ? null : Std.int(max));
|
|
|
+ case TFloat:
|
|
|
+ PFloat(min != null ? min : 0.0, max != null ? max : 1.0);
|
|
|
+ case TBool:
|
|
|
+ PBool;
|
|
|
+ case TSampler2D:
|
|
|
+ PTexture;
|
|
|
+ case TVec(n, VFloat):
|
|
|
+ PVec(n);
|
|
|
+ default:
|
|
|
+ PUnsupported(hxsl.Ast.Tools.toString(v.type));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ override function getHideProps() : HideProps {
|
|
|
+ return { icon : "cog", name : "Shader", fileSource : ["hx"], allowParent : function(p) return p.to(Object2D) != null || p.to(Object3D) != null || p.to(Material) != null };
|
|
|
+ }
|
|
|
+
|
|
|
+ #end
|
|
|
+
|
|
|
}
|