mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-09 13:01:29 -10:00
- Consolidated dynamic descriptor offset logic into `DescriptorWriter::bindSets`, replacing repetitive `vkCmdBindDescriptorSets` patterns across Vulkan modules. - Eliminated redundant descriptor binding operations for Material and PerDraw sets by centralizing logic in `bindSets`. - Simplified descriptors by directly splitting offset changes from descriptor contents, avoiding unnecessary updates. - Updated comments and documentation to align with the new approach while maintaining reference consistency. - Applied optimizations across Vulkan modules (`VulkanPostProcessing`, `VulkanDescriptorManager`, etc.) to reduce per-draw overhead and improve readability.
628 lines
23 KiB
C++
628 lines
23 KiB
C++
#include "freespace.h"
|
|
#include "asteroid/asteroid.h"
|
|
#include "globalincs/vmallocator.h"
|
|
#include "graphics/2d.h"
|
|
#include "graphics/light.h"
|
|
#include "graphics/matrix.h"
|
|
#include "lab/labv2_internal.h"
|
|
#include "lab/renderer/lab_renderer.h"
|
|
#include "lighting/lighting_profiles.h"
|
|
#include "math/bitarray.h"
|
|
#include "model/modelrender.h"
|
|
#include "nebula/neb.h"
|
|
#include "parse/parselo.h"
|
|
#include "particle/particle.h"
|
|
#include "starfield/starfield.h"
|
|
#include "starfield/nebula.h"
|
|
#include "prop/prop.h"
|
|
|
|
#include "missionui/missionscreencommon.h"
|
|
#include "tracing/tracing.h"
|
|
|
|
void LabRenderer::onFrame(float frametime) {
|
|
GR_DEBUG_SCOPE("Lab Frame");
|
|
|
|
gr_reset_clip();
|
|
gr_clear();
|
|
|
|
if (!renderFlags[LabRenderFlag::TimeStopped])
|
|
Missiontime += Frametime;
|
|
|
|
// render our particular thing
|
|
if (getLabManager()->CurrentObject >= 0) {
|
|
int w, h;
|
|
renderModel(frametime);
|
|
|
|
// print out the current pof filename, to help with... something
|
|
if (strlen(getLabManager()->ModelFilename.c_str())) {
|
|
SCP_string lab_text = "POF File: " + getLabManager()->ModelFilename + " Detail Level: " + std::to_string(Lab_object_detail_level);
|
|
gr_get_string_size(&w, &h, lab_text.c_str());
|
|
gr_set_color_fast(&Color_white);
|
|
gr_string(gr_screen.center_offset_x + gr_screen.center_w - w - 20, // add a little padding to the right
|
|
gr_screen.center_offset_y + gr_screen.center_h - h, lab_text.c_str(), GR_RESIZE_NONE);
|
|
}
|
|
}
|
|
|
|
renderHud(frametime);
|
|
|
|
// Normally, we would call gr_flip here, but because wmcgui conflates rendering and input gathering, this is done at the end of
|
|
// the LabManager::onFrame method
|
|
}
|
|
|
|
namespace ltp = lighting_profiles;
|
|
void LabRenderer::resetGraphicsSettings(gfx_options settings) {
|
|
|
|
ltp::lab_set_ambient(settings.ambient_factor);
|
|
ltp::lab_set_emissive(settings.emissive_factor);
|
|
ltp::lab_set_exposure(settings.exposure_level);
|
|
ltp::lab_set_light(settings.light_factor);
|
|
ltp::lab_set_ppc(settings.ppcv);
|
|
ltp::lab_set_tonemapper(settings.tonemapper);
|
|
gr_set_bloom_intensity(settings.bloom_level);
|
|
Gr_aa_mode = settings.aa_mode;
|
|
}
|
|
|
|
void LabRenderer::resetView()
|
|
{
|
|
getLabManager()->CurrentOrientation = vmd_identity_matrix;
|
|
labCamera->resetView();
|
|
}
|
|
|
|
void LabRenderer::renderModel(float frametime) {
|
|
GR_DEBUG_SCOPE("Lab Render Model");
|
|
|
|
auto lab_debris_override_save = Motion_debris_enabled;
|
|
auto lab_envmap_override_save = Envmap_override;
|
|
auto lab_emissive_light_save = Cmdline_emissive;
|
|
|
|
light_reset();
|
|
|
|
if (currentMissionBackground == LAB_MISSION_NONE_STRING) {
|
|
common_setup_room_lights();
|
|
}
|
|
|
|
Cmdline_emissive = renderFlags[LabRenderFlag::ShowEmissiveLighting];
|
|
|
|
object* obj = &Objects[getLabManager()->CurrentObject];
|
|
|
|
// Ships && Objects stay put. Weapons are allowed to move so particle effects look correct
|
|
if (obj->type == OBJ_SHIP || obj->type == OBJ_ASTEROID) {
|
|
obj->pos = getLabManager()->CurrentPosition;
|
|
}
|
|
obj->orient = getLabManager()->CurrentOrientation;
|
|
|
|
Envmap_override = renderFlags[LabRenderFlag::NoEnvMap];
|
|
Glowpoint_override = renderFlags[LabRenderFlag::NoGlowpoints];
|
|
PostProcessing_override = renderFlags[LabRenderFlag::HidePostProcessing];
|
|
|
|
if (obj->type == OBJ_SHIP) {
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Subsystem_movement_locked, !renderFlags[LabRenderFlag::MoveSubsystems]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Draw_as_wireframe, renderFlags[LabRenderFlag::ShowWireframe]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_full_detail, renderFlags[LabRenderFlag::ShowFullDetail]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_light,
|
|
renderFlags[LabRenderFlag::NoLighting] || currentMissionBackground == LAB_MISSION_NONE_STRING);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_diffuse, renderFlags[LabRenderFlag::NoDiffuseMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_glowmap, renderFlags[LabRenderFlag::NoGlowMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_normalmap, renderFlags[LabRenderFlag::NoNormalMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_specmap, renderFlags[LabRenderFlag::NoSpecularMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_reflectmap, renderFlags[LabRenderFlag::NoReflectMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_heightmap, renderFlags[LabRenderFlag::NoHeightMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_miscmap, renderFlags[LabRenderFlag::NoMiscMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_weapons, !renderFlags[LabRenderFlag::ShowWeapons]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::Render_without_ambientmap, renderFlags[LabRenderFlag::NoAOMap]);
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::No_insignias, !renderFlags[LabRenderFlag::ShowInsignia]);
|
|
|
|
Ships[obj->instance].team_name = currentTeamColor;
|
|
|
|
if (renderFlags[LabRenderFlag::ShowDamageLightning]) {
|
|
obj->hull_strength = 1.0f;
|
|
}
|
|
else {
|
|
obj->hull_strength = Ship_info[Ships[obj->instance].ship_info_index].max_hull_strength;
|
|
}
|
|
}
|
|
|
|
if (obj->type == OBJ_PROP) {
|
|
prop* propp = prop_id_lookup(obj->instance);
|
|
propp->flags.set(Prop::Prop_Flags::Draw_as_wireframe, renderFlags[LabRenderFlag::ShowWireframe]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_full_detail, renderFlags[LabRenderFlag::ShowFullDetail]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_light,
|
|
renderFlags[LabRenderFlag::NoLighting] || currentMissionBackground == LAB_MISSION_NONE_STRING);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_diffuse, renderFlags[LabRenderFlag::NoDiffuseMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_glowmap, renderFlags[LabRenderFlag::NoGlowMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_normalmap, renderFlags[LabRenderFlag::NoNormalMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_specmap, renderFlags[LabRenderFlag::NoSpecularMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_reflectmap, renderFlags[LabRenderFlag::NoReflectMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_heightmap, renderFlags[LabRenderFlag::NoHeightMap]);
|
|
propp->flags.set(Prop::Prop_Flags::Render_without_ambientmap, renderFlags[LabRenderFlag::NoAOMap]);
|
|
}
|
|
|
|
if (obj->type == OBJ_WEAPON) {
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Draw_as_wireframe, renderFlags[LabRenderFlag::ShowWireframe]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_full_detail, renderFlags[LabRenderFlag::ShowFullDetail]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_light,
|
|
renderFlags[LabRenderFlag::NoLighting] || currentMissionBackground == LAB_MISSION_NONE_STRING);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_diffuse, renderFlags[LabRenderFlag::NoDiffuseMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_glowmap, renderFlags[LabRenderFlag::NoGlowMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_normalmap, renderFlags[LabRenderFlag::NoNormalMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_specmap, renderFlags[LabRenderFlag::NoSpecularMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_reflectmap, renderFlags[LabRenderFlag::NoReflectMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_heightmap, renderFlags[LabRenderFlag::NoHeightMap]);
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::Render_without_ambientmap, renderFlags[LabRenderFlag::NoAOMap]);
|
|
}
|
|
|
|
if (obj->type == OBJ_RAW_POF) {
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Draw_as_wireframe, renderFlags[LabRenderFlag::ShowWireframe]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_full_detail, renderFlags[LabRenderFlag::ShowFullDetail]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_light,
|
|
renderFlags[LabRenderFlag::NoLighting] || currentMissionBackground == LAB_MISSION_NONE_STRING);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_diffuse, renderFlags[LabRenderFlag::NoDiffuseMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_glowmap, renderFlags[LabRenderFlag::NoGlowMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_normalmap, renderFlags[LabRenderFlag::NoNormalMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_specmap, renderFlags[LabRenderFlag::NoSpecularMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_reflectmap, renderFlags[LabRenderFlag::NoReflectMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_heightmap, renderFlags[LabRenderFlag::NoHeightMap]);
|
|
Pof_objects[obj->instance].flags.set(Object::Raw_Pof_Flags::Render_without_ambientmap, renderFlags[LabRenderFlag::NoAOMap]);
|
|
}
|
|
|
|
if (obj->type == OBJ_ASTEROID) {
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Draw_as_wireframe, renderFlags[LabRenderFlag::ShowWireframe]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_full_detail, renderFlags[LabRenderFlag::ShowFullDetail]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_light,
|
|
renderFlags[LabRenderFlag::NoLighting] || currentMissionBackground == LAB_MISSION_NONE_STRING);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_diffuse, renderFlags[LabRenderFlag::NoDiffuseMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_glowmap, renderFlags[LabRenderFlag::NoGlowMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_normalmap, renderFlags[LabRenderFlag::NoNormalMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_specmap, renderFlags[LabRenderFlag::NoSpecularMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_reflectmap, renderFlags[LabRenderFlag::NoReflectMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_heightmap, renderFlags[LabRenderFlag::NoHeightMap]);
|
|
Asteroids[obj->instance].render_flags.set(Object::Raw_Pof_Flags::Render_without_ambientmap, renderFlags[LabRenderFlag::NoAOMap]);
|
|
}
|
|
|
|
if (renderFlags[LabRenderFlag::ShowWireframe])
|
|
model_render_set_wireframe_color(&Color_white);
|
|
|
|
if (renderFlags[LabRenderFlag::ShowThrusters] || renderFlags[LabRenderFlag::ShowAfterburners]) {
|
|
obj->phys_info.linear_thrust.xyz.z = 1.0f;
|
|
if (obj->type == OBJ_SHIP) {
|
|
Ships[obj->instance].flags.remove(Ship::Ship_Flags::No_thrusters);
|
|
} else if (obj->type == OBJ_WEAPON) {
|
|
Weapons[obj->instance].weapon_flags.remove(Weapon::Weapon_Flags::No_thruster);
|
|
}
|
|
if (renderFlags[LabRenderFlag::ShowAfterburners]) {
|
|
obj->phys_info.flags |= PF_AFTERBURNER_ON;
|
|
// Keep the AB topped off
|
|
Ships[obj->instance].afterburner_fuel = Ship_info[Ships[obj->instance].ship_info_index].afterburner_fuel_capacity;
|
|
}
|
|
else
|
|
obj->phys_info.flags &= ~PF_AFTERBURNER_ON;
|
|
}
|
|
else {
|
|
obj->phys_info.linear_thrust.xyz.z = 0.0f;
|
|
|
|
if (obj->type == OBJ_SHIP) {
|
|
Ships[obj->instance].flags.set(Ship::Ship_Flags::No_thrusters);
|
|
} else if (obj->type == OBJ_WEAPON) {
|
|
Weapons[obj->instance].weapon_flags.set(Weapon::Weapon_Flags::No_thruster);
|
|
}
|
|
}
|
|
|
|
// Prevent weapons from destroying themselves
|
|
if (!getLabManager()->AllowWeaponDestruction) {
|
|
if (obj->type == OBJ_WEAPON) {
|
|
weapon* wep = &Weapons[obj->instance];
|
|
weapon_info* wip = &Weapon_info[wep->weapon_info_index];
|
|
|
|
if (wip != nullptr && !wip->wi_flags[Weapon::Info_Flags::Beam]) {
|
|
wep->lifeleft = wip->lifetime;
|
|
}
|
|
} else if (obj->type == OBJ_BEAM) {
|
|
beam* b = &Beams[obj->instance];
|
|
//Little hack to keep targeting beams going
|
|
if (b->type == BeamType::TARGETING) {
|
|
b->life_left = 0.1f;
|
|
} else {
|
|
b->life_left = b->life_total;
|
|
}
|
|
}
|
|
}
|
|
|
|
obj_move_all(frametime);
|
|
|
|
// Force the camera to follow our current object
|
|
labCamera->updateCamera();
|
|
|
|
if (!renderFlags[LabRenderFlag::NoParticles]) {
|
|
particle::move_all(frametime);
|
|
particle::ParticleManager::get()->doFrame(frametime);
|
|
}
|
|
shockwave_move_all(frametime);
|
|
|
|
if (renderFlags[LabRenderFlag::UseOrthographicProjection]) {
|
|
float dist = labCamera->getCameraDistance();
|
|
if (dist > 0.0f)
|
|
gr_activate_ortho_proj_override(dist);
|
|
}
|
|
|
|
Trail_render_override = true;
|
|
game_render_frame(labCamera->FS_camera);
|
|
Trail_render_override = false;
|
|
|
|
gr_deactivate_ortho_proj_override();
|
|
|
|
Motion_debris_enabled = lab_debris_override_save;
|
|
Envmap_override = lab_envmap_override_save;
|
|
Cmdline_emissive = lab_emissive_light_save;
|
|
|
|
gr_reset_clip();
|
|
gr_set_color_fast(&HUD_color_debug);
|
|
// The legacy -profile_frame_time text dump. gr_flip() drains the profiler, so this only
|
|
// renders what the previous frame produced.
|
|
if (Cmdline_frame_profile && tracing::frame_profiling_active()) {
|
|
gr_string(gr_screen.center_offset_x + 20, gr_screen.center_offset_y + 100 + gr_get_font_height() + 1,
|
|
tracing::get_frame_profile_output().c_str(), GR_RESIZE_NONE);
|
|
}
|
|
}
|
|
|
|
SCP_string get_rot_mode_string(LabRotationMode rotmode)
|
|
{
|
|
switch (rotmode) {
|
|
case LabRotationMode::Both:
|
|
return "Pitch and Yaw";
|
|
case LabRotationMode::Pitch:
|
|
return "Pitch";
|
|
case LabRotationMode::Yaw:
|
|
return "Yaw";
|
|
case LabRotationMode::Roll:
|
|
return "Roll";
|
|
default:
|
|
return "HOW DID THIS HAPPEN? Ask a coder!";
|
|
}
|
|
}
|
|
|
|
SCP_string get_rot_speed_string(float speed_divisor)
|
|
{
|
|
auto exp = std::lroundf(log10f(speed_divisor));
|
|
|
|
switch (exp) {
|
|
case 2:
|
|
return "Fast";
|
|
case 3:
|
|
return "Slow";
|
|
case 4:
|
|
return "Slowest";
|
|
default:
|
|
return "HOW DID THIS HAPPEN? Ask a coder!";
|
|
}
|
|
}
|
|
|
|
void LabRenderer::renderHud(float) {
|
|
GR_DEBUG_SCOPE("Lab Render HUD");
|
|
|
|
// print FPS at bottom left, might be helpful
|
|
extern void game_get_framerate();
|
|
extern float frametotal;
|
|
extern float Framerate;
|
|
|
|
game_get_framerate();
|
|
|
|
gr_set_color_fast(&Color_white);
|
|
|
|
if (frametotal != 0.0f) {
|
|
gr_printf_no_resize(gr_screen.center_offset_x + 2,
|
|
gr_screen.center_offset_y + gr_screen.center_h - gr_get_font_height(),
|
|
"FPS: %3i %s", (int)std::lround(Framerate), labCamera->getOnFrameInfo().c_str());
|
|
}
|
|
else {
|
|
gr_string(gr_screen.center_offset_x + 10, gr_screen.center_offset_y + gr_screen.center_h - gr_get_font_height(),
|
|
"FPS: ?", GR_RESIZE_NONE);
|
|
}
|
|
|
|
//Print FXAA preset
|
|
if ((gr_is_fxaa_mode(Gr_aa_mode) || gr_is_smaa_mode(Gr_aa_mode)) && !PostProcessing_override) {
|
|
const char* aa_mode;
|
|
switch (Gr_aa_mode) {
|
|
case AntiAliasMode::FXAA_Low:
|
|
aa_mode = "FXAA Low";
|
|
break;
|
|
case AntiAliasMode::FXAA_Medium:
|
|
aa_mode = "FXAA Medium";
|
|
break;
|
|
case AntiAliasMode::FXAA_High:
|
|
aa_mode = "FXAA High";
|
|
break;
|
|
case AntiAliasMode::SMAA_Low:
|
|
aa_mode = "SMAA Low";
|
|
break;
|
|
case AntiAliasMode::SMAA_Medium:
|
|
aa_mode = "SMAA Medium";
|
|
break;
|
|
case AntiAliasMode::SMAA_High:
|
|
aa_mode = "SMAA High";
|
|
break;
|
|
case AntiAliasMode::SMAA_Ultra:
|
|
aa_mode = "SMAA Ultra";
|
|
break;
|
|
default:
|
|
aa_mode = "None";
|
|
break;
|
|
}
|
|
|
|
gr_printf_no_resize(gr_screen.center_offset_x + 2, gr_screen.center_offset_y + gr_screen.center_h - (gr_get_font_height() * 2) - 3, "AA Preset: %s", aa_mode);
|
|
}
|
|
|
|
// Controls info
|
|
gr_printf_no_resize(gr_screen.center_offset_x + 2,
|
|
gr_screen.center_offset_y + gr_screen.center_h - (gr_get_font_height() * 7) - 3,
|
|
"Open Options -> Controls reference for the full object and camera controls list.");
|
|
|
|
// Rotation mode
|
|
gr_printf_no_resize(gr_screen.center_offset_x + 2,
|
|
gr_screen.center_offset_y + gr_screen.center_h - (gr_get_font_height() * 5) - 3,
|
|
"Model rotation axis limit: %s, Rotation speed: %s", get_rot_mode_string(getLabManager()->RotationMode).c_str(),
|
|
get_rot_speed_string(getLabManager()->RotationSpeedDivisor).c_str());
|
|
|
|
// Print current Team Color setting, if any
|
|
if (currentTeamColor != LAB_TEAM_COLOR_NONE) {
|
|
gr_printf_no_resize(gr_screen.center_offset_x + 2,
|
|
gr_screen.center_offset_y + gr_screen.center_h - (gr_get_font_height() * 4) - 3,
|
|
"Current Team Color: %s",
|
|
currentTeamColor.c_str());
|
|
}
|
|
|
|
if (showOrientationWidget) {
|
|
labCamera->renderOverlay();
|
|
}
|
|
}
|
|
|
|
void LabRenderer::useBackground(const SCP_string& mission_name) {
|
|
matrix skybox_orientation;
|
|
char skybox_model[MAX_FILENAME_LEN];
|
|
int skybox_flags;
|
|
|
|
int ambient_light_level;
|
|
extern const char* Neb2_filenames[];
|
|
|
|
char envmap_name[MAX_FILENAME_LEN] = {0};
|
|
SCP_string ltp_name;
|
|
currentMissionBackground = mission_name;
|
|
|
|
stars_pre_level_init(true);
|
|
vm_set_identity(&skybox_orientation);
|
|
|
|
// (DahBlount) - Remember to load the debris anims
|
|
stars_load_debris(false);
|
|
|
|
if (mission_name != LAB_MISSION_NONE_STRING) {
|
|
read_file_text((mission_name + ".fs2").c_str(), CF_TYPE_MISSIONS);
|
|
reset_parse();
|
|
|
|
flagset<Mission::Mission_Flags> flags;
|
|
skip_to_start_of_string("+Flags");
|
|
if (optional_string("+Flags:"))
|
|
stuff_flagset(&flags);
|
|
|
|
skip_to_start_of_string_one_of(SCP_vector<SCP_string>{ "+Volumetric Nebula:", "$Skybox Model:", "$Lighting Profile:", "#Background bitmaps" });
|
|
if (optional_string("+Volumetric Nebula:")) {
|
|
//Rendering usually happens in post-mission-init, just do it now in the lab
|
|
The_mission.volumetrics.emplace().parse_volumetric_nebula().renderVolumeBitmap();
|
|
}
|
|
else {
|
|
volumetrics_level_close();
|
|
}
|
|
|
|
// Are we using a skybox?
|
|
//skip will skip to the end of the file (or to the 'end' string) if any string is absent,
|
|
//so be sure to include any section that might be found
|
|
skip_to_start_of_string_one_of(SCP_vector<SCP_string>{ "$Skybox Model:", "$Lighting Profile:", "#Background bitmaps" });
|
|
strcpy_s(skybox_model, "");
|
|
if (optional_string("$Skybox Model:")) {
|
|
stuff_string(skybox_model, F_NAME, MAX_FILENAME_LEN);
|
|
|
|
if (optional_string("+Skybox Orientation:")) {
|
|
stuff_matrix(&skybox_orientation);
|
|
}
|
|
|
|
if (optional_string("+Skybox Flags:")) {
|
|
skybox_flags = 0;
|
|
stuff_int(&skybox_flags);
|
|
}
|
|
else {
|
|
skybox_flags = DEFAULT_NMODEL_FLAGS;
|
|
}
|
|
|
|
stars_set_background_model(skybox_model, nullptr, skybox_flags);
|
|
stars_set_background_orientation(&skybox_orientation);
|
|
}
|
|
|
|
skip_to_start_of_string_either("$Lighting Profile:", "#Background bitmaps");
|
|
ltp_name = ltp::default_name();
|
|
if(optional_string("$Lighting Profile:")){
|
|
stuff_string(ltp_name,F_NAME);
|
|
if (ltp_name.empty())
|
|
ltp_name = ltp::default_name();
|
|
}
|
|
if (ltp_name != ltp::current()->name) {
|
|
ltp::switch_to(ltp_name);
|
|
}
|
|
|
|
// Mission headers include additional fields between lighting profile and the
|
|
// background section. If we stopped at the lighting profile, we need to seek again.
|
|
skip_to_start_of_string("#Background bitmaps");
|
|
|
|
if (optional_string("#Background bitmaps")) {
|
|
required_string("$Num stars:");
|
|
stuff_int(&Num_stars);
|
|
if (Num_stars >= MAX_STARS)
|
|
Num_stars = MAX_STARS;
|
|
|
|
required_string("$Ambient light level:");
|
|
stuff_int(&ambient_light_level);
|
|
|
|
if (ambient_light_level == 0) {
|
|
ambient_light_level = DEFAULT_AMBIENT_LIGHT_LEVEL;
|
|
}
|
|
|
|
gr_set_ambient_light(ambient_light_level & 0xff, (ambient_light_level >> 8) & 0xff,
|
|
(ambient_light_level >> 16) & 0xff);
|
|
|
|
strcpy_s(Neb2_texture_name, "");
|
|
clear_all_bits(Neb2_poof_flags.get(), Poof_info.size());
|
|
bool nebula = false;
|
|
if (optional_string("+Neb2:")) {
|
|
nebula = true;
|
|
stuff_string(Neb2_texture_name, F_NAME, MAX_FILENAME_LEN);
|
|
}
|
|
if (optional_string("+Neb2Color:")) {
|
|
nebula = true;
|
|
int neb_colors[3];
|
|
stuff_int_list(neb_colors, 3, ParseLookupType::RAW_INTEGER_TYPE);
|
|
Neb2_fog_color[0] = (ubyte)neb_colors[0];
|
|
Neb2_fog_color[1] = (ubyte)neb_colors[1];
|
|
Neb2_fog_color[2] = (ubyte)neb_colors[2];
|
|
flags |= Mission::Mission_Flags::Neb2_fog_color_override;
|
|
}
|
|
|
|
if (nebula){
|
|
// Obsolete and only for backwards compatibility
|
|
if (optional_string("+Neb2Flags:")) {
|
|
int temp;
|
|
stuff_int(&temp);
|
|
bit_array_set_from_int(Neb2_poof_flags.get(), Poof_info.size(), temp);
|
|
}
|
|
// Get poofs by name
|
|
if (optional_string("+Neb2 Poofs List:")) {
|
|
SCP_vector<SCP_string> poofs_list;
|
|
stuff_string_list(poofs_list);
|
|
neb2_set_poof_bits(poofs_list);
|
|
}
|
|
|
|
if (flags[Mission::Mission_Flags::Fullneb]) {
|
|
neb2_post_level_init(flags[Mission::Mission_Flags::Neb2_fog_color_override]);
|
|
}
|
|
}
|
|
|
|
if (flags[Mission::Mission_Flags::Fullneb]) {
|
|
// no regular nebula stuff
|
|
nebula_close();
|
|
}
|
|
else {
|
|
Nebula_index = -1;
|
|
if (optional_string("+Nebula:")) {
|
|
char str[MAX_FILENAME_LEN];
|
|
int z;
|
|
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
|
|
|
|
// parse the proper nebula type (full or not)
|
|
for (z = 0; z < NUM_NEBULAS; z++) {
|
|
if (flags[Mission::Mission_Flags::Fullneb]) {
|
|
if (!stricmp(str, Neb2_filenames[z])) {
|
|
Nebula_index = z;
|
|
break;
|
|
}
|
|
}
|
|
else {
|
|
if (!stricmp(str, Nebula_filenames[z])) {
|
|
Nebula_index = z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (z == NUM_NEBULAS)
|
|
WarningEx(LOCATION, "Unknown nebula %s!", str);
|
|
|
|
if (optional_string("+Color:")) {
|
|
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
|
|
for (z = 0; z < NUM_NEBULA_COLORS; z++) {
|
|
if (!stricmp(str, Nebula_colors[z])) {
|
|
Mission_palette = z;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (z == NUM_NEBULA_COLORS)
|
|
WarningEx(LOCATION, "Unknown nebula color %s!", str);
|
|
|
|
if (optional_string("+Pitch:")) {
|
|
stuff_int(&Nebula_pitch);
|
|
}
|
|
else {
|
|
Nebula_pitch = 0;
|
|
}
|
|
|
|
if (optional_string("+Bank:")) {
|
|
stuff_int(&Nebula_bank);
|
|
}
|
|
else {
|
|
Nebula_bank = 0;
|
|
}
|
|
|
|
if (optional_string("+Heading:")) {
|
|
stuff_int(&Nebula_heading);
|
|
}
|
|
else {
|
|
Nebula_heading = 0;
|
|
}
|
|
}
|
|
|
|
nebula_init(Nebula_index, Nebula_pitch, Nebula_bank, Nebula_heading);
|
|
}
|
|
|
|
stars_load_debris(flags[Mission::Mission_Flags::Fullneb]);
|
|
|
|
|
|
extern void parse_one_background(background_t * background);
|
|
while (optional_string("$Bitmap List:") || check_for_string("$Sun:") || check_for_string("$Starbitmap:")) {
|
|
stars_add_blank_background(false);
|
|
parse_one_background(&Backgrounds.back());
|
|
}
|
|
|
|
stars_load_first_valid_background();
|
|
|
|
if (optional_string("$Environment Map:")) {
|
|
stuff_string(envmap_name, F_NAME, MAX_FILENAME_LEN);
|
|
}
|
|
|
|
const int size = 512;
|
|
int gen_flags = (BMP_FLAG_RENDER_TARGET_STATIC | BMP_FLAG_CUBEMAP | BMP_FLAG_RENDER_TARGET_MIPMAP);
|
|
|
|
if (!Cmdline_env) {
|
|
return;
|
|
}
|
|
|
|
if (gr_screen.envmap_render_target >= 0) {
|
|
if (!bm_release(gr_screen.envmap_render_target, 1)) {
|
|
Warning(LOCATION, "Unable to release environment map render target.");
|
|
}
|
|
|
|
gr_screen.envmap_render_target = -1;
|
|
}
|
|
|
|
if (strlen(envmap_name)) {
|
|
// Load the mission map so we can use it later
|
|
ENVMAP = bm_load(The_mission.envmap_name);
|
|
// Load may fail, if so, don't exit early. Proceed to make render target.
|
|
if (ENVMAP > 1) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
gr_screen.envmap_render_target = bm_make_render_target(size, size, gen_flags);
|
|
}
|
|
}
|
|
else {
|
|
// (DahBlount) - This spot should be used to disable rendering features that only apply to missions.
|
|
Motion_debris_override = true;
|
|
Num_stars = 0;
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<LabCamera> &LabRenderer::getCurrentCamera() {
|
|
return labCamera;
|
|
}
|
|
|
|
void LabRenderer::setCurrentCamera(std::unique_ptr<LabCamera> &newcam) {
|
|
labCamera = std::move(newcam);
|
|
} |