render_world.cpp 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751
  1. /*
  2. * Copyright (c) 2012-2025 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "core/containers/array.inl"
  6. #include "core/containers/hash_map.inl"
  7. #include "core/containers/hash_set.inl"
  8. #include "core/list.inl"
  9. #include "core/math/aabb.h"
  10. #include "core/math/color4.inl"
  11. #include "core/math/constants.h"
  12. #include "core/math/frustum.inl"
  13. #include "core/math/intersection.h"
  14. #include "core/math/matrix4x4.inl"
  15. #include "core/strings/string_id.inl"
  16. #include "device/pipeline.h"
  17. #include "resource/mesh_resource.h"
  18. #include "resource/render_config_resource.h"
  19. #include "resource/resource_manager.h"
  20. #include "resource/sprite_resource.h"
  21. #include "world/debug_line.h"
  22. #include "world/material.h"
  23. #include "world/material_manager.h"
  24. #include "world/render_world.h"
  25. #include "world/scene_graph.h"
  26. #include "world/shader_manager.h"
  27. #include "world/unit_manager.h"
  28. #include <algorithm> // std::sort
  29. #include <bgfx/bgfx.h>
  30. #include <bx/math.h>
  31. namespace crown
  32. {
  33. static void unit_destroyed_callback_bridge(UnitId unit, void *user_ptr)
  34. {
  35. ((RenderWorld *)user_ptr)->unit_destroyed_callback(unit);
  36. }
  37. RenderWorld::RenderWorld(Allocator &a
  38. , ResourceManager &rm
  39. , ShaderManager &sm
  40. , MaterialManager &mm
  41. , UnitManager &um
  42. , Pipeline &pl
  43. , SceneGraph &sg
  44. )
  45. : _marker(RENDER_WORLD_MARKER)
  46. , _resource_manager(&rm)
  47. , _shader_manager(&sm)
  48. , _material_manager(&mm)
  49. , _unit_manager(&um)
  50. , _pipeline(&pl)
  51. , _scene_graph(&sg)
  52. , _debug_drawing(false)
  53. , _mesh_manager(a, this)
  54. , _sprite_manager(a, this)
  55. , _light_manager(a)
  56. , _selection(a)
  57. , _fog_unit(UNIT_INVALID)
  58. , _global_lighting_unit(UNIT_INVALID)
  59. , _bloom_unit(UNIT_INVALID)
  60. {
  61. _unit_destroy_callback.destroy = unit_destroyed_callback_bridge;
  62. _unit_destroy_callback.user_data = this;
  63. _unit_destroy_callback.node.next = NULL;
  64. _unit_destroy_callback.node.prev = NULL;
  65. um.register_destroy_callback(&_unit_destroy_callback);
  66. // Fog.
  67. memset(&_fog_desc, 0, sizeof(_fog_desc));
  68. // Global lighting.
  69. memset((void *)&_global_lighting_desc, 0, sizeof(_global_lighting_desc));
  70. // Bloom.
  71. memset((void *)&_bloom_desc, 0, sizeof(_bloom_desc));
  72. // Tonemap.
  73. memset((void *)&_tonemap_desc, 0, sizeof(_tonemap_desc));
  74. _tonemap_desc.type = TonemapType::REINHARD;
  75. }
  76. RenderWorld::~RenderWorld()
  77. {
  78. _unit_manager->unregister_destroy_callback(&_unit_destroy_callback);
  79. _mesh_manager.destroy();
  80. _sprite_manager.destroy();
  81. _light_manager.destroy();
  82. _marker = 0;
  83. }
  84. MeshInstance RenderWorld::mesh_create(UnitId unit, const MeshRendererDesc &mrd, const Matrix4x4 &tr)
  85. {
  86. const MeshResource *mr = (MeshResource *)_resource_manager->get(RESOURCE_TYPE_MESH, mrd.mesh_resource);
  87. const MaterialResource *mat_res = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, mrd.material_resource);
  88. _material_manager->create_material(mat_res);
  89. return _mesh_manager.create(unit, mr, mrd, tr);
  90. }
  91. void RenderWorld::mesh_destroy(MeshInstance mesh)
  92. {
  93. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  94. _mesh_manager.destroy(mesh);
  95. }
  96. MeshInstance RenderWorld::mesh_instance(UnitId unit)
  97. {
  98. return _mesh_manager.mesh(unit);
  99. }
  100. void RenderWorld::mesh_set_geometry(MeshInstance mesh, StringId64 mesh_resource, StringId32 geometry)
  101. {
  102. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  103. const MeshResource *mr = (MeshResource *)_resource_manager->get(RESOURCE_TYPE_MESH, mesh_resource);
  104. _mesh_manager.set_geometry(mesh, mr, geometry);
  105. }
  106. void RenderWorld::mesh_set_skeleton(MeshInstance mesh, const AnimationSkeletonInstance *bones)
  107. {
  108. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  109. _mesh_manager._data.skeleton[mesh.i] = (AnimationSkeletonInstance *)bones;
  110. UnitId unit = _mesh_manager._data.unit[mesh.i];
  111. TransformInstance ti = _scene_graph->instance(unit);
  112. _scene_graph->set_local_pose(ti, MATRIX4X4_IDENTITY);
  113. }
  114. Material *RenderWorld::mesh_material(MeshInstance mesh)
  115. {
  116. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  117. return _mesh_manager._data.material[mesh.i];
  118. }
  119. void RenderWorld::mesh_set_material(MeshInstance mesh, StringId64 id)
  120. {
  121. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  122. const MaterialResource *mat_res = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, id);
  123. _mesh_manager._data.material[mesh.i] = _material_manager->create_material(mat_res);
  124. }
  125. void RenderWorld::mesh_set_visible(MeshInstance mesh, bool visible)
  126. {
  127. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  128. _mesh_manager.set_visible(mesh, visible);
  129. }
  130. void RenderWorld::mesh_set_cast_shadows(MeshInstance mesh, bool cast_shadows)
  131. {
  132. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  133. if (cast_shadows)
  134. _mesh_manager._data.flags[mesh.i] |= RenderableFlags::SHADOW_CASTER;
  135. else
  136. _mesh_manager._data.flags[mesh.i] &= ~RenderableFlags::SHADOW_CASTER;
  137. }
  138. OBB RenderWorld::mesh_obb(MeshInstance mesh)
  139. {
  140. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  141. const Matrix4x4 &world = _mesh_manager._data.world[mesh.i];
  142. const OBB &obb = _mesh_manager._data.obb[mesh.i];
  143. OBB o;
  144. o.tm = obb.tm * world;
  145. o.half_extents = obb.half_extents;
  146. return o;
  147. }
  148. f32 RenderWorld::mesh_cast_ray(MeshInstance mesh, const Vector3 &from, const Vector3 &dir)
  149. {
  150. CE_ASSERT(mesh.i < _mesh_manager._data.size, "Index out of bounds");
  151. const MeshGeometry *mg = _mesh_manager._data.geometry[mesh.i];
  152. return ray_mesh_intersection(from
  153. , dir
  154. , _mesh_manager._data.world[mesh.i]
  155. , mg->vertices.data
  156. , mg->vertices.stride
  157. , (u16 *)mg->indices.data
  158. , mg->indices.num
  159. );
  160. }
  161. SpriteInstance RenderWorld::sprite_create(UnitId unit, const SpriteRendererDesc &srd, const Matrix4x4 &tr)
  162. {
  163. const SpriteResource *sr = (SpriteResource *)_resource_manager->get(RESOURCE_TYPE_SPRITE, srd.sprite_resource);
  164. const MaterialResource *mat_res = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, srd.material_resource);
  165. _material_manager->create_material(mat_res);
  166. return _sprite_manager.create(unit, sr, srd, tr);
  167. }
  168. void RenderWorld::sprite_destroy(SpriteInstance sprite)
  169. {
  170. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  171. _sprite_manager.destroy(sprite);
  172. }
  173. SpriteInstance RenderWorld::sprite_instance(UnitId unit)
  174. {
  175. return _sprite_manager.sprite(unit);
  176. }
  177. void RenderWorld::sprite_set_sprite(SpriteInstance sprite, StringId64 sprite_resource_name)
  178. {
  179. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  180. const SpriteResource *resource = (SpriteResource *)_resource_manager->get(RESOURCE_TYPE_SPRITE, sprite_resource_name);
  181. _sprite_manager._data.resource[sprite.i] = resource;
  182. }
  183. Material *RenderWorld::sprite_material(SpriteInstance sprite)
  184. {
  185. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  186. return _sprite_manager._data.material[sprite.i];
  187. }
  188. void RenderWorld::sprite_set_material(SpriteInstance sprite, StringId64 id)
  189. {
  190. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  191. const MaterialResource *mat_res = (MaterialResource *)_resource_manager->get(RESOURCE_TYPE_MATERIAL, id);
  192. _sprite_manager._data.material[sprite.i] = _material_manager->create_material(mat_res);
  193. }
  194. void RenderWorld::sprite_set_frame(SpriteInstance sprite, u32 index)
  195. {
  196. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  197. _sprite_manager._data.frame[sprite.i] = index;
  198. }
  199. void RenderWorld::sprite_set_visible(SpriteInstance sprite, bool visible)
  200. {
  201. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  202. _sprite_manager.set_visible(sprite, visible);
  203. }
  204. void RenderWorld::sprite_flip_x(SpriteInstance sprite, bool flip)
  205. {
  206. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  207. if (flip)
  208. _sprite_manager._data.flags[sprite.i] |= SpriteFlags::FLIP_X;
  209. else
  210. _sprite_manager._data.flags[sprite.i] &= ~SpriteFlags::FLIP_X;
  211. }
  212. void RenderWorld::sprite_flip_y(SpriteInstance sprite, bool flip)
  213. {
  214. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  215. if (flip)
  216. _sprite_manager._data.flags[sprite.i] |= SpriteFlags::FLIP_Y;
  217. else
  218. _sprite_manager._data.flags[sprite.i] &= ~SpriteFlags::FLIP_Y;
  219. }
  220. void RenderWorld::sprite_set_layer(SpriteInstance sprite, u32 layer)
  221. {
  222. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  223. _sprite_manager._data.layer[sprite.i] = layer;
  224. }
  225. void RenderWorld::sprite_set_depth(SpriteInstance sprite, u32 depth)
  226. {
  227. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  228. _sprite_manager._data.depth[sprite.i] = depth;
  229. }
  230. OBB RenderWorld::sprite_obb(SpriteInstance sprite)
  231. {
  232. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  233. const OBB &obb = _sprite_manager._data.resource[sprite.i]->obb;
  234. const Matrix4x4 &world = _sprite_manager._data.world[sprite.i];
  235. OBB o;
  236. o.tm = obb.tm * world;
  237. o.half_extents = obb.half_extents;
  238. return o;
  239. }
  240. f32 RenderWorld::sprite_cast_ray(SpriteInstance sprite, const Vector3 &from, const Vector3 &dir, u32 &layer, u32 &depth)
  241. {
  242. CE_ASSERT(sprite.i < _sprite_manager._data.size, "Index out of bounds");
  243. const SpriteManager::SpriteInstanceData &sid = _sprite_manager._data;
  244. const f32 *frame = sprite_resource::frame_data(sid.resource[sprite.i], sid.frame[sprite.i]);
  245. const f32 vertices[] =
  246. {
  247. frame[ 0], frame[ 1], frame[ 2],
  248. frame[ 5], frame[ 6], frame[ 7],
  249. frame[10], frame[11], frame[12],
  250. frame[15], frame[16], frame[17]
  251. };
  252. const u16 indices[] =
  253. {
  254. 0, 1, 2,
  255. 0, 2, 3
  256. };
  257. layer = _sprite_manager._data.layer[sprite.i];
  258. depth = _sprite_manager._data.depth[sprite.i];
  259. return ray_mesh_intersection(from
  260. , dir
  261. , _sprite_manager._data.world[sprite.i]
  262. , vertices
  263. , sizeof(Vector3)
  264. , indices
  265. , 6
  266. );
  267. }
  268. LightInstance RenderWorld::light_create(UnitId unit, const LightDesc &ld, const Matrix4x4 &tr)
  269. {
  270. return _light_manager.create(unit, ld, tr);
  271. }
  272. void RenderWorld::light_destroy(LightInstance light)
  273. {
  274. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  275. _light_manager.destroy(light);
  276. }
  277. LightInstance RenderWorld::light_instance(UnitId unit)
  278. {
  279. return _light_manager.light(unit);
  280. }
  281. Color4 RenderWorld::light_color(LightInstance light)
  282. {
  283. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  284. Vector3 c = _light_manager._data.shader[light.i].color;
  285. return { c.x, c.y, c.z, 0.0f };
  286. }
  287. LightType::Enum RenderWorld::light_type(LightInstance light)
  288. {
  289. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  290. return (LightType::Enum)_light_manager._data.type[light.i];
  291. }
  292. f32 RenderWorld::light_range(LightInstance light)
  293. {
  294. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  295. return _light_manager._data.shader[light.i].range;
  296. }
  297. f32 RenderWorld::light_intensity(LightInstance light)
  298. {
  299. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  300. return _light_manager._data.shader[light.i].intensity;
  301. }
  302. f32 RenderWorld::light_spot_angle(LightInstance light)
  303. {
  304. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  305. return _light_manager._data.shader[light.i].spot_angle;
  306. }
  307. f32 RenderWorld::light_shadow_bias(LightInstance light)
  308. {
  309. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  310. return _light_manager._data.shader[light.i].shadow_bias;
  311. }
  312. void RenderWorld::light_set_color(LightInstance light, const Color4 &col)
  313. {
  314. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  315. _light_manager._data.shader[light.i].color = { col.x, col.y, col.z };
  316. }
  317. void RenderWorld::light_set_type(LightInstance light, LightType::Enum type)
  318. {
  319. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  320. _light_manager._data.type[light.i] = type;
  321. }
  322. void RenderWorld::light_set_range(LightInstance light, f32 range)
  323. {
  324. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  325. _light_manager._data.shader[light.i].range = range;
  326. }
  327. void RenderWorld::light_set_intensity(LightInstance light, f32 intensity)
  328. {
  329. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  330. _light_manager._data.shader[light.i].intensity = intensity;
  331. }
  332. void RenderWorld::light_set_spot_angle(LightInstance light, f32 angle)
  333. {
  334. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  335. _light_manager._data.shader[light.i].spot_angle = angle;
  336. }
  337. void RenderWorld::light_set_shadow_bias(LightInstance light, f32 bias)
  338. {
  339. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  340. _light_manager._data.shader[light.i].shadow_bias = bias;
  341. }
  342. void RenderWorld::light_set_cast_shadows(LightInstance light, bool cast_shadows)
  343. {
  344. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  345. if (cast_shadows)
  346. _light_manager._data.flag[light.i] |= RenderableFlags::SHADOW_CASTER;
  347. else
  348. _light_manager._data.flag[light.i] &= ~RenderableFlags::SHADOW_CASTER;
  349. }
  350. void RenderWorld::light_debug_draw(LightInstance light, DebugLine &dl)
  351. {
  352. CE_ASSERT(light.i < _light_manager._data.size, "Index out of bounds");
  353. _light_manager.debug_draw(light.i, 1, dl);
  354. }
  355. FogInstance RenderWorld::fog_create(UnitId unit, const FogDesc &desc)
  356. {
  357. _fog_unit = unit;
  358. _fog = { 0u };
  359. _fog_desc = desc;
  360. return _fog;
  361. }
  362. void RenderWorld::fog_destroy(FogInstance fog)
  363. {
  364. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  365. _fog_desc = {};
  366. _fog = { UINT32_MAX };
  367. _fog_unit = UNIT_INVALID;
  368. }
  369. FogInstance RenderWorld::fog_instance(UnitId unit)
  370. {
  371. if (_fog_unit == unit)
  372. return _fog;
  373. return { UINT32_MAX };
  374. }
  375. void RenderWorld::fog_set_color(FogInstance fog, Vector3 color)
  376. {
  377. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  378. _fog_desc.color = color;
  379. }
  380. void RenderWorld::fog_set_density(FogInstance fog, float density)
  381. {
  382. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  383. _fog_desc.density = density;
  384. }
  385. void RenderWorld::fog_set_range_min(FogInstance fog, float range)
  386. {
  387. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  388. _fog_desc.range_min = range;
  389. }
  390. void RenderWorld::fog_set_range_max(FogInstance fog, float range)
  391. {
  392. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  393. _fog_desc.range_max = range;
  394. }
  395. void RenderWorld::fog_set_sun_blend(FogInstance fog, float sun_blend)
  396. {
  397. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  398. _fog_desc.sun_blend = sun_blend;
  399. }
  400. void RenderWorld::fog_set_enabled(FogInstance fog, bool enable)
  401. {
  402. CE_ASSERT(fog.i == _fog.i, "Instance not found");
  403. _fog_desc.enabled = (f32)enable;
  404. }
  405. u32 RenderWorld::global_lighting_create(UnitId unit, const GlobalLightingDesc &desc)
  406. {
  407. _global_lighting_desc = desc;
  408. _global_lighting_unit = unit;
  409. return 0;
  410. }
  411. GlobalLightingInstance RenderWorld::global_lighting_instance(UnitId unit)
  412. {
  413. if (_global_lighting_unit == unit)
  414. return { 0 };
  415. return { UINT32_MAX };
  416. }
  417. void RenderWorld::global_lighting_destroy(u32 global_lighting)
  418. {
  419. CE_UNUSED(global_lighting);
  420. _global_lighting_desc = {};
  421. _global_lighting_unit = UNIT_INVALID;
  422. }
  423. void RenderWorld::global_lighting_set_skydome_map(StringId64 texture_name)
  424. {
  425. _global_lighting_desc.skydome_map = texture_name;
  426. }
  427. void RenderWorld::global_lighting_set_skydome_intensity(f32 intensity)
  428. {
  429. _global_lighting_desc.skydome_intensity = intensity;
  430. }
  431. void RenderWorld::global_lighting_set_ambient_color(Color4 color)
  432. {
  433. _global_lighting_desc.ambient_color = { color.x, color.y, color.z };
  434. }
  435. u32 RenderWorld::bloom_create(UnitId unit, const BloomDesc &desc)
  436. {
  437. _bloom_desc = desc;
  438. _bloom_unit = unit;
  439. return 0;
  440. }
  441. void RenderWorld::bloom_destroy(u32 bloom)
  442. {
  443. CE_UNUSED(bloom);
  444. _bloom_desc = {};
  445. _bloom_unit = UNIT_INVALID;
  446. }
  447. BloomInstance RenderWorld::bloom_instance(UnitId unit)
  448. {
  449. if (_bloom_unit == unit)
  450. return { 0 };
  451. return { UINT32_MAX };
  452. }
  453. void RenderWorld::bloom_set_enabled(bool enabled)
  454. {
  455. _bloom_desc.enabled = enabled;
  456. }
  457. void RenderWorld::bloom_set_weight(float weight)
  458. {
  459. _bloom_desc.weight = weight;
  460. }
  461. void RenderWorld::bloom_set_intensity(float intensity)
  462. {
  463. _bloom_desc.intensity = intensity;
  464. }
  465. void RenderWorld::bloom_set_threshold(float threshold)
  466. {
  467. _bloom_desc.threshold = threshold;
  468. }
  469. u32 RenderWorld::tonemap_create(UnitId unit, const TonemapDesc &desc)
  470. {
  471. _tonemap_desc = desc;
  472. _tonemap_unit = unit;
  473. return 0;
  474. }
  475. void RenderWorld::tonemap_destroy(u32 tonemap)
  476. {
  477. CE_UNUSED(tonemap);
  478. _tonemap_desc = {};
  479. _tonemap_unit = UNIT_INVALID;
  480. }
  481. TonemapInstance RenderWorld::tonemap_instance(UnitId unit)
  482. {
  483. if (_tonemap_unit == unit)
  484. return { 0 };
  485. return { UINT32_MAX };
  486. }
  487. void RenderWorld::tonemap_set_type(TonemapType::Enum type)
  488. {
  489. _tonemap_desc.type = (f32)type;
  490. }
  491. void RenderWorld::update_transforms(const UnitId *begin, const UnitId *end, const Matrix4x4 *world)
  492. {
  493. MeshManager::MeshInstanceData &mid = _mesh_manager._data;
  494. SpriteManager::SpriteInstanceData &sid = _sprite_manager._data;
  495. LightManager::LightInstanceData &lid = _light_manager._data;
  496. for (; begin != end; ++begin, ++world) {
  497. if (_mesh_manager.has(*begin)) {
  498. MeshInstance mesh = _mesh_manager.mesh(*begin);
  499. mid.world[mesh.i] = *world;
  500. }
  501. if (_sprite_manager.has(*begin)) {
  502. SpriteInstance sprite = _sprite_manager.sprite(*begin);
  503. sid.world[sprite.i] = *world;
  504. }
  505. if (_light_manager.has(*begin)) {
  506. LightInstance light = _light_manager.light(*begin);
  507. Vector3 pos = translation(*world);
  508. Vector3 dir = -z(*world);
  509. normalize(dir);
  510. lid.shader[light.i].position = pos;
  511. lid.shader[light.i].direction = dir;
  512. }
  513. }
  514. }
  515. static u32 best_square_size(u32 width, u32 height, u32 num_tiles)
  516. {
  517. CE_ENSURE(num_tiles > 0);
  518. u32 low = 1;
  519. u32 high = (width < height ? width : height);
  520. u32 best = 0;
  521. while (low <= high) {
  522. u32 mid = low + ((high - low) >> 1);
  523. u64 num = (u64)(width / mid) * (u64)(height / mid);
  524. if (num >= num_tiles) {
  525. best = mid;
  526. low = mid + 1;
  527. } else {
  528. high = mid - 1;
  529. }
  530. }
  531. return best;
  532. }
  533. void RenderWorld::render(const Matrix4x4 &view, const Matrix4x4 &proj, UnitId skydome_unit)
  534. {
  535. LightManager &lm = _light_manager;
  536. LightManager::LightInstanceData &lid = lm._data;
  537. const bgfx::Caps *caps = bgfx::getCaps();
  538. Matrix4x4 inv_view = view;
  539. invert(inv_view);
  540. const Vector3 camera_pos = translation(inv_view);
  541. const float sy = caps->originBottomLeft ? 0.5f : -0.5f;
  542. const float sz = caps->homogeneousDepth ? 0.5f : 1.0f;
  543. const float tz = caps->homogeneousDepth ? 0.5f : 0.0f;
  544. Matrix4x4 crop = {
  545. { 0.5f, 0.0f, 0.0f, 0.0f },
  546. { 0.0f, sy, 0.0f, 0.0f },
  547. { 0.0f, 0.0f, sz, 0.0f },
  548. { 0.5f, 0.5f, tz, 1.0f }
  549. };
  550. Matrix4x4 cascaded_lights[MAX_NUM_CASCADES];
  551. array::clear(lm._directional_lights);
  552. array::clear(lm._local_lights);
  553. array::clear(lm._local_lights_spot);
  554. array::clear(lm._local_lights_omni);
  555. array::clear(lm._lights_data);
  556. u32 num_lights = 0; // Total lights to render this frame.
  557. // Collect indices to all directional and local lights.
  558. for (u32 i = 0; i < lid.size; ++i) {
  559. if (lid.type[i] == LightType::DIRECTIONAL)
  560. array::push_back(lm._directional_lights, i);
  561. else
  562. array::push_back(lm._local_lights, i);
  563. }
  564. // Sort directional lights by intensity.
  565. std::sort(array::begin(lm._directional_lights)
  566. , array::end(lm._directional_lights)
  567. , [lm](const u32 &in_a, const u32 &in_b) {
  568. return lm._data.shader[in_a].intensity > lm._data.shader[in_b].intensity;
  569. });
  570. // Render directional lights.
  571. for (u32 i = 0; i < array::size(lm._directional_lights) && num_lights < MAX_NUM_LIGHTS; ++i) {
  572. u32 L = lm._directional_lights[i];
  573. // CSMs are only computed for the brightest directional light (index = 0) in the scene.
  574. if (i == 0 && (lid.flag[L] & RenderableFlags::SHADOW_CASTER) != 0
  575. && (_pipeline->_render_settings.flags & RenderSettingsFlags::SUN_SHADOWS) != 0) {
  576. Matrix4x4 light_proj;
  577. Matrix4x4 light_view;
  578. Frustum splits[MAX_NUM_CASCADES];
  579. Frustum frustum;
  580. // Compute light view matrix.
  581. const Vector3 &light_dir = lid.shader[L].direction;
  582. const bx::Vec3 at = { -light_dir.x, -light_dir.y, -light_dir.z };
  583. const bx::Vec3 eye = { 0.0, 0.0, 0.0 };
  584. const bx::Vec3 up = { 0.0f, 0.0f, 1.0f };
  585. bx::mtxLookAt(to_float_ptr(light_view), eye, at, up, bx::Handedness::Right);
  586. // Split the view frustum into MAX_NUM_CASCADES frustums.
  587. frustum::from_matrix(frustum, proj, caps->homogeneousDepth, bx::Handedness::Right);
  588. frustum::split(splits, MAX_NUM_CASCADES, frustum, 0.75f);
  589. // Render the scene once per cascade.
  590. for (u32 i = 0; i < MAX_NUM_CASCADES; ++i) {
  591. Frustum split_i_world;
  592. frustum::transform(split_i_world, splits[i], inv_view);
  593. // Compute light projection matrix.
  594. // Get frustum corners in view space.
  595. Vector3 vertices[8];
  596. frustum::vertices(vertices, splits[i]);
  597. for (u32 j = 0; j < 8; ++j) {
  598. // Transform frustum corners to light space.
  599. vertices[j] = vertices[j] * inv_view; // To world space.
  600. vertices[j] = vertices[j] * light_view; // To light space.
  601. }
  602. // Compute frustum bounding box in light space.
  603. AABB box;
  604. aabb::from_points(box, countof(vertices), vertices);
  605. // debug_draw_box(box, get_inverted(light_view), _lines, COLOR4_YELLOW); // Debug draw in world space.
  606. bx::mtxOrtho(to_float_ptr(light_proj)
  607. , box.min.x
  608. , box.max.x
  609. , box.min.y
  610. , box.max.y
  611. , -1000.0f
  612. , 1000.0f
  613. , 0.0f
  614. , caps->homogeneousDepth
  615. , bx::Handedness::Right
  616. );
  617. cascaded_lights[i] = light_view * light_proj * crop;
  618. // Render scene into atlas.
  619. //
  620. // Screen-space Texture-space
  621. //
  622. // (0;0) (w;0) (0;1)
  623. // +------> |
  624. // | |
  625. // | |
  626. // | +------>
  627. // (0;h) (0;0) (1;0)
  628. //
  629. const f32 tile_size_x = 0.5f * _pipeline->_render_settings.sun_shadow_map_size.x;
  630. const f32 tile_size_y = 0.5f * _pipeline->_render_settings.sun_shadow_map_size.y;
  631. Vector4 rects[] =
  632. {
  633. { 0, tile_size_y, tile_size_x, tile_size_y },
  634. { tile_size_x, tile_size_y, tile_size_x, tile_size_y },
  635. { 0, 0, tile_size_x, tile_size_y },
  636. { tile_size_x, 0, tile_size_x, tile_size_y },
  637. };
  638. CE_STATIC_ASSERT(countof(rects) == MAX_NUM_CASCADES);
  639. lid.shader[L].atlas_u = 0.0f;
  640. #if CROWN_PLATFORM_WINDOWS
  641. lid.shader[L].atlas_v = rects[0].y / _pipeline->_render_settings.sun_shadow_map_size.y;
  642. #else
  643. lid.shader[L].atlas_v = 1.0f - ((rects[0].y + rects[0].w) / _pipeline->_render_settings.sun_shadow_map_size.y);
  644. #endif
  645. lid.shader[L].map_size = 0.5f;
  646. bgfx::setViewRect(View::CASCADE_0 + i, rects[i].x, rects[i].y, rects[i].z, rects[i].w);
  647. bgfx::setViewFrameBuffer(View::CASCADE_0 + i, _pipeline->_sun_shadow_map_frame_buffer);
  648. bgfx::setViewTransform(View::CASCADE_0 + i, to_float_ptr(light_view), to_float_ptr(light_proj));
  649. _mesh_manager.draw_shadow_casters(View::CASCADE_0 + i, *_scene_graph);
  650. }
  651. }
  652. array::push_back(lm._lights_data, lid.shader[L]);
  653. ++num_lights;
  654. }
  655. // Render local lights.
  656. if (_pipeline->_render_settings.flags & RenderSettingsFlags::LOCAL_LIGHTS) {
  657. // Sort culled lights by distance to camera.
  658. // TODO: no culling is performed yet, "culled lights" here means *all* local lights.
  659. std::sort(array::begin(lm._local_lights)
  660. , array::end(lm._local_lights)
  661. , [lm, camera_pos](const u32 &in_a, const u32 &in_b) {
  662. const f32 dist_a = distance_squared(camera_pos, lm._data.shader[in_a].position);
  663. const f32 dist_b = distance_squared(camera_pos, lm._data.shader[in_b].position);
  664. return dist_a < dist_b;
  665. });
  666. // FIXME: this is a pretty dumb allocation scheme but it's fine for now.
  667. const u32 tile_size = best_square_size(_pipeline->_render_settings.local_lights_shadow_map_size.x
  668. , _pipeline->_render_settings.local_lights_shadow_map_size.y
  669. , LOCAL_LIGHTS_MAX_SHADOW_CASTERS
  670. );
  671. const u32 tile_cols = _pipeline->_render_settings.local_lights_shadow_map_size.x / tile_size;
  672. u32 num_tiles = 0;
  673. u32 cur_tile;
  674. // Render shadow map for spot lights.
  675. for (u32 i = 0; i < array::size(lm._local_lights) && num_lights < MAX_NUM_LIGHTS && num_tiles < LOCAL_LIGHTS_MAX_SHADOW_CASTERS; ++i) {
  676. LightManager::ShaderData &shader = lid.shader[lm._local_lights[i]];
  677. if (lid.type[lm._local_lights[i]] == LightType::SPOT) {
  678. if ((lid.flag[lm._local_lights[i]] & RenderableFlags::SHADOW_CASTER) != 0 && (_pipeline->_render_settings.flags & RenderSettingsFlags::LOCAL_LIGHTS_SHADOWS) != 0) {
  679. cur_tile = num_tiles++;
  680. // Compute light view-proj matrix.
  681. Matrix4x4 light_view;
  682. Matrix4x4 light_proj;
  683. const Vector3 &light_dir = shader.direction;
  684. const Vector3 &light_pos = shader.position;
  685. const bx::Vec3 at = { light_pos.x - light_dir.x, light_pos.y - light_dir.y, light_pos.z - light_dir.z };
  686. const bx::Vec3 eye = { -light_pos.x, -light_pos.y, -light_pos.z };
  687. const bx::Vec3 up = { 0.0f, 0.0f, 1.0f };
  688. bx::mtxLookAt(to_float_ptr(light_view), eye, at, up, bx::Handedness::Right);
  689. bx::mtxProj(to_float_ptr(light_proj)
  690. , fdeg(shader.spot_angle) * 2.0f
  691. , 1.0f // Square depth texture.
  692. , 0.1
  693. , shader.range
  694. , caps->homogeneousDepth
  695. , bx::Handedness::Right
  696. );
  697. shader.mvp = light_view * light_proj * crop;
  698. Vector4 rect = {
  699. f32(tile_size * (cur_tile % tile_cols)),
  700. f32(tile_size * (cur_tile / tile_cols)),
  701. f32(tile_size),
  702. f32(tile_size)
  703. };
  704. shader.atlas_u = rect.x / _pipeline->_render_settings.local_lights_shadow_map_size.x;
  705. shader.atlas_v = 1.0f - ((rect.y + rect.z) / _pipeline->_render_settings.local_lights_shadow_map_size.x);
  706. shader.map_size = rect.w / _pipeline->_render_settings.local_lights_shadow_map_size.x;
  707. bgfx::setViewFrameBuffer(View::SM_LOCAL_0 + i, _pipeline->_local_lights_shadow_map_frame_buffer);
  708. bgfx::setViewRect(View::SM_LOCAL_0 + i, rect.x, rect.y, rect.z, rect.w);
  709. bgfx::setViewTransform(View::SM_LOCAL_0 + i, to_float_ptr(light_view), to_float_ptr(light_proj));
  710. _mesh_manager.draw_shadow_casters(View::SM_LOCAL_0 + i, *_scene_graph);
  711. }
  712. array::push_back(lm._local_lights_spot, lm._local_lights[i]);
  713. } else if (lid.type[lm._local_lights[i]] == LightType::OMNI) {
  714. array::push_back(lm._local_lights_omni, lm._local_lights[i]);
  715. } else {
  716. CE_FATAL("Unknown local light type");
  717. }
  718. ++num_lights;
  719. }
  720. for (u32 i = 0; i < array::size(lm._local_lights_omni); ++i)
  721. array::push_back(lm._lights_data, lid.shader[lm._local_lights_omni[i]]);
  722. for (u32 i = 0; i < array::size(lm._local_lights_spot); ++i)
  723. array::push_back(lm._lights_data, lid.shader[lm._local_lights_spot[i]]);
  724. }
  725. // Send lights data to GPU.
  726. Vector4 h;
  727. h.x = array::size(lm._directional_lights);
  728. h.y = array::size(lm._local_lights_omni);
  729. h.z = array::size(lm._local_lights_spot);
  730. h.w = 0.0f;
  731. bgfx::setUniform(_pipeline->_lights_num, &h);
  732. CE_ENSURE(array::size(lm._lights_data) <= MAX_NUM_LIGHTS);
  733. bgfx::setUniform(_pipeline->_lights_data, (char *)array::begin(lm._lights_data), array::size(lm._lights_data)*sizeof(LightManager::ShaderData)/sizeof(Vector4));
  734. bgfx::touch(View::LIGHTS);
  735. // Skydome.
  736. if (skydome_unit.is_valid()) {
  737. // Copy camera pos to skydome.
  738. TransformInstance skydome_tr = _scene_graph->instance(skydome_unit);
  739. _scene_graph->set_local_position(skydome_tr, camera_pos);
  740. // Override skydome texture from global lighting.
  741. if (_global_lighting_unit.is_valid()) {
  742. MeshInstance skydome_mesh = mesh_instance(skydome_unit);
  743. Material *skydome_material = mesh_material(skydome_mesh);
  744. skydome_material->set_texture(STRING_ID_32("u_skydome_map", UINT32_C(0x90e2fdaa)), _global_lighting_desc.skydome_map);
  745. skydome_material->set_float(STRING_ID_32("u_skydome_intensity", UINT32_C(0x539e93b8)), _global_lighting_desc.skydome_intensity);
  746. }
  747. }
  748. _pipeline->_bloom = _bloom_desc;
  749. _pipeline->_tonemap = _tonemap_desc;
  750. // Render objects.
  751. _mesh_manager.draw_visibles(View::MESH, *_scene_graph, &cascaded_lights[0]);
  752. _sprite_manager.draw_visibles(View::SPRITE_0);
  753. // Render outlines.
  754. _mesh_manager.draw_selected(View::SELECTION, *_scene_graph);
  755. _sprite_manager.draw_selected(View::SELECTION);
  756. }
  757. void RenderWorld::debug_draw(DebugLine &dl)
  758. {
  759. if (!_debug_drawing)
  760. return;
  761. const MeshManager::MeshInstanceData &mid = _mesh_manager._data;
  762. for (u32 i = 0; i < mid.size; ++i) {
  763. const OBB &obb = mid.obb[i];
  764. const Matrix4x4 &world = mid.world[i];
  765. dl.add_obb(obb.tm * world, obb.half_extents, COLOR4_RED);
  766. }
  767. _light_manager.debug_draw(0, _light_manager._data.size, dl);
  768. }
  769. void RenderWorld::enable_debug_drawing(bool enable)
  770. {
  771. _debug_drawing = enable;
  772. }
  773. void RenderWorld::unit_destroyed_callback(UnitId unit)
  774. {
  775. {
  776. MeshInstance first = mesh_instance(unit);
  777. if (is_valid(first))
  778. mesh_destroy(first);
  779. }
  780. {
  781. SpriteInstance first = sprite_instance(unit);
  782. if (is_valid(first))
  783. sprite_destroy(first);
  784. }
  785. {
  786. LightInstance first = light_instance(unit);
  787. if (is_valid(first))
  788. light_destroy(first);
  789. }
  790. }
  791. void RenderWorld::reload_materials(const MaterialResource *old_resource, const MaterialResource *new_resource)
  792. {
  793. #if CROWN_CAN_RELOAD
  794. for (u32 i = 0; i < _mesh_manager._data.size; ++i) {
  795. if (_mesh_manager._data.material_resource[i] == old_resource) {
  796. _mesh_manager._data.material[i] = _material_manager->get(new_resource);
  797. _mesh_manager._data.material_resource[i] = new_resource;
  798. }
  799. }
  800. for (u32 i = 0; i < _sprite_manager._data.size; ++i) {
  801. if (_sprite_manager._data.material_resource[i] == old_resource) {
  802. _sprite_manager._data.material[i] = _material_manager->get(new_resource);
  803. _sprite_manager._data.material_resource[i] = new_resource;
  804. }
  805. }
  806. #else
  807. CE_UNUSED_2(old_resource, new_resource);
  808. #endif
  809. }
  810. void RenderWorld::MeshManager::allocate(u32 num)
  811. {
  812. CE_ENSURE(num > _data.size);
  813. const u32 bytes = 0
  814. + num*sizeof(UnitId) + alignof(UnitId)
  815. + num*sizeof(MeshResource *) + alignof(MeshResource *)
  816. + num*sizeof(MeshGeometry *) + alignof(MeshGeometry *)
  817. + num*sizeof(MeshData) + alignof(MeshData)
  818. + num*sizeof(Material *) + alignof(Material *)
  819. + num*sizeof(Matrix4x4) + alignof(Matrix4x4)
  820. + num*sizeof(OBB) + alignof(OBB)
  821. + num*sizeof(AnimationSkeletonInstance *) + alignof(AnimationSkeletonInstance *)
  822. + num*sizeof(u32) + alignof(u32)
  823. #if CROWN_CAN_RELOAD
  824. + num*sizeof(MaterialResource *) + alignof(MaterialResource *)
  825. #endif
  826. + 0
  827. ;
  828. MeshInstanceData new_data;
  829. new_data.size = _data.size;
  830. new_data.capacity = num;
  831. new_data.buffer = _allocator->allocate(bytes);
  832. new_data.first_hidden = _data.first_hidden;
  833. new_data.unit = (UnitId * )memory::align_top(new_data.buffer, alignof(UnitId));
  834. new_data.resource = (const MeshResource **)memory::align_top(new_data.unit + num, alignof(MeshResource *));
  835. new_data.geometry = (const MeshGeometry **)memory::align_top(new_data.resource + num, alignof(MeshGeometry *));
  836. new_data.mesh = (MeshData * )memory::align_top(new_data.geometry + num, alignof(MeshData));
  837. new_data.material = (Material ** )memory::align_top(new_data.mesh + num, alignof(Material *));
  838. new_data.world = (Matrix4x4 * )memory::align_top(new_data.material + num, alignof(Matrix4x4));
  839. new_data.obb = (OBB * )memory::align_top(new_data.world + num, alignof(OBB));
  840. new_data.skeleton = (const AnimationSkeletonInstance **)memory::align_top(new_data.obb + num, alignof(AnimationSkeletonInstance *));
  841. new_data.flags = (u32 * )memory::align_top(new_data.skeleton + num, alignof(u32));
  842. #if CROWN_CAN_RELOAD
  843. new_data.material_resource = (const MaterialResource **)memory::align_top(new_data.flags + num, alignof(MaterialResource *));
  844. #endif
  845. memcpy(new_data.unit, _data.unit, _data.size * sizeof(UnitId));
  846. memcpy(new_data.resource, _data.resource, _data.size * sizeof(MeshResource *));
  847. memcpy(new_data.geometry, _data.geometry, _data.size * sizeof(MeshGeometry *));
  848. memcpy(new_data.mesh, _data.mesh, _data.size * sizeof(MeshData));
  849. memcpy(new_data.material, _data.material, _data.size * sizeof(Material *));
  850. memcpy(new_data.world, _data.world, _data.size * sizeof(Matrix4x4));
  851. memcpy(new_data.obb, _data.obb, _data.size * sizeof(OBB));
  852. memcpy(new_data.skeleton, _data.skeleton, _data.size * sizeof(AnimationSkeletonInstance *));
  853. memcpy(new_data.flags, _data.flags, _data.size * sizeof(u32));
  854. #if CROWN_CAN_RELOAD
  855. memcpy(new_data.material_resource, _data.material_resource, _data.size * sizeof(MaterialResource *));
  856. #endif
  857. _allocator->deallocate(_data.buffer);
  858. _data = new_data;
  859. }
  860. void RenderWorld::MeshManager::grow()
  861. {
  862. allocate(_data.capacity * 2 + 1);
  863. }
  864. MeshInstance RenderWorld::MeshManager::create(UnitId unit, const MeshResource *mr, const MeshRendererDesc &mrd, const Matrix4x4 &tr)
  865. {
  866. CE_ASSERT(!hash_map::has(_map, unit), "Unit already has a mesh component");
  867. if (_data.size == _data.capacity)
  868. grow();
  869. const u32 last = _data.size;
  870. const MeshGeometry *mg = mr->geometry(mrd.geometry_name);
  871. const MaterialResource *mat_res = (MaterialResource *)_render_world->_resource_manager->get(RESOURCE_TYPE_MATERIAL, mrd.material_resource);
  872. _data.unit[last] = unit;
  873. _data.resource[last] = mr;
  874. _data.geometry[last] = mg;
  875. _data.mesh[last].vbh = mg->vertex_buffer;
  876. _data.mesh[last].ibh = mg->index_buffer;
  877. _data.material[last] = _render_world->_material_manager->get(mat_res);
  878. _data.world[last] = tr;
  879. _data.obb[last] = mg->obb;
  880. _data.skeleton[last] = NULL;
  881. _data.flags[last] = mrd.flags;
  882. #if CROWN_CAN_RELOAD
  883. _data.material_resource[last] = mat_res;
  884. #endif
  885. hash_map::set(_map, unit, last);
  886. ++_data.size;
  887. if (mrd.flags & RenderableFlags::VISIBLE) {
  888. if (last >= _data.first_hidden) {
  889. // _data now contains a visible item in its hidden partition.
  890. swap(last, _data.first_hidden);
  891. ++_data.first_hidden;
  892. return make_instance(_data.first_hidden - 1);
  893. }
  894. ++_data.first_hidden;
  895. }
  896. CE_ENSURE(last >= _data.first_hidden);
  897. return make_instance(last);
  898. }
  899. void RenderWorld::MeshManager::destroy(MeshInstance inst)
  900. {
  901. CE_ASSERT(inst.i < _data.size, "Index out of bounds");
  902. const u32 last = _data.size - 1;
  903. const UnitId u = _data.unit[inst.i];
  904. const UnitId last_u = _data.unit[last];
  905. _data.unit[inst.i] = _data.unit[last];
  906. _data.resource[inst.i] = _data.resource[last];
  907. _data.geometry[inst.i] = _data.geometry[last];
  908. _data.mesh[inst.i].vbh = _data.mesh[last].vbh;
  909. _data.mesh[inst.i].ibh = _data.mesh[last].ibh;
  910. _data.material[inst.i] = _data.material[last];
  911. _data.world[inst.i] = _data.world[last];
  912. _data.obb[inst.i] = _data.obb[last];
  913. _data.skeleton[inst.i] = _data.skeleton[last];
  914. _data.flags[inst.i] = _data.flags[last];
  915. #if CROWN_CAN_RELOAD
  916. _data.material_resource[inst.i] = _data.material_resource[last];
  917. #endif
  918. hash_map::set(_map, last_u, inst.i);
  919. hash_map::remove(_map, u);
  920. --_data.size;
  921. // If item was hidden.
  922. if (inst.i >= _data.first_hidden)
  923. return;
  924. // If item was visible *and* last item was hidden.
  925. if (last >= _data.first_hidden)
  926. swap(inst.i, _data.first_hidden - 1);
  927. --_data.first_hidden;
  928. }
  929. void RenderWorld::MeshManager::swap(u32 inst_a, u32 inst_b)
  930. {
  931. if (inst_a == inst_b)
  932. return;
  933. const UnitId unit_a = _data.unit[inst_a];
  934. const UnitId unit_b = _data.unit[inst_b];
  935. exchange(_data.unit[inst_a], _data.unit[inst_b]);
  936. exchange(_data.resource[inst_a], _data.resource[inst_b]);
  937. exchange(_data.geometry[inst_a], _data.geometry[inst_b]);
  938. exchange(_data.mesh[inst_a], _data.mesh[inst_b]);
  939. exchange(_data.material[inst_a], _data.material[inst_b]);
  940. exchange(_data.world[inst_a], _data.world[inst_b]);
  941. exchange(_data.obb[inst_a], _data.obb[inst_b]);
  942. exchange(_data.skeleton[inst_a], _data.skeleton[inst_b]);
  943. exchange(_data.flags[inst_a], _data.flags[inst_b]);
  944. #if CROWN_CAN_RELOAD
  945. exchange(_data.material_resource[inst_a], _data.material_resource[inst_b]);
  946. #endif
  947. hash_map::set(_map, unit_a, inst_b);
  948. hash_map::set(_map, unit_b, inst_a);
  949. }
  950. bool RenderWorld::MeshManager::has(UnitId unit)
  951. {
  952. return is_valid(mesh(unit));
  953. }
  954. void RenderWorld::MeshManager::set_geometry(MeshInstance mesh, const MeshResource *mr, StringId32 geometry)
  955. {
  956. const MeshGeometry *mg = mr->geometry(geometry);
  957. CE_ENSURE(mg != NULL);
  958. _data.resource[mesh.i] = mr;
  959. _data.geometry[mesh.i] = mg;
  960. _data.mesh[mesh.i].vbh = mg->vertex_buffer;
  961. _data.mesh[mesh.i].ibh = mg->index_buffer;
  962. _data.obb[mesh.i] = mg->obb;
  963. }
  964. void RenderWorld::MeshManager::set_visible(MeshInstance inst, bool visible)
  965. {
  966. if (visible) {
  967. if (inst.i < _data.first_hidden)
  968. return; // Already visible.
  969. swap(inst.i, _data.first_hidden);
  970. ++_data.first_hidden;
  971. } else {
  972. if (inst.i >= _data.first_hidden)
  973. return; // Already hidden.
  974. swap(inst.i, _data.first_hidden - 1);
  975. --_data.first_hidden;
  976. }
  977. }
  978. MeshInstance RenderWorld::MeshManager::mesh(UnitId unit)
  979. {
  980. return make_instance(hash_map::get(_map, unit, UINT32_MAX));
  981. }
  982. void RenderWorld::MeshManager::destroy()
  983. {
  984. _allocator->deallocate(_data.buffer);
  985. }
  986. void RenderWorld::MeshManager::set_instance_data(u32 ii, SceneGraph &scene_graph)
  987. {
  988. if (_data.skeleton[ii] != NULL) {
  989. AnimationSkeletonInstance *skeleton = (AnimationSkeletonInstance *)_data.skeleton[ii];
  990. for (u32 b = 0; b < skeleton->num_bones; ++b) {
  991. TransformInstance bone_ti = scene_graph.instance(skeleton->bone_lookup[b]);
  992. skeleton->bones[b] = skeleton->offsets[b] * scene_graph.world_pose(bone_ti);
  993. }
  994. TransformInstance ti = scene_graph.instance(_data.unit[ii]);
  995. Matrix4x4 world_pose = scene_graph.world_pose(ti);
  996. skeleton->bones[0] = world_pose;
  997. bgfx::setTransform(skeleton->bones, skeleton->num_bones);
  998. } else {
  999. TransformInstance ti = scene_graph.instance(_data.unit[ii]);
  1000. Matrix4x4 world_pose = scene_graph.world_pose(ti);
  1001. bgfx::setTransform(to_float_ptr(world_pose));
  1002. }
  1003. bgfx::setVertexBuffer(0, _data.mesh[ii].vbh);
  1004. bgfx::setIndexBuffer(_data.mesh[ii].ibh);
  1005. }
  1006. void RenderWorld::MeshManager::draw_shadow_casters(u8 view_id, SceneGraph &scene_graph)
  1007. {
  1008. for (u32 ii = 0; ii < _data.first_hidden; ++ii) {
  1009. if ((_data.flags[ii] & RenderableFlags::SHADOW_CASTER) == 0) // FIXME: put in a separate list.
  1010. continue;
  1011. set_instance_data(ii, scene_graph);
  1012. ShaderData sd = _data.skeleton[ii] != NULL
  1013. ? _render_world->_pipeline->_shadow_skinning_shader
  1014. : _render_world->_pipeline->_shadow_shader
  1015. ;
  1016. bgfx::setState(sd.state);
  1017. bgfx::submit(view_id, sd.program);
  1018. }
  1019. }
  1020. void RenderWorld::MeshManager::draw_visibles(u8 view_id, SceneGraph &scene_graph, const Matrix4x4 *cascaded_lights)
  1021. {
  1022. const Vector4 texel_sizes =
  1023. {
  1024. 1.0f/_render_world->_pipeline->_render_settings.sun_shadow_map_size.x,
  1025. 1.0f/_render_world->_pipeline->_render_settings.sun_shadow_map_size.y,
  1026. 1.0f/_render_world->_pipeline->_render_settings.local_lights_shadow_map_size.x,
  1027. 1.0f/_render_world->_pipeline->_render_settings.local_lights_shadow_map_size.y
  1028. };
  1029. for (u32 ii = 0; ii < _data.first_hidden; ++ii) {
  1030. bgfx::setTexture(CASCADED_SHADOW_MAP_SLOT, _render_world->_pipeline->_u_cascaded_shadow_map, _render_world->_pipeline->_sun_shadow_map_texture);
  1031. bgfx::setUniform(_render_world->_pipeline->_u_cascaded_lights, cascaded_lights, MAX_NUM_CASCADES);
  1032. bgfx::setUniform(_render_world->_pipeline->_u_shadow_maps_texel_sizes, &texel_sizes);
  1033. bgfx::setUniform(_render_world->_pipeline->_fog_data, (char *)&_render_world->_fog_desc, sizeof(_render_world->_fog_desc) / sizeof(Vector4));
  1034. _render_world->_pipeline->set_local_lights_params_uniform();
  1035. _render_world->_pipeline->set_global_lighting_params(&_render_world->_global_lighting_desc);
  1036. bgfx::setTexture(LOCAL_LIGHTS_SHADOW_MAP_SLOT, _render_world->_pipeline->_u_local_lights_shadow_map, _render_world->_pipeline->_local_lights_shadow_map_texture);
  1037. set_instance_data(ii, scene_graph);
  1038. _data.material[ii]->bind(view_id);
  1039. }
  1040. }
  1041. void RenderWorld::MeshManager::draw_selected(u8 view_id, SceneGraph &scene_graph)
  1042. {
  1043. union
  1044. {
  1045. u32 u;
  1046. f32 f;
  1047. } u2f;
  1048. for (u32 ii = 0; ii < _data.size; ++ii) {
  1049. UnitId unit_id = _data.unit[ii];
  1050. if (!hash_set::has(_render_world->_selection, unit_id)) // FIXME: put selected objects in a separate list.
  1051. continue;
  1052. u2f.u = unit_id._idx;
  1053. Vector4 data = { u2f.f, 0.0f, 0.0f, 0.0f };
  1054. bgfx::setUniform(_render_world->_pipeline->_unit_id, &data);
  1055. set_instance_data(ii, scene_graph);
  1056. bgfx::setState(_render_world->_pipeline->_selection_shader.state);
  1057. bgfx::submit(view_id, _render_world->_pipeline->_selection_shader.program);
  1058. }
  1059. }
  1060. void RenderWorld::SpriteManager::allocate(u32 num)
  1061. {
  1062. CE_ENSURE(num > _data.size);
  1063. const u32 bytes = 0
  1064. + num*sizeof(UnitId) + alignof(UnitId)
  1065. + num*sizeof(SpriteResource **) + alignof(SpriteResource *)
  1066. + num*sizeof(Material **) + alignof(Material *)
  1067. + num*sizeof(u32) + alignof(u32)
  1068. + num*sizeof(Matrix4x4) + alignof(Matrix4x4)
  1069. + num*sizeof(AABB) + alignof(AABB)
  1070. + num*sizeof(u32) + alignof(u32)
  1071. + num*sizeof(u32) + alignof(u32)
  1072. + num*sizeof(u32) + alignof(u32)
  1073. #if CROWN_CAN_RELOAD
  1074. + num*sizeof(MaterialResource **) + alignof(MaterialResource *)
  1075. #endif
  1076. + 0
  1077. ;
  1078. SpriteInstanceData new_data;
  1079. new_data.size = _data.size;
  1080. new_data.capacity = num;
  1081. new_data.buffer = _allocator->allocate(bytes);
  1082. new_data.first_hidden = _data.first_hidden;
  1083. new_data.unit = (UnitId * )memory::align_top(new_data.buffer, alignof(UnitId));
  1084. new_data.resource = (const SpriteResource **)memory::align_top(new_data.unit + num, alignof(SpriteResource *));
  1085. new_data.material = (Material ** )memory::align_top(new_data.resource + num, alignof(Material *));
  1086. new_data.frame = (u32 * )memory::align_top(new_data.material + num, alignof(u32));
  1087. new_data.world = (Matrix4x4 * )memory::align_top(new_data.frame + num, alignof(Matrix4x4));
  1088. new_data.aabb = (AABB * )memory::align_top(new_data.world + num, alignof(AABB));
  1089. new_data.flags = (u32 * )memory::align_top(new_data.aabb + num, alignof(u32));
  1090. new_data.layer = (u32 * )memory::align_top(new_data.flags + num, alignof(u32));
  1091. new_data.depth = (u32 * )memory::align_top(new_data.layer + num, alignof(u32));
  1092. #if CROWN_CAN_RELOAD
  1093. new_data.material_resource = (const MaterialResource **)memory::align_top(new_data.depth + num, alignof(MaterialResource *));
  1094. #endif
  1095. memcpy(new_data.unit, _data.unit, _data.size * sizeof(UnitId));
  1096. memcpy(new_data.resource, _data.resource, _data.size * sizeof(SpriteResource**));
  1097. memcpy(new_data.material, _data.material, _data.size * sizeof(Material **));
  1098. memcpy(new_data.frame, _data.frame, _data.size * sizeof(u32));
  1099. memcpy(new_data.world, _data.world, _data.size * sizeof(Matrix4x4));
  1100. memcpy(new_data.aabb, _data.aabb, _data.size * sizeof(AABB));
  1101. memcpy(new_data.flags, _data.flags, _data.size * sizeof(u32));
  1102. memcpy(new_data.layer, _data.layer, _data.size * sizeof(u32));
  1103. memcpy(new_data.depth, _data.depth, _data.size * sizeof(u32));
  1104. #if CROWN_CAN_RELOAD
  1105. memcpy(new_data.material_resource, _data.material_resource, _data.size * sizeof(MaterialResource *));
  1106. #endif
  1107. _allocator->deallocate(_data.buffer);
  1108. _data = new_data;
  1109. }
  1110. void RenderWorld::SpriteManager::grow()
  1111. {
  1112. allocate(_data.capacity * 2 + 1);
  1113. }
  1114. SpriteInstance RenderWorld::SpriteManager::create(UnitId unit, const SpriteResource *sr, const SpriteRendererDesc &srd, const Matrix4x4 &tr)
  1115. {
  1116. CE_ASSERT(!hash_map::has(_map, unit), "Unit already has a sprite component");
  1117. if (_data.size == _data.capacity)
  1118. grow();
  1119. const u32 last = _data.size;
  1120. const MaterialResource *mat_res = (MaterialResource *)_render_world->_resource_manager->get(RESOURCE_TYPE_MATERIAL, srd.material_resource);
  1121. _data.unit[last] = unit;
  1122. _data.resource[last] = sr;
  1123. _data.material[last] = _render_world->_material_manager->get(mat_res);
  1124. _data.frame[last] = 0;
  1125. _data.world[last] = tr;
  1126. _data.aabb[last] = AABB();
  1127. _data.flags[last] = srd.flags;
  1128. _data.layer[last] = srd.layer;
  1129. _data.depth[last] = srd.depth;
  1130. #if CROWN_CAN_RELOAD
  1131. _data.material_resource[last] = mat_res;
  1132. #endif
  1133. hash_map::set(_map, unit, last);
  1134. ++_data.size;
  1135. if (srd.flags & RenderableFlags::VISIBLE) {
  1136. if (last >= _data.first_hidden) {
  1137. // _data now contains a visible item in its hidden partition.
  1138. swap(last, _data.first_hidden);
  1139. ++_data.first_hidden;
  1140. return make_instance(_data.first_hidden - 1);
  1141. }
  1142. ++_data.first_hidden;
  1143. }
  1144. CE_ENSURE(last >= _data.first_hidden);
  1145. return make_instance(last);
  1146. }
  1147. void RenderWorld::SpriteManager::destroy(SpriteInstance inst)
  1148. {
  1149. CE_ASSERT(inst.i < _data.size, "Index out of bounds");
  1150. const u32 last = _data.size - 1;
  1151. const UnitId u = _data.unit[inst.i];
  1152. const UnitId last_u = _data.unit[last];
  1153. _data.unit[inst.i] = _data.unit[last];
  1154. _data.resource[inst.i] = _data.resource[last];
  1155. _data.material[inst.i] = _data.material[last];
  1156. _data.frame[inst.i] = _data.frame[last];
  1157. _data.world[inst.i] = _data.world[last];
  1158. _data.aabb[inst.i] = _data.aabb[last];
  1159. _data.flags[inst.i] = _data.flags[last];
  1160. _data.layer[inst.i] = _data.layer[last];
  1161. _data.depth[inst.i] = _data.depth[last];
  1162. #if CROWN_CAN_RELOAD
  1163. _data.material_resource[inst.i] = _data.material_resource[last];
  1164. #endif
  1165. hash_map::set(_map, last_u, inst.i);
  1166. hash_map::remove(_map, u);
  1167. --_data.size;
  1168. // If item was hidden.
  1169. if (inst.i >= _data.first_hidden)
  1170. return;
  1171. // If item was visible *and* last item was hidden.
  1172. if (last >= _data.first_hidden)
  1173. swap(inst.i, _data.first_hidden - 1);
  1174. --_data.first_hidden;
  1175. }
  1176. void RenderWorld::SpriteManager::swap(u32 inst_a, u32 inst_b)
  1177. {
  1178. if (inst_a == inst_b)
  1179. return;
  1180. const UnitId unit_a = _data.unit[inst_a];
  1181. const UnitId unit_b = _data.unit[inst_b];
  1182. exchange(_data.unit[inst_a], _data.unit[inst_b]);
  1183. exchange(_data.resource[inst_a], _data.resource[inst_b]);
  1184. exchange(_data.material[inst_a], _data.material[inst_b]);
  1185. exchange(_data.frame[inst_a], _data.frame[inst_b]);
  1186. exchange(_data.world[inst_a], _data.world[inst_b]);
  1187. exchange(_data.aabb[inst_a], _data.aabb[inst_b]);
  1188. exchange(_data.flags[inst_a], _data.flags[inst_b]);
  1189. exchange(_data.layer[inst_a], _data.layer[inst_b]);
  1190. exchange(_data.depth[inst_a], _data.depth[inst_b]);
  1191. #if CROWN_CAN_RELOAD
  1192. exchange(_data.material_resource[inst_a], _data.material_resource[inst_b]);
  1193. #endif
  1194. hash_map::set(_map, unit_a, inst_b);
  1195. hash_map::set(_map, unit_b, inst_a);
  1196. }
  1197. bool RenderWorld::SpriteManager::has(UnitId unit)
  1198. {
  1199. return is_valid(sprite(unit));
  1200. }
  1201. void RenderWorld::SpriteManager::set_visible(SpriteInstance inst, bool visible)
  1202. {
  1203. if (visible) {
  1204. if (inst.i < _data.first_hidden)
  1205. return; // Already visible.
  1206. swap(inst.i, _data.first_hidden);
  1207. ++_data.first_hidden;
  1208. } else {
  1209. if (inst.i >= _data.first_hidden)
  1210. return; // Already hidden.
  1211. swap(inst.i, _data.first_hidden - 1);
  1212. --_data.first_hidden;
  1213. }
  1214. }
  1215. SpriteInstance RenderWorld::SpriteManager::sprite(UnitId unit)
  1216. {
  1217. return make_instance(hash_map::get(_map, unit, UINT32_MAX));
  1218. }
  1219. void RenderWorld::SpriteManager::destroy()
  1220. {
  1221. _allocator->deallocate(_data.buffer);
  1222. }
  1223. void RenderWorld::SpriteManager::set_instance_data(f32 **vdata_, u16 **idata_, bgfx::TransientVertexBuffer &tvb, bgfx::TransientIndexBuffer &tib, u32 ii)
  1224. {
  1225. f32 *vdata = *vdata_;
  1226. u16 *idata = *idata_;
  1227. const f32 *frame = sprite_resource::frame_data(_data.resource[ii]
  1228. , _data.frame[ii] % _data.resource[ii]->num_frames
  1229. );
  1230. f32 u0 = frame[ 3]; // u
  1231. f32 v0 = frame[ 4]; // v
  1232. f32 u1 = frame[ 8]; // u
  1233. f32 v1 = frame[ 9]; // v
  1234. f32 u2 = frame[13]; // u
  1235. f32 v2 = frame[14]; // v
  1236. f32 u3 = frame[18]; // u
  1237. f32 v3 = frame[19]; // v
  1238. if ((_data.flags[ii] & SpriteFlags::FLIP_X) != 0) {
  1239. f32 u;
  1240. u = u0; u0 = u1; u1 = u;
  1241. u = u2; u2 = u3; u3 = u;
  1242. }
  1243. if ((_data.flags[ii] & SpriteFlags::FLIP_Y) != 0) {
  1244. f32 v;
  1245. v = v0; v0 = v2; v2 = v;
  1246. v = v1; v1 = v3; v3 = v;
  1247. }
  1248. vdata[ 0] = frame[ 0]; // x
  1249. vdata[ 1] = frame[ 1]; // y
  1250. vdata[ 2] = frame[ 2]; // z
  1251. vdata[ 3] = u0;
  1252. vdata[ 4] = v0;
  1253. vdata[ 5] = frame[ 5]; // x
  1254. vdata[ 6] = frame[ 6]; // y
  1255. vdata[ 7] = frame[ 7]; // z
  1256. vdata[ 8] = u1;
  1257. vdata[ 9] = v1;
  1258. vdata[10] = frame[10]; // x
  1259. vdata[11] = frame[11]; // y
  1260. vdata[12] = frame[12]; // z
  1261. vdata[13] = u2;
  1262. vdata[14] = v2;
  1263. vdata[15] = frame[15]; // x
  1264. vdata[16] = frame[16]; // y
  1265. vdata[17] = frame[17]; // z
  1266. vdata[18] = u3;
  1267. vdata[19] = v3;
  1268. *vdata_ += 20;
  1269. idata[0] = ii*4 + 0;
  1270. idata[1] = ii*4 + 1;
  1271. idata[2] = ii*4 + 2;
  1272. idata[3] = ii*4 + 0;
  1273. idata[4] = ii*4 + 2;
  1274. idata[5] = ii*4 + 3;
  1275. *idata_ += 6;
  1276. bgfx::setTransform(to_float_ptr(_data.world[ii]));
  1277. bgfx::setVertexBuffer(0, &tvb);
  1278. bgfx::setIndexBuffer(&tib, ii*6, 6);
  1279. }
  1280. void RenderWorld::SpriteManager::draw_visibles(u8 view_id)
  1281. {
  1282. bgfx::VertexLayout layout;
  1283. bgfx::TransientVertexBuffer tvb;
  1284. bgfx::TransientIndexBuffer tib;
  1285. f32 *vdata;
  1286. u16 *idata;
  1287. // Allocate vertex and index buffers.
  1288. if (_data.first_hidden) {
  1289. layout.begin();
  1290. layout.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
  1291. layout.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float, false);
  1292. layout.end();
  1293. bgfx::allocTransientVertexBuffer(&tvb, 4*_data.first_hidden, layout);
  1294. bgfx::allocTransientIndexBuffer(&tib, 6*_data.first_hidden);
  1295. vdata = (f32 *)tvb.data;
  1296. idata = (u16 *)tib.data;
  1297. }
  1298. // Render all sprites.
  1299. for (u32 ii = 0; ii < _data.first_hidden; ++ii) {
  1300. set_instance_data(&vdata, &idata, tvb, tib, ii);
  1301. _data.material[ii]->bind(_data.layer[ii] + view_id, _data.depth[ii]);
  1302. }
  1303. }
  1304. void RenderWorld::SpriteManager::draw_selected(u8 view_id)
  1305. {
  1306. union
  1307. {
  1308. u32 u;
  1309. f32 f;
  1310. } u2f;
  1311. bgfx::VertexLayout layout;
  1312. bgfx::TransientVertexBuffer tvb;
  1313. bgfx::TransientIndexBuffer tib;
  1314. f32 *vdata;
  1315. u16 *idata;
  1316. // Allocate vertex and index buffers.
  1317. if (_data.size) {
  1318. layout.begin();
  1319. layout.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
  1320. layout.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float, false);
  1321. layout.end();
  1322. bgfx::allocTransientVertexBuffer(&tvb, 4*_data.size, layout);
  1323. bgfx::allocTransientIndexBuffer(&tib, 6*_data.size);
  1324. vdata = (f32 *)tvb.data;
  1325. idata = (u16 *)tib.data;
  1326. }
  1327. // Render all sprites.
  1328. for (u32 ii = 0; ii < _data.size; ++ii) {
  1329. set_instance_data(&vdata, &idata, tvb, tib, ii);
  1330. UnitId unit_id = _data.unit[ii];
  1331. if (!hash_set::has(_render_world->_selection, unit_id)) { // FIXME: put selected objects in a separate list.
  1332. bgfx::discard();
  1333. continue;
  1334. }
  1335. u2f.u = unit_id._idx;
  1336. Vector4 data = { u2f.f, 0.0f, 0.0f, 0.0f };
  1337. bgfx::setUniform(_render_world->_pipeline->_unit_id, &data);
  1338. bgfx::setState(_render_world->_pipeline->_selection_shader.state);
  1339. bgfx::submit(view_id, _render_world->_pipeline->_selection_shader.program);
  1340. }
  1341. }
  1342. void RenderWorld::LightManager::allocate(u32 num)
  1343. {
  1344. CE_ENSURE(num > _data.size);
  1345. const u32 bytes = 0
  1346. + num*sizeof(UnitId) + alignof(UnitId)
  1347. + num*sizeof(u32) + alignof(u32)
  1348. + num*sizeof(u32) + alignof(u32)
  1349. + num*sizeof(ShaderData) + alignof(ShaderData)
  1350. + num*sizeof(f32) + alignof(f32)
  1351. + num*sizeof(u32) + alignof(u32)
  1352. ;
  1353. LightInstanceData new_data;
  1354. new_data.size = _data.size;
  1355. new_data.capacity = num;
  1356. new_data.buffer = _allocator->allocate(bytes);
  1357. new_data.unit = (UnitId *)memory::align_top(new_data.buffer, alignof(UnitId));
  1358. new_data.flag = (u32 *)memory::align_top(new_data.unit + num, alignof(u32));
  1359. new_data.type = (u32 *)memory::align_top(new_data.flag + num, alignof(u32));
  1360. new_data.shader = (ShaderData *)memory::align_top(new_data.type + num, alignof(ShaderData));
  1361. memcpy(new_data.unit, _data.unit, _data.size * sizeof(*new_data.unit));
  1362. memcpy(new_data.flag, _data.flag, _data.size * sizeof(*new_data.flag));
  1363. memcpy(new_data.type, _data.type, _data.size * sizeof(*new_data.type));
  1364. memcpy(new_data.shader, _data.shader, _data.size * sizeof(ShaderData));
  1365. _allocator->deallocate(_data.buffer);
  1366. _data = new_data;
  1367. }
  1368. void RenderWorld::LightManager::grow()
  1369. {
  1370. allocate(_data.capacity * 2 + 1);
  1371. }
  1372. LightInstance RenderWorld::LightManager::create(UnitId unit, const LightDesc &ld, const Matrix4x4 &tr)
  1373. {
  1374. CE_ASSERT(!hash_map::has(_map, unit), "Unit already has a light component");
  1375. if (_data.size == _data.capacity)
  1376. grow();
  1377. const u32 last = _data.size;
  1378. Vector3 dir = -z(tr);
  1379. normalize(dir);
  1380. _data.unit[last] = unit;
  1381. _data.flag[last] = ld.flags;
  1382. _data.type[last] = ld.type;
  1383. _data.shader[last].color = ld.color;
  1384. _data.shader[last].intensity = ld.intensity;
  1385. _data.shader[last].position = translation(tr);
  1386. _data.shader[last].range = ld.range;
  1387. _data.shader[last].direction = dir;
  1388. _data.shader[last].spot_angle = ld.spot_angle;
  1389. _data.shader[last].shadow_bias = ld.shadow_bias;
  1390. _data.shader[last].atlas_u = 0.0f;
  1391. _data.shader[last].atlas_v = 0.0f;
  1392. _data.shader[last].map_size = 0.0f;
  1393. _data.shader[last].mvp = MATRIX4X4_IDENTITY;
  1394. ++_data.size;
  1395. hash_map::set(_map, unit, last);
  1396. return make_instance(last);
  1397. }
  1398. void RenderWorld::LightManager::destroy(LightInstance light)
  1399. {
  1400. CE_ASSERT(light.i < _data.size, "Index out of bounds");
  1401. const u32 last = _data.size - 1;
  1402. const UnitId u = _data.unit[light.i];
  1403. const UnitId last_u = _data.unit[last];
  1404. _data.unit[light.i] = _data.unit[last];
  1405. _data.flag[light.i] = _data.flag[last];
  1406. _data.type[light.i] = _data.type[last];
  1407. _data.shader[light.i] = _data.shader[last];
  1408. --_data.size;
  1409. hash_map::set(_map, last_u, light.i);
  1410. hash_map::remove(_map, u);
  1411. }
  1412. bool RenderWorld::LightManager::has(UnitId unit)
  1413. {
  1414. return is_valid(light(unit));
  1415. }
  1416. LightInstance RenderWorld::LightManager::light(UnitId unit)
  1417. {
  1418. return make_instance(hash_map::get(_map, unit, UINT32_MAX));
  1419. }
  1420. void RenderWorld::LightManager::destroy()
  1421. {
  1422. _allocator->deallocate(_data.buffer);
  1423. }
  1424. void RenderWorld::LightManager::debug_draw(u32 start_index, u32 num, DebugLine &dl)
  1425. {
  1426. for (u32 i = start_index; i < start_index + num; ++i) {
  1427. const Vector3 pos = _data.shader[i].position;
  1428. const Vector3 dir = _data.shader[i].direction;
  1429. switch (_data.type[i]) {
  1430. case LightType::DIRECTIONAL: {
  1431. const Vector3 end = pos + dir*3.0f;
  1432. dl.add_line(pos, end, COLOR4_YELLOW);
  1433. dl.add_cone(pos + dir*2.8f, end, 0.1f, COLOR4_YELLOW);
  1434. break;
  1435. }
  1436. case LightType::OMNI:
  1437. dl.add_sphere(pos, _data.shader[i].range, COLOR4_YELLOW);
  1438. break;
  1439. case LightType::SPOT: {
  1440. const f32 angle = _data.shader[i].spot_angle;
  1441. const f32 range = _data.shader[i].range;
  1442. const f32 radius = ftan(angle)*range;
  1443. dl.add_cone(pos + range*dir, pos, radius, COLOR4_YELLOW, 36, 4);
  1444. break;
  1445. }
  1446. default:
  1447. CE_FATAL("Unknown light type");
  1448. break;
  1449. }
  1450. }
  1451. }
  1452. } // namespace crown