| 1201 | } |
| 1202 | |
| 1203 | void RenderWorld::render(f32 dt, const Matrix4x4 &view, const Matrix4x4 &proj, const Matrix4x4 &persp, UnitId skydome_unit, DebugLine &dl) |
| 1204 | { |
| 1205 | LightManager &lm = _light_manager; |
| 1206 | LightManager::LightInstanceData &lid = lm._data; |
| 1207 | |
| 1208 | sync_cullable_sets(); |
| 1209 | |
| 1210 | const bgfx::Caps *caps = bgfx::getCaps(); |
| 1211 | Matrix4x4 inv_view = view; |
| 1212 | invert(inv_view); |
| 1213 | const Vector3 camera_pos = translation(inv_view); |
| 1214 | const Matrix4x4 view_proj = view * proj; |
| 1215 | |
| 1216 | // Skydome. |
| 1217 | if (skydome_unit.is_valid()) { |
| 1218 | MeshId skydome_mesh = mesh_instance(skydome_unit); |
| 1219 | const u32 skydome_mesh_i = _mesh_manager.index(skydome_mesh); |
| 1220 | |
| 1221 | // Copy camera pos to skydome. |
| 1222 | _mesh_manager._data.world[skydome_mesh_i] = from_translation(camera_pos); |
| 1223 | culling_set::update(_cullable_objects |
| 1224 | , CullableType::MESH |
| 1225 | , skydome_mesh_i |
| 1226 | , _mesh_manager._data.sphere[skydome_mesh_i] |
| 1227 | , _mesh_manager._data.world[skydome_mesh_i] |
| 1228 | ); |
| 1229 | |
| 1230 | Material *skydome_material = mesh_material(skydome_mesh); |
| 1231 | skydome_material->set_matrix4x4(STRING_ID_32("u_persp", UINT32_C(0x404ac2c2)), persp); |
| 1232 | |
| 1233 | // Override skydome texture from global lighting. |
| 1234 | if (_global_lighting_unit.is_valid()) { |
| 1235 | skydome_material->set_texture(STRING_ID_32("u_skydome_map", UINT32_C(0x90e2fdaa)), _global_lighting_desc.skydome_map); |
| 1236 | skydome_material->set_float(STRING_ID_32("u_skydome_intensity", UINT32_C(0x539e93b8)), _global_lighting_desc.skydome_intensity); |
| 1237 | } |
| 1238 | } |
| 1239 | |
| 1240 | // Frustum culling of visible objects. |
| 1241 | Frustum view_frustum; |
| 1242 | frustum::from_matrix(view_frustum, view_proj, caps->homogeneousDepth, bx::Handedness::Right); |
| 1243 | culling_set::cull_spheres(_cullable_objects, view_frustum, 0, array::size(_cullable_objects.id)); |
| 1244 | u32 visible_objects = culling_set::remove_culled(_cullable_objects); |
| 1245 | RECORD_FLOAT("world.visible_objects", (f32)visible_objects); |
| 1246 | |
| 1247 | // Count sprites for transient buffer allocation and select LOD groups once |
| 1248 | // before render/selection passes consume selected_mesh. |
| 1249 | u32 num_visible_sprites = 0; |
| 1250 | for (u32 ii = 0; ii < visible_objects; ++ii) { |
| 1251 | const u32 i = _cullable_objects.render[ii]; |
| 1252 | if (_cullable_objects.type[i] == CullableType::SPRITE) |
| 1253 | ++num_visible_sprites; |
| 1254 | else if (_cullable_objects.type[i] == CullableType::LOD_GROUP) |
| 1255 | _lod_group_manager.select_level(_cullable_objects.id[i], view_proj, dt); |
| 1256 | } |
| 1257 | |
| 1258 | const f32 sy = caps->originBottomLeft ? 0.5f : -0.5f; |
| 1259 | const f32 sz = caps->homogeneousDepth ? 0.5f : 1.0f; |
| 1260 | const f32 tz = caps->homogeneousDepth ? 0.5f : 0.0f; |
nothing calls this directly
no test coverage detected