Files
BMagnu 25eebd96de Shadow Overhaul (#7529)
* Extract shadows into own shader and render pass

# Conflicts:
#	code/def_files/data/effects/main-g.sdr

* Consolidate render queue code

* More cleanup

* Fix missing clear of shadow buffer inter frame

* Request capability for viewport layer rendering

* instanced shadows

* Fix issues

* Switch to PCF+PCSS and proper textures for it

* Smooth PCSS toggle

* Fix for windows

* Fix OGL error

* Cleanup of old flag

* Expose shadow smoothness

* Fix missing uniform

* Make number of shadow cascades dynamic

* Progress on cockpit shadow integration

* Wrangle Cockpit and show-ship shadows into correct behaviour

* Cleanup

* make player ship shadow table options more intuitive

* Cleanup

* Only read from correct set of shadow maps, also stretch first main-scene map to 0

* Remove now non-necessary validation

* Make shadow cascade buffer more typesafe and less wasteful

* Don't allocate cockpit cascades if not used

* Cleanup

* Final fixes

* Fix Warnings

* clang tidy

* Fix missing fallback for shader precaching

* That weird FOV multiplier that always ruins your day

* Avoid shadow geometry artifacts by using hardware depth clamping

* Correctly handle shadow cascade overrides with hardcoded length

* GCC9 and its sad state of C++17 support.

* Address Feedback

# Conflicts:
#	code/graphics/shadows.cpp
2026-07-04 16:08:41 +02:00

409 lines
11 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#ifndef _SHIPFX_H
#define _SHIPFX_H
#include "globalincs/pstypes.h"
#include "graphics/grbatch.h"
#include "model/modelrender.h"
class object;
class ship;
class ship_info;
struct game_snd;
class ship_subsys;
struct shockwave_create_info;
struct vec3d;
struct matrix;
// Make sparks fly off of ship n
// sn = spark number to spark, corrosponding to element in
// ship->hitpos array. If this isn't -1, it is a just
// got hit by weapon spark, otherwise pick one randomally.
void shipfx_emit_spark( int n, int sn );
// Does the special effects to blow a subsystem off a ship
extern void shipfx_blow_off_subsystem(object *ship_obj, ship *ship_p, const ship_subsys *subsys, const vec3d *exp_center, bool no_explosion = false, bool no_fireballs = false);
// Creates "ndebris" pieces of debris on random verts of the "submodel" in the
// ship's model.
extern void shipfx_blow_up_model(object *obj, int submodel, int ndebris, const vec3d *exp_center, const ship_subsys *subsys = nullptr);
// =================================================
// SHIP WARP IN EFFECT STUFF
// =================================================
// if we are specifying a Default warp with an index into fireball.tbl, use this flag
#define WT_DEFAULT_WITH_FIREBALL (1<<31)
// if we have more than one flag defined above, this should mask all of them
#define WT_FLAG_MASK ~(1<<31)
// Warp type defines
#define WT_DEFAULT 0
#define WT_KNOSSOS 1
#define WT_DEFAULT_THEN_KNOSSOS 2
#define WT_IN_PLACE_ANIM 3
#define WT_SWEEPER 4
#define WT_HYPERSPACE 5
extern const char *Warp_types[];
extern int Num_warp_types;
extern int warptype_match(const char *p);
extern void ship_set_warp_effects(object *objp);
enum class WarpDirection { NONE, WARP_IN, WARP_OUT };
// When a ship warps in, this gets called to start the effect
extern void shipfx_warpin_start( object *objp );
// During a ship warp in, this gets called each frame to move the ship
extern void shipfx_warpin_frame( object *objp, float frametime );
// When a ship warps out, this gets called to start the effect
extern void shipfx_warpout_start( object *objp );
// During a ship warp out, this gets called each frame to move the ship
extern void shipfx_warpout_frame( object *objp, float frametime );
// =================================================
// WARP PARAMS
// =================================================
// WarpParams allows per-ship customization of what was previously in ships.tbl
class WarpParams
{
public:
WarpDirection direction = WarpDirection::WARP_IN;
char anim[MAX_FILENAME_LEN];
float radius = 0.0f;
gamesnd_id snd_start;
gamesnd_id snd_end;
float speed = 0.0f;
int time = 0; // in ms
float accel_exp = 1.0f;
int warp_type = WT_DEFAULT;
bool supercap_warp_physics = false;
// only valid for warpout
int warpout_engage_time = -1; // in ms
float warpout_player_speed = 0.0f;
WarpParams();
bool operator==(const WarpParams &other);
bool operator!=(const WarpParams &other);
};
extern SCP_vector<WarpParams> Warp_params;
extern int find_or_add_warp_params(const WarpParams &params);
extern float shipfx_calculate_warp_time(object *objp, WarpDirection warp_dir, float half_length, float warping_dist);
extern float shipfx_calculate_arrival_warp_distance(object *objp);
// =================================================
// SHIP SHADOW EFFECT STUFF
// =================================================
// Given world point see if it is in a shadow.
bool shipfx_eye_in_shadow( vec3d *eye_pos, object *src_obj, int light_n);
// =================================================
// SHIP GUN FLASH EFFECT STUFF
// =================================================
// Resets the ship flash stuff. Call before
// each level.
void shipfx_flash_init();
// Given that a ship fired a weapon, light up the model
// accordingly.
// Set is_primary to non-zero if this is a primary weapon.
// Gun_pos should be in object's frame of reference, not world!!!
void shipfx_flash_create(object *objp, int model_num, vec3d *gun_pos, vec3d *gun_dir, int is_primary, int weapon_info_index, int weapon_objnum);
// Does whatever processing needs to be done each frame.
void shipfx_flash_do_frame(float frametime);
// =================================================
// LARGE SHIP EXPLOSION EFFECT STUFF
// =================================================
// Call between levels
void shipfx_large_blowup_level_init();
// Returns 0 if couldn't init
void shipfx_large_blowup_init(ship *shipp);
// Returns 1 when explosion is done
int shipfx_large_blowup_do_frame(ship *shipp, float frametime);
void shipfx_large_blowup_queue_render(model_draw_list *scene, ship* shipp);
void shipfx_debris_limit_speed(const struct debris *db, const ship *shipp);
// sound manager fore big ship sub explosions sounds
void do_sub_expl_sound(float radius, vec3d* sound_pos, sound_handle* sound_handle);
// do all shockwaves for a ship blowing up
void shipfx_do_shockwave_stuff(ship *shipp, shockwave_create_info *sci);
// =================================================
// ELECTRICAL SPARKS ON DAMAGED SHIPS EFFECT STUFF
// =================================================
void shipfx_do_lightning_arcs_frame( ship *shipp );
// =================================================
// NEBULA LIGHTNING
// =================================================
void shipfx_do_lightning_frame( ship *shipp );
// engine wash level init
void shipfx_engine_wash_level_init();
// pause engine wash sounds
void shipfx_stop_engine_wash_sound();
//********************-----CLASS: WarpEffect-----********************//
class WarpEffect
{
protected:
//core variables
int m_objnum = -1;
WarpDirection m_direction = WarpDirection::NONE;
//variables provided for expediency
int m_shipnum = -1;
int m_ship_info_index = -1;
int m_warp_params_index = -1;
public:
WarpEffect() = default;
explicit WarpEffect(int objnum, WarpDirection direction);
virtual ~WarpEffect() = default;
bool isValid() const;
virtual void pageIn();
virtual void pageOut();
virtual int warpStart();
virtual int warpFrame(float frametime);
virtual int warpShipClip(model_render_params *render_info);
virtual int warpShipRender();
virtual int warpEnd();
//For VM_WARP_CHASE
virtual int getWarpPosition(vec3d *output) const;
virtual int getWarpOrientation(matrix *output) const;
};
bool point_is_clipped_by_warp(const vec3d* point, WarpEffect* warp_effect);
//********************-----CLASS: WE_Default-----********************//
#define WE_DEFAULT_NUM_STAGES 2
class WE_Default : public WarpEffect
{
private:
//portal object
int m_portal_objnum = -1;
//ship data
vec3d actual_local_center; // center of the ship, not necessarily the model origin
float half_length; // half the length of the ship, or the docked assembly
float warping_dist; // distance to go through the effect (which is the full length)
float warping_time; // time to go through the effect
float warping_speed; // speed to go through the effect
void compute_warpout_stuff(float *ship_move_time, vec3d *warp_pos);
//Total data
int total_time_start;
int total_time_end;
//Stage data
int stage_time_start;
int stage_time_end; // pops when ship is completely warped out or warped in. Used for both warp in and out.
//Data "storage"
int stage_duration[WE_DEFAULT_NUM_STAGES + 1] = { 0 };
//sweeper polygon and clip effect
vec3d pos = vmd_zero_vector;
vec3d fvec = vmd_zero_vector;
float radius = 0.0f;
public:
explicit WE_Default(int objnum, WarpDirection n_direction);
int warpStart() override;
int warpFrame(float frametime) override;
int warpShipClip(model_render_params *render_info) override;
int warpShipRender() override;
int getWarpPosition(vec3d *output) const override;
int getWarpOrientation(matrix *output) const override;
};
//********************-----CLASS: WE_BSG-----********************//
#define WE_BSG_NUM_STAGES 2
class WE_BSG : public WarpEffect
{
private:
//Total data
int total_time_start;
int total_time_end;
//Stage data
int stage;
int stage_time_start;
int stage_time_end; // pops when ship is completely warped out or warped in. Used for both warp in and out.
//Data "storage"
int stage_duration[WE_BSG_NUM_STAGES];
//anim
int anim;
int anim_nframes;
int anim_fps;
int anim_total_time;
int shockwave;
int shockwave_nframes;
int shockwave_fps;
int shockwave_total_time;
vec3d autocenter;
float z_offset_max;
float z_offset_min;
float tube_radius;
float shockwave_radius;
//*****Per-instance
vec3d pos;
//Sound
float snd_range_factor;
sound_handle snd_start;
game_snd *snd_start_gs;
sound_handle snd_end;
game_snd *snd_end_gs;
public:
explicit WE_BSG(int objnum, WarpDirection n_direction);
~WE_BSG() override;
void pageIn() override;
int warpStart() override;
int warpFrame(float frametime) override;
int warpShipClip(model_render_params *render_info) override;
int warpShipRender() override;
int warpEnd() override;
int getWarpPosition(vec3d *output) const override;
int getWarpOrientation(matrix *output) const override;
};
//********************-----CLASS: WE_Homeworld-----********************//
#define WE_HOMEWORLD_NUM_STAGES 6
class WE_Homeworld : public WarpEffect
{
private:
//Total data
int total_time_start;
int total_time_end;
//Stage data
int stage;
int stage_time_start;
int stage_time_end; // pops when ship is completely warped out or warped in. Used for both warp in and out.
//Data "storage"
int stage_duration[WE_HOMEWORLD_NUM_STAGES];
//anim
int anim;
int anim_nframes;
int anim_fps;
//sound
sound_handle snd;
float snd_range_factor;
game_snd *snd_gs;
//sweeper polygon and clip effect
vec3d pos;
vec3d fvec;
float width;
float width_full;
float height;
float height_full;
float z_offset_min;
float z_offset_max;
public:
explicit WE_Homeworld(int objnum, WarpDirection n_direction);
~WE_Homeworld() override;
int warpStart() override;
int warpFrame(float frametime) override;
int warpShipClip(model_render_params *render_info) override;
int warpShipRender() override;
int warpEnd() override;
int getWarpPosition(vec3d *output) const override;
int getWarpOrientation(matrix *output) const override;
};
//********************-----CLASS: WE_Hyperspace----********************//
class WE_Hyperspace : public WarpEffect
{
private:
//Total data
int total_time_start;
int total_duration;
int total_time_end;
float accel_or_decel_exp;
float initial_velocity;
//sweeper polygon and clip effect
vec3d pos_final;
float scale_factor;
//Sound
float snd_range_factor;
sound_handle snd_start;
game_snd *snd_start_gs;
sound_handle snd_end;
game_snd *snd_end_gs;
public:
explicit WE_Hyperspace(int objnum, WarpDirection n_direction);
int warpStart() override;
int warpFrame(float frametime) override;
int warpEnd() override;
};
class shadow_render_list;
void shipfx_shadow_render_blowup(shadow_render_list* shadow_list, ship* shipp);
#endif