diff --git a/code/graphics/opengl/gropengldeferred.cpp b/code/graphics/opengl/gropengldeferred.cpp index 2051febac6a..fc03d4755c6 100644 --- a/code/graphics/opengl/gropengldeferred.cpp +++ b/code/graphics/opengl/gropengldeferred.cpp @@ -346,7 +346,7 @@ void gr_opengl_deferred_lighting_finish() auto light_data = prepare_light_uniforms(l, light_uniform_aligner); if (l.type == Light_Type::Cone) { - light_data->dualCone = l.dual_cone ? 1.0f : 0.0f; + light_data->dualCone = (l.flags & LF_DUAL_CONE) ? 1.0f : 0.0f; light_data->coneAngle = l.cone_angle; light_data->coneInnerAngle = l.cone_inner_angle; light_data->coneDir = l.vec2; diff --git a/code/graphics/opengl/gropenglpostprocessing.cpp b/code/graphics/opengl/gropenglpostprocessing.cpp index e2b27ce0ced..5a77fc94296 100644 --- a/code/graphics/opengl/gropenglpostprocessing.cpp +++ b/code/graphics/opengl/gropenglpostprocessing.cpp @@ -431,7 +431,6 @@ extern GLuint Cockpit_depth_texture; extern GLuint Scene_position_texture; extern GLuint Scene_normal_texture; extern GLuint Scene_specular_texture; -extern bool stars_sun_has_glare(int index); extern float Sun_spot; void opengl_post_lightshafts() { @@ -452,7 +451,7 @@ void opengl_post_lightshafts() light_get_global_dir(&light_dir, idx); vm_vec_rotate(&local_light_dir, &light_dir, &Eye_matrix); - if ( !stars_sun_has_glare(idx) ) { + if ( !light_has_glare(idx) ) { continue; } diff --git a/code/lighting/lighting.cpp b/code/lighting/lighting.cpp index 00e8de2c1eb..387e2c5c412 100644 --- a/code/lighting/lighting.cpp +++ b/code/lighting/lighting.cpp @@ -176,13 +176,13 @@ static void light_rotate(light * l) } } -void light_add_directional(const vec3d* dir, const hdr_color* new_color, const float source_radius) +void light_add_directional(const vec3d* dir, int sun_index, bool no_glare, const hdr_color* new_color, const float source_radius) { Assert(new_color!= nullptr); - light_add_directional(dir, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius); + light_add_directional(dir, sun_index, no_glare, new_color->i(), new_color->r(), new_color->g(), new_color->b(), source_radius); } namespace ltp=lighting_profiles; -void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius) +void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius) { if (Lighting_off) return; @@ -191,6 +191,8 @@ void light_add_directional(const vec3d *dir, float intensity, float r, float g, light l; l.type = Light_Type::Directional; + l.flags = no_glare ? (LF_DEFAULT | LF_NO_GLARE) : LF_DEFAULT; + l.sun_index = sun_index; vm_vec_copy_scale( &l.vec, dir, -1.0f ); @@ -233,6 +235,8 @@ void light_add_point(const vec3d *pos, float r1, float r2, float intensity, floa Num_lights++; l.type = Light_Type::Point; + l.flags = LF_DEFAULT; + l.sun_index = -1; l.vec = *pos; l.r = r; l.g = g; @@ -272,6 +276,8 @@ void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, float Num_lights++; l.type = Light_Type::Tube; + l.flags = LF_DEFAULT; + l.sun_index = -1; l.vec = *p0; l.vec2 = *p1; l.r = r; @@ -317,19 +323,46 @@ int light_get_global_count() * @param pos Position * @param n Light source * - * Returns 0 if there is no global light. + * Returns false if there is no global light. */ -int light_get_global_dir(vec3d *pos, int n) +bool light_get_global_dir(vec3d *pos, int n) { - if ( (n < 0) || (n >= (int)Static_light.size()) ) { - return 0; + if (!SCP_vector_inbounds(Static_light, n)) { + return false; } if (pos) { *pos = Static_light[n].vec; vm_vec_scale( pos, -1.0f ); } - return 1; + return true; +} + +bool light_has_glare(int n) +{ + if (!SCP_vector_inbounds(Static_light, n)) { + return false; + } + + return (Static_light[n].flags & LF_NO_GLARE) == 0; +} + +int light_get_sun_index(int n) +{ + if (!SCP_vector_inbounds(Static_light, n)) { + return -1; + } + + return Static_light[n].sun_index; +} + +int light_find_for_sun(int sun_index) +{ + for (size_t n = 0; n < Static_light.size(); ++n) + if (Static_light[n].sun_index == sun_index) + return static_cast(n); + + return -1; } void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, float static_light_level ) @@ -478,11 +511,12 @@ void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner Num_lights++; l.type = Light_Type::Cone; + l.flags = dual_cone ? (LF_DEFAULT | LF_DUAL_CONE) : LF_DEFAULT; + l.sun_index = -1; l.vec = *pos; l.vec2= *dir; l.cone_angle = angle; l.cone_inner_angle = inner_angle; - l.dual_cone = dual_cone; l.r = r; l.g = g; l.b = b; diff --git a/code/lighting/lighting.h b/code/lighting/lighting.h index c9b41643b81..60fe5d5e243 100644 --- a/code/lighting/lighting.h +++ b/code/lighting/lighting.h @@ -47,11 +47,16 @@ typedef struct light { float r,g,b; // The color components of the light float cone_angle; // angle for cone lights float cone_inner_angle; // the inner angle for calculating falloff - bool dual_cone; // should the cone be shining in both directions? + int flags; // see below + int sun_index; // if this light corresponds to a sun float source_radius; // The actual size of the object or volume emitting the light int instance; } light; +#define LF_DUAL_CONE (1<<0) // should the cone be shining in both directions? +#define LF_NO_GLARE (1<<1) // for example, a sun with $NoGlare +#define LF_DEFAULT 0 // no flags by default + extern SCP_vector Static_light; struct light_indexing_info @@ -91,8 +96,8 @@ extern void light_reset(); //Intensity in lighting inputs multiplies the base colors. -extern void light_add_directional(const vec3d *dir, const hdr_color *new_color, const float source_radius = 0.0f ); -extern void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, const float source_radius = 0.0f); +extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, const hdr_color *new_color, const float source_radius = 0.0f ); +extern void light_add_directional(const vec3d *dir, int sun_index, bool no_glare, float intensity, float r, float g, float b, const float source_radius = 0.0f); extern void light_add_point(const vec3d * pos, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f); extern void light_add_point(const vec3d * pos, float r1, float r2, float intensity, float r, float g, float b, const float source_radius = 0.0f); extern void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, const hdr_color *new_color, const float source_radius = 0.0f); @@ -110,8 +115,13 @@ void light_apply_rgb( ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3 extern int light_get_global_count(); // Fills direction of global light source N in pos. -// Returns 0 if there is no global light. -extern int light_get_global_dir(vec3d *pos, int n); +// Returns false if there is no global light. +extern bool light_get_global_dir(vec3d *pos, int n); + +extern bool light_has_glare(int n); + +extern int light_get_sun_index(int n); +extern int light_find_for_sun(int sun_index); bool light_compare_by_type(const light &a, const light &b); diff --git a/code/missionui/missionscreencommon.cpp b/code/missionui/missionscreencommon.cpp index 147896cb536..ca0ecc65b01 100644 --- a/code/missionui/missionscreencommon.cpp +++ b/code/missionui/missionscreencommon.cpp @@ -1960,13 +1960,13 @@ void common_setup_room_lights() light_reset(); auto tempv = vm_vec_new(-1.0f,0.3f,-1.0f); auto tempc = hdr_color(1.0f,0.95f,0.9f, 0.0f, 1.5f); - light_add_directional(&tempv,&tempc); + light_add_directional(&tempv,-1,false,&tempc); tempv.xyz={-0.4f,0.4f,1.1f}; tempc = hdr_color(0.788f,0.886f,1.0f,0.0f,1.5f); - light_add_directional(&tempv,&tempc); + light_add_directional(&tempv,-1,false,&tempc); tempv.xyz={0.4f,0.1f,0.4f}; tempc = hdr_color(1.0f,1.0f,1.0f,0.0f,0.4f); - light_add_directional(&tempv,&tempc); + light_add_directional(&tempv,-1,false,&tempc); gr_set_ambient_light(53, 53, 53); light_rotate_all(); } diff --git a/code/ship/shipfx.cpp b/code/ship/shipfx.cpp index 88304496f37..6e54fd2d25e 100644 --- a/code/ship/shipfx.cpp +++ b/code/ship/shipfx.cpp @@ -785,7 +785,7 @@ void shipfx_warpout_frame( object *objp, float frametime ) /** * Given world point see if it is in a shadow. */ -bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int sun_n ) +bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int light_n ) { object *objp; ship_obj *so; @@ -802,7 +802,7 @@ bool shipfx_eye_in_shadow( vec3d *eye_pos, object * src_obj, int sun_n ) rp0 = *eye_pos; // get the light dir - if(!light_get_global_dir(&light_dir, sun_n)){ + if(!light_get_global_dir(&light_dir, light_n)){ return false; } diff --git a/code/ship/shipfx.h b/code/ship/shipfx.h index cdd11cb983d..c7fbdeab232 100644 --- a/code/ship/shipfx.h +++ b/code/ship/shipfx.h @@ -120,7 +120,7 @@ extern float shipfx_calculate_arrival_warp_distance(object *objp); // ================================================= // Given world point see if it is in a shadow. -bool shipfx_eye_in_shadow( vec3d *eye_pos, object *src_obj, int sun_n); +bool shipfx_eye_in_shadow( vec3d *eye_pos, object *src_obj, int light_n); // ================================================= diff --git a/code/starfield/starfield.cpp b/code/starfield/starfield.cpp index 181107ea9fb..50bf135d7c2 100644 --- a/code/starfield/starfield.cpp +++ b/code/starfield/starfield.cpp @@ -1301,7 +1301,7 @@ void stars_draw_sun(int show_sun) // add the light source corresponding to the sun, except when rendering to an envmap if ( !Rendering_to_env ) - light_add_directional(&sun_dir, bm->i, bm->r, bm->g, bm->b); + light_add_directional(&sun_dir, idx, !bm->glare, bm->i, bm->r, bm->g, bm->b); // if supernova if ( supernova_active() && (idx == 0) ) @@ -2698,12 +2698,6 @@ starfield_bitmap *stars_get_bitmap_entry(int index, bool is_a_sun) return NULL; } -bool stars_sun_has_glare(int index) -{ - starfield_bitmap *sb = stars_get_bitmap_entry(index, true); - return (sb && sb->glare); -} - // set an instace to not render void stars_mark_instance_unused(int index, bool is_a_sun) { diff --git a/freespace2/freespace.cpp b/freespace2/freespace.cpp index f81e936a86d..39424ea25f4 100644 --- a/freespace2/freespace.cpp +++ b/freespace2/freespace.cpp @@ -661,13 +661,17 @@ DCF(sn_glare, "Sets the sun glare scale (Default is 1.7)") } float Supernova_last_glare = 0.0f; -bool stars_sun_has_glare(int index); + void game_sunspot_process(float frametime) { TRACE_SCOPE(tracing::SunspotProcess); int n_lights, idx; float Sun_spot_goal = 0.0f; + int sun_idx = 0; + int light_idx = light_find_for_sun(sun_idx); + Assertion(light_idx >= 0, "Could not find sun for light index %d!", sun_idx); + // supernova auto sn_stage = supernova_stage(); if (sn_stage != SUPERNOVA_STAGE::NONE) { @@ -685,7 +689,7 @@ void game_sunspot_process(float frametime) pct = supernova_sunspot_pct(); vec3d light_dir; - light_get_global_dir(&light_dir, 0); + light_get_global_dir(&light_dir, light_idx); float dot; dot = vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec ); @@ -698,9 +702,9 @@ void game_sunspot_process(float frametime) } // draw the sun glow - if ( !shipfx_eye_in_shadow( &Eye_position, Viewer_obj, 0 ) ) { + if ( !shipfx_eye_in_shadow( &Eye_position, Viewer_obj, light_idx ) ) { // draw the glow for this sun - stars_draw_sun_glow(0); + stars_draw_sun_glow(sun_idx); } Supernova_last_glare = Sun_spot_goal; @@ -747,8 +751,8 @@ void game_sunspot_process(float frametime) vec3d light_dir; light_get_global_dir(&light_dir, idx); - //only do sunglare stuff if this sun has one - if (stars_sun_has_glare(idx)) { + //only do sunglare stuff if this light source has one + if (light_has_glare(idx)) { float dot = vm_vec_dot( &light_dir, &Eye_matrix.vec.fvec )*0.5f+0.5f; Sun_spot_goal += (float)pow(dot,85.0f); }