RenderContext.hx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. package h3d.impl;
  2. class RenderContext {
  3. public static var STRICT = true;
  4. public var engine : h3d.Engine;
  5. public var time : Float;
  6. public var elapsedTime : Float;
  7. public var frame : Int;
  8. public var textures : h3d.impl.TextureCache;
  9. public var globals : hxsl.Globals;
  10. public var shaderBuffers = new h3d.shader.Buffers();
  11. function new() {
  12. engine = h3d.Engine.getCurrent();
  13. frame = 0;
  14. time = 0.;
  15. elapsedTime = 1. / hxd.System.getDefaultFrameRate();
  16. textures = new h3d.impl.TextureCache();
  17. globals = new hxsl.Globals();
  18. }
  19. public function setCurrent() {
  20. inst = this;
  21. }
  22. public function clearCurrent() {
  23. if( inst == this )
  24. inst = null;
  25. else
  26. throw "Context has changed";
  27. }
  28. public function dispose() {
  29. textures.dispose();
  30. }
  31. function fillRec( v : Dynamic, type : hxsl.Ast.Type, out : #if hl hl.BytesAccess<hl.F32> #else h3d.shader.Buffers.ShaderBufferData #end, pos : Int ) {
  32. switch( type ) {
  33. case TInt:
  34. out[pos] = v;
  35. return 1;
  36. case TFloat:
  37. out[pos] = v;
  38. return 1;
  39. case TVec(4, _):
  40. var v : hxsl.Types.Vec4 = v;
  41. out[pos++] = v.x;
  42. out[pos++] = v.y;
  43. out[pos++] = v.z;
  44. out[pos++] = v.w;
  45. return 4;
  46. case TVec(n, _):
  47. var v : hxsl.Types.Vec = v;
  48. out[pos++] = v.x;
  49. out[pos++] = v.y;
  50. if( n == 3 )
  51. out[pos++] = v.z;
  52. return n;
  53. case TMat4:
  54. var m : h3d.Matrix = v;
  55. out[pos++] = m._11;
  56. out[pos++] = m._21;
  57. out[pos++] = m._31;
  58. out[pos++] = m._41;
  59. out[pos++] = m._12;
  60. out[pos++] = m._22;
  61. out[pos++] = m._32;
  62. out[pos++] = m._42;
  63. out[pos++] = m._13;
  64. out[pos++] = m._23;
  65. out[pos++] = m._33;
  66. out[pos++] = m._43;
  67. out[pos++] = m._14;
  68. out[pos++] = m._24;
  69. out[pos++] = m._34;
  70. out[pos++] = m._44;
  71. return 16;
  72. case TMat3x4:
  73. var m : h3d.Matrix = v;
  74. out[pos++] = m._11;
  75. out[pos++] = m._21;
  76. out[pos++] = m._31;
  77. out[pos++] = m._41;
  78. out[pos++] = m._12;
  79. out[pos++] = m._22;
  80. out[pos++] = m._32;
  81. out[pos++] = m._42;
  82. out[pos++] = m._13;
  83. out[pos++] = m._23;
  84. out[pos++] = m._33;
  85. out[pos++] = m._43;
  86. return 12;
  87. case TMat3:
  88. var m : h3d.Matrix = v;
  89. out[pos++] = m._11;
  90. out[pos++] = m._21;
  91. out[pos++] = m._31;
  92. out[pos++] = 0;
  93. out[pos++] = m._12;
  94. out[pos++] = m._22;
  95. out[pos++] = m._32;
  96. out[pos++] = 0;
  97. out[pos++] = m._13;
  98. out[pos++] = m._23;
  99. out[pos++] = m._33;
  100. out[pos++] = 0;
  101. return 12;
  102. case TArray(TVec(4,VFloat), SConst(len)):
  103. var v : Array<h3d.Vector4> = v;
  104. for( i in 0...len ) {
  105. var n = v[i];
  106. if( n == null ) break;
  107. out[pos++] = n.x;
  108. out[pos++] = n.y;
  109. out[pos++] = n.z;
  110. out[pos++] = n.w;
  111. }
  112. return len * 4;
  113. case TArray(TMat3x4, SConst(len)):
  114. var v : Array<h3d.Matrix> = v;
  115. for( i in 0...len ) {
  116. var m = v[i];
  117. if( m == null ) break;
  118. out[pos++] = m._11;
  119. out[pos++] = m._21;
  120. out[pos++] = m._31;
  121. out[pos++] = m._41;
  122. out[pos++] = m._12;
  123. out[pos++] = m._22;
  124. out[pos++] = m._32;
  125. out[pos++] = m._42;
  126. out[pos++] = m._13;
  127. out[pos++] = m._23;
  128. out[pos++] = m._33;
  129. out[pos++] = m._43;
  130. }
  131. return len * 12;
  132. case TArray(TFloat, SConst(len)):
  133. var v : Array<Float> = v;
  134. var size = 0;
  135. var count = v.length < len ? v.length : len;
  136. for( i in 0...count )
  137. out[pos++] = v[i];
  138. return len;
  139. case TArray(t, SConst(len)):
  140. var v : Array<Dynamic> = v;
  141. var size = 0;
  142. for( i in 0...len ) {
  143. var n = v[i];
  144. if( n == null ) break;
  145. size = fillRec(n, t, out, pos);
  146. pos += size;
  147. }
  148. return len * size;
  149. case TStruct(vl):
  150. var tot = 0;
  151. for( vv in vl )
  152. tot += fillRec(Reflect.field(v, vv.name), vv.type, out, pos + tot);
  153. return tot;
  154. default:
  155. throw "assert " + type;
  156. }
  157. return 0;
  158. }
  159. function shaderInfo( shaders : hxsl.ShaderList, path : String ) {
  160. var name = path.split(".").pop();
  161. while( shaders != null ) {
  162. var inst = @:privateAccess shaders.s.instance;
  163. for( v in inst.shader.vars )
  164. if( v.name == name )
  165. return shaders.s.toString();
  166. shaders = shaders.next;
  167. }
  168. return "(not found)";
  169. }
  170. inline function getPtr( data : h3d.shader.Buffers.ShaderBufferData ) {
  171. #if hl
  172. return (hl.Bytes.getArray((cast data : Array<Single>)) : hl.BytesAccess<hl.F32>);
  173. #else
  174. return data;
  175. #end
  176. }
  177. public inline function getParamValue( p : hxsl.RuntimeShader.AllocParam, shaders : hxsl.ShaderList, opt = false ) : Dynamic {
  178. if( p.perObjectGlobal != null ) {
  179. var v : Dynamic = globals.fastGet(p.perObjectGlobal.gid);
  180. if( v == null ) throw "Missing global value " + p.perObjectGlobal.path+" for shader "+shaderInfo(shaders,p.perObjectGlobal.path);
  181. if( p.type.match(TChannel(_)) )
  182. return v.texture;
  183. return v;
  184. }
  185. var si = shaders;
  186. var n = p.instance;
  187. while( --n > 0 ) si = si.next;
  188. var v = si.s.getParamValue(p.index);
  189. if( v == null && !opt ) throw "Missing param value " + si.s + "." + p.name;
  190. return v;
  191. }
  192. public function fillGlobals( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader ) {
  193. inline function fill(buf:h3d.shader.Buffers.ShaderBuffers, s:hxsl.RuntimeShader.RuntimeShaderData) {
  194. var g = s.globals;
  195. var ptr = getPtr(buf.globals);
  196. while( g != null ) {
  197. var v = globals.fastGet(g.gid);
  198. if( v == null )
  199. throw "Missing global value " + g.path;
  200. fillRec(v, g.type, ptr, g.pos);
  201. g = g.next;
  202. }
  203. }
  204. fill(buf.vertex, s.vertex);
  205. if( s.fragment != null ) fill(buf.fragment, s.fragment);
  206. }
  207. public function fillParams( buf : h3d.shader.Buffers, s : hxsl.RuntimeShader, shaders : hxsl.ShaderList, compute : Bool = false ) {
  208. var curInstance = -1;
  209. var curInstanceValue = null;
  210. inline function getInstance( index : Int ) {
  211. if( curInstance == index )
  212. return curInstanceValue;
  213. var si = shaders;
  214. curInstance = index;
  215. // Compute list has no linker shader.
  216. if ( compute ) index++;
  217. while( --index > 0 ) si = si.next;
  218. curInstanceValue = si.s;
  219. return curInstanceValue;
  220. }
  221. inline function getParamValue( p : hxsl.RuntimeShader.AllocParam, shaders : hxsl.ShaderList, opt = false ) : Dynamic {
  222. if( p.perObjectGlobal != null ) {
  223. var v : Dynamic = globals.fastGet(p.perObjectGlobal.gid);
  224. if( v == null ) throw "Missing global value " + p.perObjectGlobal.path+" for shader "+shaderInfo(shaders,p.perObjectGlobal.path);
  225. if( p.type.match(TChannel(_)) )
  226. return v.texture;
  227. return v;
  228. }
  229. var v = getInstance(p.instance).getParamValue(p.index);
  230. if( v == null && !opt ) throw "Missing param value " + shaders.s + "." + p.name;
  231. return v;
  232. }
  233. inline function fill(buf:h3d.shader.Buffers.ShaderBuffers, s:hxsl.RuntimeShader.RuntimeShaderData) {
  234. var p = s.params;
  235. var ptr = getPtr(buf.params);
  236. while( p != null ) {
  237. var v : Dynamic;
  238. if( p.perObjectGlobal == null ) {
  239. switch( p.type ) {
  240. case TFloat, TInt:
  241. var i = getInstance(p.instance);
  242. ptr[p.pos] = i.getParamFloatValue(p.index);
  243. p = p.next;
  244. continue;
  245. default:
  246. }
  247. v = getInstance(p.instance).getParamValue(p.index);
  248. if( v == null ) throw "Missing param value " + curInstanceValue + "." + p.name;
  249. } else
  250. v = getParamValue(p, shaders);
  251. fillRec(v, p.type, ptr, p.pos);
  252. p = p.next;
  253. }
  254. var tid = 0;
  255. var p = s.textures;
  256. while( p != null ) {
  257. var t : Dynamic = getParamValue(p, shaders, !STRICT);
  258. if( p.pos < 0 ) {
  259. // is array !
  260. var arr : Array<h3d.mat.Texture> = t;
  261. for( i in 0...-p.pos )
  262. buf.tex[tid++] = arr[i];
  263. } else
  264. buf.tex[tid++] = t;
  265. p = p.next;
  266. }
  267. var p = s.buffers;
  268. var bid = 0;
  269. while( p != null ) {
  270. var b : h3d.Buffer = getParamValue(p, shaders, !STRICT);
  271. buf.buffers[bid++] = b;
  272. p = p.next;
  273. }
  274. }
  275. fill(buf.vertex, s.vertex);
  276. if( s.fragment != null ) fill(buf.fragment, s.fragment);
  277. }
  278. static var inst : RenderContext;
  279. public static function get() return inst;
  280. public static inline function getType<T:RenderContext>( cl : Class<h3d.impl.RenderContext> ) {
  281. return Std.downcast(inst, cl);
  282. }
  283. }