Renderer Instancing.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /******************************************************************************/
  2. #if EE_PRIVATE
  3. /******************************************************************************/
  4. // INSTANCE
  5. /******************************************************************************/
  6. #define INSTANCE_PTR 1 // if store 'MeshPart.Variation' as pointer or index (pointer uses 8 bytes of memory, index 4 bytes, pointer doesn't need 'if' in the draw call, while index needs it)
  7. #define PER_INSTANCE_VEL 1
  8. #define PER_INSTANCE_ANG_VEL 0 // TODO: add support for this
  9. /******************************************************************************/
  10. extern Memc<Material::MaterialShader> MaterialShaders;
  11. struct EarlyZInstance
  12. {
  13. C MeshRender *mesh;
  14. Matrix view_matrix;
  15. EarlyZInstance& set(C MeshRender &mesh);
  16. };
  17. extern Memc<EarlyZInstance> EarlyZInstances[2];
  18. struct ShaderDraw
  19. {
  20. Int last_shader_material, first_shader_material; // keep 'last_shader_material' as first member, because it's used most often
  21. ShaderBase *shader;
  22. void unlink() {shader->unlink();}
  23. };
  24. extern Memc<ShaderDraw> ShaderDraws, MultiMaterialShaderDraws;
  25. struct ShaderMaterial
  26. {
  27. Int next_shader_material, last_shader_material_mesh, first_shader_material_mesh; // keep 'next_shader_material' as first member, because it's used most often
  28. #if SUPPORT_MATERIAL_CHANGE_IN_RENDERING
  29. union
  30. {
  31. Material *material;
  32. UniqueMultiMaterialData *umm;
  33. };
  34. #else
  35. // no need to store the material because we can obtain it from 'ShaderMaterialMesh'
  36. #endif
  37. void unlink();
  38. };
  39. extern Memc<ShaderMaterial> ShaderMaterials;
  40. struct ShaderMaterialMesh
  41. {
  42. Int next_shader_material_mesh, first_instance; // keep 'next_shader_material_mesh' as first member, because it's used most often
  43. C MeshPart *mesh;
  44. #if SUPPORT_MATERIAL_CHANGE_IN_RENDERING
  45. void unlink() {mesh->unlink();} // have to unlink all variations because we don't store pointer to variation
  46. #else
  47. #if INSTANCE_PTR
  48. C MeshPart::Variation *variation;
  49. C MeshPart::Variation& Variation()C {return *variation;}
  50. #else
  51. Int variation_1; // this is "variation-1"
  52. C MeshPart::Variation& Variation()C {return mesh->getVariation1(variation_1);}
  53. #endif
  54. void unlink() {Variation().unlink();}
  55. #endif
  56. };
  57. extern Memc<ShaderMaterialMesh> ShaderMaterialMeshes;
  58. struct SolidShaderMaterialMeshInstance
  59. {
  60. Int next_instance; // index of next instance in the same shader/material/mesh group in 'SolidShaderMaterialMeshInstances' container, keep 'next_instance' as first member, because it's used most often
  61. Vec vel, ang_vel_shader;
  62. Matrix view_matrix;
  63. C Memc<ShaderParamChange> *shader_param_changes;
  64. Color highlight;
  65. Byte stencil_value;
  66. SolidShaderMaterialMeshInstance& set();
  67. SolidShaderMaterialMeshInstance& setSkipVel();
  68. SolidShaderMaterialMeshInstance& set(C Vec &vel, C Vec &ang_vel_shader);
  69. };
  70. extern Memc<SolidShaderMaterialMeshInstance> SolidShaderMaterialMeshInstances;
  71. struct ShadowShaderMaterialMeshInstance
  72. {
  73. Int next_instance; // index of next instance in the same shader/material/mesh group in 'ShadowShaderMaterialMeshInstances' container, keep 'next_instance' as first member, because it's used most often
  74. Matrix view_matrix;
  75. C Memc<ShaderParamChange> *shader_param_changes;
  76. ShadowShaderMaterialMeshInstance& set();
  77. };
  78. extern Memc<ShadowShaderMaterialMeshInstance> ShadowShaderMaterialMeshInstances;
  79. struct AmbientInstance // ambient instances are stored in a simple way, without categorizing to shaders/materials, so we don't have to store one extra "MaterialShader _ambient_material_shader" in 'Material', also ambient instances are almost never used
  80. {
  81. C MeshPart *mesh;
  82. #if SUPPORT_MATERIAL_CHANGE_IN_RENDERING
  83. Shader *shader;
  84. Material *material;
  85. #if COUNT_MATERIAL_USAGE
  86. ~AmbientInstance() {material->decUsage();} // for ambient, material will always be != null, because only materials with ambient value can create ambient instances
  87. #endif
  88. #else
  89. #if INSTANCE_PTR
  90. C MeshPart::Variation *variation;
  91. C MeshPart::Variation& Variation()C {return *variation;}
  92. #else
  93. Int variation_1; // this is "variation-1"
  94. C MeshPart::Variation& Variation()C {return mesh->getVariation1(variation_1);}
  95. #endif
  96. #if COUNT_MATERIAL_USAGE
  97. ~AmbientInstance() {Variation().material->decUsage();} // for ambient, material will always be != null, because only materials with ambient value can create ambient instances
  98. #endif
  99. #endif
  100. Matrix view_matrix;
  101. C Memc<ShaderParamChange> *shader_param_changes;
  102. AmbientInstance& set(C MeshPart &mesh, C MeshPart::Variation &variation);
  103. };
  104. extern Memc<AmbientInstance> AmbientInstances;
  105. /******************************************************************************/
  106. // SKELETON
  107. /******************************************************************************/
  108. struct SkeletonShaderMaterial
  109. {
  110. C Material *material; // keep this as first member, because it's used most often
  111. Int next_skeleton_shader_material, first_mesh_instance, last_mesh_instance;
  112. #if COUNT_MATERIAL_USAGE
  113. ~SkeletonShaderMaterial() {if(material)material->decUsage();}
  114. #endif
  115. };
  116. extern Memc<SkeletonShaderMaterial> SkeletonShaderMaterials, SkeletonBlendShaderMaterials;
  117. struct SkeletonShaderMaterialMeshInstance
  118. {
  119. Int next_instance; // keep this as first member, because it's used most often
  120. C MeshRender *mesh;
  121. C Memc<ShaderParamChange> *shader_param_changes;
  122. void set(C MeshRender &mesh);
  123. void set(C MeshPart &mesh) {set(mesh.render);}
  124. };
  125. extern Memc<SkeletonShaderMaterialMeshInstance> SkeletonShadowShaderMaterialMeshInstances;
  126. STRUCT(SkeletonSolidShaderMaterialMeshInstance , SkeletonShaderMaterialMeshInstance)
  127. //{
  128. Color highlight;
  129. void set(C MeshRender &mesh);
  130. void set(C MeshPart &mesh) {set(mesh.render);}
  131. };
  132. extern Memc<SkeletonSolidShaderMaterialMeshInstance> SkeletonSolidShaderMaterialMeshInstances;
  133. STRUCT(SkeletonBlendShaderMaterialMeshInstance , SkeletonSolidShaderMaterialMeshInstance)
  134. //{
  135. STENCIL_MODE stencil_mode;
  136. void set(C MeshRender &mesh);
  137. void set(C MeshPart &mesh) {set(mesh.render);}
  138. };
  139. extern Memc<SkeletonBlendShaderMaterialMeshInstance> SkeletonBlendShaderMaterialMeshInstances;
  140. struct SkeletonShader
  141. {
  142. ShaderBase *shader; // keep this as first member, because it's used most often
  143. SkeletonShaderMaterial material;
  144. Int next_skeleton_shader;
  145. };
  146. extern Memc<SkeletonShader> SkeletonShaders;
  147. struct SkeletonBlendShader : SkeletonShader
  148. {
  149. Byte type; // BlendInstance::TYPE
  150. };
  151. extern Memc<SkeletonBlendShader> SkeletonBlendShaders;
  152. struct SkeletonInstance
  153. {
  154. C AnimatedSkeleton *anim_skel;
  155. SkeletonShader skel_shader;
  156. void set(C AnimatedSkeleton &anim_skel);
  157. void newInstance(ShaderBase &shader, C Material &material, Memc<SkeletonShaderMaterialMeshInstance> &instances);
  158. void unlinkSolid () {anim_skel->_instance.solid =-1;}
  159. void unlinkBlend () {anim_skel->_instance.blend =-1;}
  160. void unlinkShadow() {anim_skel->_instance.shadow=-1;}
  161. };
  162. struct SkeletonBlendInstance
  163. {
  164. C AnimatedSkeleton *anim_skel;
  165. SkeletonBlendShader skel_shader;
  166. void set(C AnimatedSkeleton &anim_skel);
  167. void newInstance(ShaderBase &shader, C Material &material, UInt type);
  168. void addBlend(Shader &shader, C Material &material, C MeshPart &mesh);
  169. void addBlend(BLST &blst , C Material &material, C MeshPart &mesh);
  170. void addFur (Shader &shader, C Material &material, C MeshPart &mesh);
  171. void unlinkSolid () {anim_skel->_instance.solid =-1;}
  172. void unlinkBlend () {anim_skel->_instance.blend =-1;}
  173. void unlinkShadow() {anim_skel->_instance.shadow=-1;}
  174. };
  175. struct SkeletonInstances : Memc<SkeletonInstance>
  176. {
  177. SkeletonInstance& getSkeletonInstance (C AnimatedSkeleton &anim_skel, Int &instance_index);
  178. INLINE SkeletonInstance& getSkeletonInstanceSolid (C AnimatedSkeleton &anim_skel) {return getSkeletonInstance(anim_skel, anim_skel._instance.solid );}
  179. INLINE SkeletonInstance& getSkeletonInstanceShadow(C AnimatedSkeleton &anim_skel) {return getSkeletonInstance(anim_skel, anim_skel._instance.shadow);}
  180. };
  181. extern SkeletonInstances SkeletonSolidInstances, SkeletonShadowInstances;
  182. struct SkeletonAmbientInstance // ambient instances are stored in a simple way, without categorizing to shaders/materials, so we don't have to store one extra "Int _ambient" in 'AnimatedSkeleton', also ambient instances are almost never used
  183. {
  184. C MeshPart *mesh;
  185. #if SUPPORT_MATERIAL_CHANGE_IN_RENDERING
  186. Shader *shader;
  187. C Material *material;
  188. #if COUNT_MATERIAL_USAGE
  189. ~SkeletonAmbientInstance() {material->decUsage();} // for ambient, material will always be != null, because only materials with ambient value can create ambient instances
  190. #endif
  191. #else
  192. #if INSTANCE_PTR
  193. C MeshPart::Variation *variation;
  194. C MeshPart::Variation& Variation()C {return *variation;}
  195. #else
  196. Int variation_1; // this is "variation-1"
  197. C MeshPart::Variation& Variation()C {return mesh->getVariation1(variation_1);}
  198. #endif
  199. #if COUNT_MATERIAL_USAGE
  200. ~SkeletonAmbientInstance() {Variation().material->decUsage();} // for ambient, material will always be != null, because only materials with ambient value can create ambient instances
  201. #endif
  202. #endif
  203. C AnimatedSkeleton *anim_skel;
  204. C Memc<ShaderParamChange> *shader_param_changes;
  205. void set(C MeshPart &mesh, C MeshPart::Variation &variation, C AnimatedSkeleton &anim_skel);
  206. };
  207. extern Memc<SkeletonAmbientInstance> SkeletonAmbientInstances;
  208. /******************************************************************************/
  209. // BLEND
  210. /******************************************************************************/
  211. struct BlendInstance
  212. {
  213. enum TYPE
  214. {
  215. SOLID ,
  216. SOLID_BLST,
  217. SOLID_FUR ,
  218. SKELETON ,
  219. BLEND_OBJ ,
  220. GAME_OBJ ,
  221. GAME_AREA ,
  222. }type;
  223. Flt z; // used for sorting
  224. struct Solid // solid
  225. {
  226. #if 1
  227. union
  228. {
  229. Shader *shader;
  230. BLST *blst ;
  231. };
  232. C Material *material;
  233. #else
  234. C MeshPart::Variation *variation;
  235. #endif
  236. C MeshPart *mesh;
  237. Vec vel, ang_vel_shader;
  238. Matrix view_matrix;
  239. C Memc<ShaderParamChange> *shader_param_changes;
  240. Color highlight;
  241. STENCIL_MODE stencil_mode;
  242. };
  243. union // Data
  244. {
  245. Solid s ; // solid
  246. SkeletonBlendInstance skeleton ; // skeleton
  247. BlendObject *blend_obj ; // blend object
  248. Game::Obj * game_obj ; // game object
  249. Game::Area::Data * game_area; // game area
  250. };
  251. void setViewZ(Flt z) {T.z=z;}
  252. void setZ (C VecD &pos);
  253. void setViewMatrix(C Matrix &view_matrix) {T.s.view_matrix=view_matrix; setViewZ(view_matrix.pos.z);}
  254. void setMatrix (C MatrixM & matrix);
  255. void unlink();
  256. ~BlendInstance();
  257. BlendInstance() {} // needed because of union
  258. };
  259. STRUCT(BlendInstancesClass , Memc<BlendInstance>)
  260. //{
  261. BlendInstance& add (Shader &shader, C Material &material, C MeshPart &mesh, C MeshPart::Variation &variation);
  262. BlendInstance& add (BLST &blst , C Material &material, C MeshPart &mesh, C MeshPart::Variation &variation, C Vec &vel, C Vec &ang_vel_shader);
  263. BlendInstance& addFur(Shader &shader, C Material &material, C MeshPart &mesh, C MeshPart::Variation &variation, C Vec &vel);
  264. void add(BlendObject &blend_obj, C VecD &pos);
  265. void add( Game::Obj & game_obj );
  266. void add( Game::Area::Data & game_area);
  267. SkeletonBlendInstance& getSkeletonInstance(C AnimatedSkeleton &anim_skel);
  268. };
  269. /******************************************************************************/
  270. // CLOTH
  271. /******************************************************************************/
  272. struct ClothInstance
  273. {
  274. C Cloth *cloth;
  275. ShaderBase *shader;
  276. C Material *material;
  277. Vec vel;
  278. Color highlight;
  279. #if COUNT_MATERIAL_USAGE
  280. ~ClothInstance() {if(material)material->decUsage();}
  281. #endif
  282. };
  283. STRUCT(ClothInstances , Memc<ClothInstance>)
  284. //{
  285. void add(C Cloth &cloth, Shader &shader, C Material &material);
  286. void add(C Cloth &cloth, Shader &shader, C Material &material, C Vec &vel);
  287. void add(C Cloth &cloth, FRST &frst , C Material &material);
  288. };
  289. /******************************************************************************/
  290. // MISC
  291. /******************************************************************************/
  292. STRUCT(GameObjects , Memc<Game::Obj*>)
  293. //{
  294. };
  295. STRUCT(GameAreas, Memc<Game::Area::Data*>)
  296. //{
  297. };
  298. /******************************************************************************/
  299. // VARIABLES
  300. /******************************************************************************/
  301. extern BlendInstancesClass BlendInstances;
  302. extern ClothInstances SolidClothInstances, ShadowClothInstances;
  303. extern GameObjects PaletteObjects, Palette1Objects, OverlayObjects, SolidObjects, AmbientObjects, OutlineObjects, BehindObjects;
  304. extern GameAreas PaletteAreas , Palette1Areas;
  305. /******************************************************************************/
  306. Bool HasEarlyZInstances();
  307. void DrawEarlyZInstances();
  308. void ClearEarlyZInstances();
  309. void DrawSolidInstances();
  310. void ClearSolidInstances();
  311. Int Compare(C BlendInstance &a, C BlendInstance &b);
  312. inline void SortBlendInstances() {BlendInstances.sort(Compare);}
  313. void DrawBlendInstances();
  314. void ClearBlendInstances();
  315. void SortAmbientInstances();
  316. void DrawAmbientInstances();
  317. void ClearAmbientInstances();
  318. void PrepareShadowInstances();
  319. void DrawShadowInstances();
  320. void DrawPaletteObjects();
  321. void DrawPalette1Objects();
  322. void DrawOverlayObjects();
  323. void DrawOutlineObjects();
  324. void DrawBehindObjects();
  325. void ShutInstances();
  326. void InitInstances();
  327. void ClearInstances();
  328. /******************************************************************************/
  329. #endif
  330. /******************************************************************************/