ShaderLoader.hx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package hide.tools;
  2. typedef CachedShader = {
  3. var file : String;
  4. var name : String;
  5. var shader : hxsl.SharedShader;
  6. var inits : Array<{ v : hxsl.Ast.TVar, e : hxsl.Ast.TExpr }>;
  7. var watch : Void -> Void;
  8. }
  9. class ShaderLoader {
  10. var ide : hide.Ide;
  11. var shaderPath : Array<String>;
  12. var shaderCache = new Map<String, CachedShader>();
  13. public function new() {
  14. ide = hide.Ide.inst;
  15. shaderPath = ide.currentConfig.get("haxe.classPath");
  16. }
  17. public function load( name : String ) {
  18. var s = loadSharedShader(name);
  19. if( s == null )
  20. return null;
  21. var d = new hxsl.DynamicShader(s.shader);
  22. for( v in s.inits )
  23. d.hscriptSet(v.v.name, hxsl.Ast.Tools.evalConst(v.e));
  24. return d;
  25. }
  26. public function loadSharedShader( name : String, ?file : String ) {
  27. var s = shaderCache.get(name);
  28. if( s != null )
  29. return s;
  30. var e = loadShaderExpr(name, file);
  31. if( e == null )
  32. return null;
  33. var chk = new hxsl.Checker();
  34. chk.loadShader = function(iname) {
  35. var e = loadShaderExpr(iname, null);
  36. if( e == null )
  37. throw "Could not @:import " + iname + " (referenced from " + name+")";
  38. return e.expr;
  39. };
  40. var s = new hxsl.SharedShader("");
  41. s.data = chk.check(name, e.expr);
  42. @:privateAccess s.initialize();
  43. var s : CachedShader = { file : e.file, name : name, shader : s, inits : chk.inits, watch : null };
  44. if(sys.FileSystem.exists(s.file)) {
  45. s.watch = onShaderChanged.bind(s);
  46. ide.fileWatcher.register(s.file, s.watch);
  47. }
  48. shaderCache.set(name, s);
  49. return s;
  50. }
  51. function onShaderChanged( s : CachedShader ) {
  52. shaderCache.remove(s.name);
  53. ide.fileWatcher.unregister(s.file, s.watch);
  54. }
  55. function loadShaderExpr( name : String, file : String ) : { file : String, expr : hxsl.Ast.Expr } {
  56. if( file != null && sys.FileSystem.exists(file) )
  57. return { file : file, expr : loadShaderString(file,sys.io.File.getContent(file), name) };
  58. var path = name.split(".").join("/")+".hx";
  59. for( s in shaderPath ) {
  60. var file = ide.projectDir + "/" + s + "/" + path;
  61. if( sys.FileSystem.exists(file) )
  62. return { file : file, expr : loadShaderString(file, sys.io.File.getContent(file), null) };
  63. }
  64. if( StringTools.startsWith(name,"h3d.shader.") ) {
  65. var r = haxe.Resource.getString("shader/" + name.substr(11));
  66. if( r != null ) return { file : null, expr : loadShaderString(path, r, null) };
  67. }
  68. return null;
  69. }
  70. function loadShaderString( file : String, content : String, name : String ) {
  71. var parser = new hscript.Parser();
  72. var decls = parser.parseModule(content, file);
  73. var cl = null, cf = null;
  74. for( d in decls ) {
  75. switch( d ) {
  76. case DClass(c) if( name == null || c.name == name.split(".").pop() ):
  77. for( f in c.fields )
  78. if( f.name == "SRC" ) {
  79. cl = c;
  80. cf = f;
  81. break;
  82. }
  83. if( cf != null )
  84. break;
  85. default:
  86. }
  87. }
  88. if( cf == null )
  89. throw file+" does not contain shader class";
  90. var expr = switch( cf.kind ) {
  91. case KVar(v): v.expr;
  92. default: throw "assert";
  93. }
  94. var e = new hscript.Macro({ min : 0, max : 0, file : file }).convert(expr);
  95. var e = new hxsl.MacroParser().parseExpr(e);
  96. switch( cl.extend ) {
  97. case CTPath(p,_):
  98. var path = p.join(".");
  99. if( path != "hxsl.Shader" ) {
  100. var pos = e.pos;
  101. e = { expr : EBlock([ { expr : ECall( { expr : EIdent("extends"), pos : pos }, [ { expr : EConst(CString(path)), pos : pos } ]), pos : pos }, e]), pos : pos };
  102. }
  103. default:
  104. }
  105. return e;
  106. }
  107. }