|
@@ -2,8 +2,10 @@ package hxsl;
|
|
|
|
|
|
class DynamicShader extends Shader {
|
|
class DynamicShader extends Shader {
|
|
|
|
|
|
- var params = new Array<Dynamic>();
|
|
|
|
|
|
+ var values = new Array<Dynamic>();
|
|
|
|
+ var accesses = new Array<{ index : Int, fields : Array<String> }>();
|
|
var varIndexes = new Map<Int,Int>();
|
|
var varIndexes = new Map<Int,Int>();
|
|
|
|
+ var varNames = new Map<String,Int>();
|
|
var varIndex = 0;
|
|
var varIndex = 0;
|
|
|
|
|
|
public function new( s : SharedShader ) {
|
|
public function new( s : SharedShader ) {
|
|
@@ -13,36 +15,83 @@ class DynamicShader extends Shader {
|
|
addVarIndex(v);
|
|
addVarIndex(v);
|
|
}
|
|
}
|
|
|
|
|
|
- function addVarIndex(v:hxsl.Ast.TVar) {
|
|
|
|
|
|
+ function addVarIndex(v:hxsl.Ast.TVar, ?access : { index : Int, fields : Array<String> }, ?defObj : Dynamic ) {
|
|
if( v.kind != Param )
|
|
if( v.kind != Param )
|
|
return;
|
|
return;
|
|
|
|
+ var vid = values.length;
|
|
|
|
+ if( access != null )
|
|
|
|
+ access = { index : access.index, fields : access.fields.copy() };
|
|
switch(v.type){
|
|
switch(v.type){
|
|
case TStruct(vl):
|
|
case TStruct(vl):
|
|
- for( v in vl )
|
|
|
|
- addVarIndex(v);
|
|
|
|
|
|
+ var vobj = {};
|
|
|
|
+ if( access == null ) {
|
|
|
|
+ values.push(vobj);
|
|
|
|
+ access = { index : vid, fields : [] };
|
|
|
|
+ varNames.set(v.name, vid);
|
|
|
|
+ } else {
|
|
|
|
+ Reflect.setField(defObj, v.name, vobj);
|
|
|
|
+ }
|
|
|
|
+ for( v in vl ) {
|
|
|
|
+ access.fields.push(v.name);
|
|
|
|
+ addVarIndex(v, access, vobj);
|
|
|
|
+ access.fields.pop();
|
|
|
|
+ }
|
|
return;
|
|
return;
|
|
default:
|
|
default:
|
|
}
|
|
}
|
|
|
|
+ var value : Dynamic = null;
|
|
switch( v.type ) {
|
|
switch( v.type ) {
|
|
case TSampler2D:
|
|
case TSampler2D:
|
|
- params[varIndex] = h3d.mat.Texture.fromColor(0xFF00FF);
|
|
|
|
|
|
+ value = h3d.mat.Texture.fromColor(0xFF00FF);
|
|
case TSamplerCube:
|
|
case TSamplerCube:
|
|
- params[varIndex] = h3d.mat.Texture.defaultCubeTexture();
|
|
|
|
|
|
+ value = h3d.mat.Texture.defaultCubeTexture();
|
|
|
|
+ case TVec(_):
|
|
|
|
+ value = new h3d.Vector();
|
|
|
|
+ case TMat3, TMat4, TMat3x4:
|
|
|
|
+ var m = new h3d.Matrix();
|
|
|
|
+ m.identity();
|
|
|
|
+ value = m;
|
|
|
|
+ case TInt, TFloat:
|
|
|
|
+ value = 0;
|
|
|
|
+ case TBool:
|
|
|
|
+ value = false;
|
|
default:
|
|
default:
|
|
}
|
|
}
|
|
- varIndexes.set(v.id, varIndex++);
|
|
|
|
|
|
+ if( access == null ) {
|
|
|
|
+ varNames.set(v.name, vid);
|
|
|
|
+ values.push(value);
|
|
|
|
+ } else
|
|
|
|
+ Reflect.setField(defObj, v.name, value);
|
|
|
|
+
|
|
|
|
+ var vidx = accesses.length;
|
|
|
|
+ varIndexes.set(v.id, vidx);
|
|
|
|
+ accesses.push(access == null ? { index : vid, fields : null } : access);
|
|
}
|
|
}
|
|
|
|
|
|
override function getParamValue(index:Int) : Dynamic {
|
|
override function getParamValue(index:Int) : Dynamic {
|
|
- return params[index];
|
|
|
|
|
|
+ var a = accesses[index];
|
|
|
|
+ var v = values[a.index];
|
|
|
|
+ if( a.fields != null )
|
|
|
|
+ for( f in a.fields )
|
|
|
|
+ v = Reflect.field(v, f);
|
|
|
|
+ return v;
|
|
}
|
|
}
|
|
|
|
|
|
- override public function getParamFloatValue(index:Int):Float {
|
|
|
|
- return params[index];
|
|
|
|
|
|
+ override function getParamFloatValue(index:Int):Float {
|
|
|
|
+ return getParamValue(index);
|
|
}
|
|
}
|
|
|
|
|
|
public function setParamValue( p : hxsl.Ast.TVar, value : Dynamic ) {
|
|
public function setParamValue( p : hxsl.Ast.TVar, value : Dynamic ) {
|
|
- params[varIndexes.get(p.id)] = value;
|
|
|
|
|
|
+ var vidx = varIndexes.get(p.id);
|
|
|
|
+ var a = accesses[vidx];
|
|
|
|
+ if( a.fields == null )
|
|
|
|
+ values[a.index] = value;
|
|
|
|
+ else {
|
|
|
|
+ var obj = values[a.index];
|
|
|
|
+ for( i in 0...a.fields.length - 1 )
|
|
|
|
+ obj = Reflect.field(obj, a.fields[i]);
|
|
|
|
+ Reflect.setField(obj, a.fields[a.fields.length - 1], value);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
override function updateConstants( globals : Globals ) {
|
|
override function updateConstants( globals : Globals ) {
|
|
@@ -53,7 +102,7 @@ class DynamicShader extends Shader {
|
|
c = c.next;
|
|
c = c.next;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- var v : Dynamic = params[varIndexes.get(c.v.id)];
|
|
|
|
|
|
+ var v : Dynamic = getParamValue(varIndexes.get(c.v.id));
|
|
switch( c.v.type ) {
|
|
switch( c.v.type ) {
|
|
case TInt:
|
|
case TInt:
|
|
var v : Int = v;
|
|
var v : Int = v;
|
|
@@ -71,4 +120,24 @@ class DynamicShader extends Shader {
|
|
updateConstantsFinal(globals);
|
|
updateConstantsFinal(globals);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
|
|
+ #if hscript
|
|
|
|
+ @:keep public function hscriptGet( field : String ) {
|
|
|
|
+ var vid = varNames.get(field);
|
|
|
|
+ if( vid == null )
|
|
|
|
+ return Reflect.getProperty(this, field);
|
|
|
|
+ return values[vid];
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @:keep public function hscriptSet( field : String, value : Dynamic ) : Dynamic {
|
|
|
|
+ var vid = varNames.get(field);
|
|
|
|
+ if( vid == null ) {
|
|
|
|
+ Reflect.setProperty(this, field, value);
|
|
|
|
+ return value;
|
|
|
|
+ }
|
|
|
|
+ return values[vid] = value;
|
|
|
|
+ }
|
|
|
|
+ #end
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|