25 #define MAX_LIGHT_LEVELS 16
34 static int Num_light_levels = 0;
38 static int Light_in_shadow = 0;
43 #define MIN_LIGHT 0.03f // When light drops below this level, ignore it. Must be non-zero! (1/32)
46 static int Lighting_off = 0;
50 #if 1 // ADAM'S new stuff
52 #define AMBIENT_LIGHT_DEFAULT 0.15f //0.10f
53 #define REFLECTIVE_LIGHT_DEFAULT 0.75f //0.90f
56 #define AMBIENT_LIGHT_DEFAULT 0.75f //0.10f
57 #define REFLECTIVE_LIGHT_DEFAULT 0.50f //0.90f
65 static void light_filter_reset();
74 dc_printf(
"Usage: light keyword\nWhere keyword can be in the following forms:\n" );
75 dc_printf(
"light on|off Turns all lighting on/off\n" );
76 dc_printf(
"light default Resets lighting to all default values\n" );
77 dc_printf(
"light ambient X Where X is the ambient light between 0 and 1.0\n" );
78 dc_printf(
"light reflect X Where X is the material reflectiveness between 0 and 1.0\n" );
79 dc_printf(
"light dynamic [bool] Toggles dynamic lighting on/off\n" );
80 dc_printf(
"light mode [light|darken] Changes the lighting mode.\n" );
81 dc_printf(
" Where 'light' means the global light adds light.\n");
82 dc_printf(
" and 'darken' means the global light subtracts light.\n");
87 dc_printf(
"Ambient light is set to %.2f\n", Ambient_light );
88 dc_printf(
"Reflective light is set to %.2f\n", Reflective_light );
90 switch( Lighting_mode ) {
95 dc_printf(
"Lighting mode is: darken\n" );
98 dc_printf(
"Lighting mode is: UNKNOWN\n" );
105 if ((val_f < 0.0
f) || (val_f > 1.0
f)) {
106 dc_printf(
" Error: ambient value must be between 0.0 and 1.0\n");
108 Ambient_light =
val_f;
113 if ( (val_f < 0.0
f) || (val_f > 1.0
f)) {
114 dc_printf(
" Error: reflect value mus be between 0.0 and 1.0\n");
116 Reflective_light =
val_f;
127 if (arg_str ==
"light") {
130 }
else if (arg_str ==
"darken") {
134 dc_printf(
" Error: unknown light mode: '%s'\n", arg_str.c_str());
142 Lighting_off = !Lighting_off;
146 dc_printf(
"Error: Unknown argument '%s'\n", arg_str.c_str());
152 Static_light.clear();
155 light_filter_reset();
164 static void light_rotate(
light * l)
218 if ( Lighting_off )
return;
247 Assert( Num_light_levels <= 1 );
249 Static_light.push_back(l);
253 void light_add_point(
const vec3d *
pos,
float r1,
float r2,
float intensity,
float r,
float g,
float b,
int light_ignore_objnum,
float spec_r,
float spec_g,
float spec_b,
bool specular)
255 Assertion( r1 > 0.0
f,
"Invalid radius r1 specified for light: %f. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r1 );
256 Assertion( r2 > 0.0
f,
"Invalid radius r2 specified for light: %f. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r2 );
258 if (r1 < 0.0001
f || r2 < 0.0001
f)
269 if ( Lighting_off )
return;
274 mprintf((
"Out of lights!\n" ));
297 Assert( Num_light_levels <= 1 );
300 void light_add_point_unique(
const vec3d *
pos,
float r1,
float r2,
float intensity,
float r,
float g,
float b,
int affected_objnum,
float spec_r,
float spec_g,
float spec_b,
bool specular)
311 if ( Lighting_off )
return;
316 mprintf((
"Out of lights!\n" ));
339 Assert( Num_light_levels <= 1 );
343 void light_add_tube(
const vec3d *
p0,
const vec3d *
p1,
float r1,
float r2,
float intensity,
float r,
float g,
float b,
int affected_objnum,
float spec_r,
float spec_g,
float spec_b,
bool specular)
354 if ( Lighting_off )
return;
359 mprintf((
"Out of lights!\n" ));
383 Assert( Num_light_levels <= 1 );
389 static void light_filter_reset()
394 if ( Lighting_off )
return;
396 Num_light_levels = 1;
398 int n = Num_light_levels-1;
399 Num_relevent_lights[
n] = 0;
403 Relevent_lights[Num_relevent_lights[
n]++][
n] = l;
421 if ( Lighting_off )
return 0;
423 light_filter_reset();
426 n1 = Num_light_levels-1;
427 n2 = Num_light_levels;
431 Num_relevent_lights[n2] = 0;
433 for (i=0; i<Num_relevent_lights[n1]; i++ ) {
434 l = Relevent_lights[
i][n1];
446 float dist_squared, max_dist_squared;
450 max_dist_squared = l->
radb+rad;
451 max_dist_squared *= max_dist_squared;
453 if ( dist_squared < max_dist_squared ) {
454 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
461 float dist_squared, max_dist_squared;
465 max_dist_squared = l->
radb+rad;
466 max_dist_squared *= max_dist_squared;
468 if ( dist_squared < max_dist_squared ) {
469 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
480 float dist_squared, max_dist_squared;
483 max_dist_squared = l->
radb+rad;
484 max_dist_squared *= max_dist_squared;
486 if ( dist_squared < max_dist_squared )
487 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
493 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
505 return Num_relevent_lights[n2];
508 static int is_inside(
const vec3d *min,
const vec3d *max,
const vec3d *
p0,
float rad)
510 const float *origin = (
float *)&p0->
xyz.x;
511 const float *minB = (
float *)min;
512 const float *maxB = (
float *)max;
515 for (i=0; i<3; i++ ) {
516 if ( origin[i] < minB[i] - rad ) {
518 }
else if (origin[i] > maxB[i] + rad ) {
531 if ( Lighting_off )
return 0;
534 n1 = Num_light_levels-1;
535 n2 = Num_light_levels;
540 Num_relevent_lights[n2] = 0;
542 for (i=0; i<Num_relevent_lights[n1]; i++ ) {
543 l = Relevent_lights[
i][n1];
552 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
559 Relevent_lights[Num_relevent_lights[n2]++][n2] = l;
571 return Num_relevent_lights[n2];
576 if ( Lighting_off )
return;
579 Assert( Num_light_levels > 0 );
582 static int l_num_points=0, l_num_lights=0;
590 if ( Lighting_off )
return;
592 int n = Num_light_levels-1;
595 for (i=0; i<Num_relevent_lights[
n]; i++ ) {
596 l = Relevent_lights[
i][
n];
600 for (i = 0; i < (
int)Static_light.size(); i++) {
601 light_rotate(Static_light[i]);
610 return (
int)Static_light.size();
623 if ( (n < 0) || (n >= (
int)Static_light.size()) ) {
628 *pos = Static_light[
n]->vec;
640 Light_in_shadow = state;
650 for (idx = 0; idx < (
int)Static_light.size(); idx++)
654 if(Deferred_lighting)
659 int n = Num_light_levels-1;
661 for (idx = 0; idx < Num_relevent_lights[
n]; idx++ )
674 return ubyte(
fl2i(static_light_level*255.0
f));
677 if ( Lighting_off )
return 191;
680 lval = Ambient_light;
683 if ( !Light_in_shadow ){
685 for (idx = 0; idx < (
int)Static_light.size(); idx++) {
689 ltmp = -
vm_vec_dot(&Static_light[idx]->local_vec, norm )*Static_light[
idx]->intensity*Reflective_light;
691 switch(Lighting_mode) {
710 lval *= static_light_level;
712 int n = Num_light_levels-1;
714 l_num_lights += Num_relevent_lights[
n];
717 for (i=0; i<Num_relevent_lights[
n]; i++ ) {
718 l = Relevent_lights[
i][
n];
726 if ( dist < l->rada_squared ) {
728 }
else if ( dist < l->radb_squared ) {
732 float ltmp = (1.0f - nnum / dden )*dot*l->
intensity;
752 float rval = 0, gval = 0, bval = 0;
769 if ( Lighting_off ) {
785 for (idx = 0; idx < (
int)Static_light.size(); idx++) {
789 vm_vec_sub(&R,&V, &Static_light[idx]->local_vec);
794 switch(Lighting_mode) {
797 rval += Static_light[
idx]->spec_r * ltmp;
798 gval += Static_light[
idx]->spec_g * ltmp;
799 bval += Static_light[
idx]->spec_b * ltmp;
804 rval -= ltmp;
if ( rval < 0.0
f ) rval = 0.0f;
805 gval -= ltmp;
if ( gval < 0.0
f ) gval = 0.0f;
806 bval -= ltmp;
if ( bval < 0.0
f ) bval = 0.0f;
819 int n = Num_light_levels-1;
821 l_num_lights += Num_relevent_lights[
n];
828 for (idx = 0; idx < Num_relevent_lights[
n]; idx++) {
829 l = Relevent_lights[
idx][
n];
869 if ( dist < l->rada_squared ) {
876 }
else if ( dist < l->radb_squared ) {
881 ratio = (1.0f - nnum / dden)*dot*l->
intensity*factor;
902 float rval, gval, bval;
914 if ( Lighting_off ) {
922 rval = Ambient_light;
923 gval = Ambient_light;
924 bval = Ambient_light;
927 if ( !Light_in_shadow ){
929 for (idx = 0; idx < (
int)Static_light.size(); idx++) {
933 ltmp = -
vm_vec_dot(&Static_light[idx]->local_vec, norm )*Static_light[
idx]->intensity*Reflective_light;
935 switch(Lighting_mode) {
938 rval += Static_light[
idx]->r * ltmp;
939 gval += Static_light[
idx]->g * ltmp;
940 bval += Static_light[
idx]->b * ltmp;
945 rval -= ltmp;
if ( rval < 0.0
f ) rval = 0.0f;
946 gval -= ltmp;
if ( gval < 0.0
f ) gval = 0.0f;
947 bval -= ltmp;
if ( bval < 0.0
f ) bval = 0.0f;
959 rval *= static_light_level;
960 gval *= static_light_level;
961 bval *= static_light_level;
963 int n = Num_light_levels-1;
965 l_num_lights += Num_relevent_lights[
n];
971 for (idx = 0; idx < Num_relevent_lights[
n]; idx++) {
972 l = Relevent_lights[
idx][
n];
1008 if ( dist < l->rada_squared ) {
1015 }
else if ( dist < l->radb_squared ) {
1020 ratio = (1.0f - nnum / dden)*dot*l->
intensity;
1030 if ( gval > m ) m = gval;
1031 if ( bval > m ) m = bval;
1034 float im = 1.0f /
m;
1050 void light_add_cone(
const vec3d *
pos,
const vec3d *dir,
float angle,
float inner_angle,
bool dual_cone,
float r1,
float r2,
float intensity,
float r,
float g,
float b,
int light_ignore_objnum,
float spec_r,
float spec_g,
float spec_b,
bool specular)
1052 Assertion( r1 > 0.0
f,
"Invalid radius r1 specified for light: %f. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r1 );
1053 Assertion( r2 > 0.0
f,
"Invalid radius r2 specified for light: %f. Radius must be > 0.0f. Examine stack trace to determine culprit.\n", r2 );
1055 if (r1 < 0.0001
f || r2 < 0.0001
f)
1066 if ( Lighting_off )
return;
1071 mprintf((
"Out of lights!\n" ));
1098 Assert( Num_light_levels <= 1 );
1108 Assert(light_ptr != NULL);
1110 AllLights.push_back(*light_ptr);
1113 StaticLightIndices.push_back(AllLights.size() - 1);
1122 FilteredLights.clear();
1124 for ( i = 0; i < AllLights.size(); ++
i ) {
1135 float dist_squared, max_dist_squared;
1139 max_dist_squared = l.
radb+rad;
1140 max_dist_squared *= max_dist_squared;
1142 if ( dist_squared < max_dist_squared ) {
1143 FilteredLights.push_back(i);
1148 float dist_squared, max_dist_squared;
1152 max_dist_squared = l.
radb+rad;
1153 max_dist_squared *= max_dist_squared;
1155 if ( dist_squared < max_dist_squared ) {
1156 FilteredLights.push_back(i);
1165 float dist_squared, max_dist_squared;
1168 max_dist_squared = l.
radb+rad;
1169 max_dist_squared *= max_dist_squared;
1171 if ( dist_squared < max_dist_squared ) {
1172 FilteredLights.push_back(i);
1178 FilteredLights.push_back(i);
1203 if ( FilteredLights.size() <= 0 ) {
1209 for ( i = 0; i < FilteredLights.size(); ++
i ) {
1210 BufferedLights.push_back(FilteredLights[i]);
1213 light_info.
num_lights = FilteredLights.size();
1220 return StaticLightIndices.size();
1225 current_light_index = -1;
1226 current_num_lights = -1;
1243 for (
size_t i = 0; i < StaticLightIndices.size(); ++
i) {
1244 int light_index = StaticLightIndices[
i];
1250 if ( Deferred_lighting ) {
1259 if ( num_lights <= 0 || index_start < 0 ) {
1265 Assert(index_start + num_lights <= (
int)BufferedLights.size());
1267 for (
int i = 0; i < num_lights; ++
i ) {
1268 int buffered_light_index = index_start +
i;
1269 int light_index = BufferedLights[buffered_light_index];
void light_add_directional(const vec3d *dir, float intensity, float r, float g, float b, float spec_r, float spec_g, float spec_b, bool specular)
bool light_compare_by_type(const light &a, const light &b)
#define REFLECTIVE_LIGHT_DEFAULT
float static_light_factor
int light_filter_push(int objnum, const vec3d *pos, float rad)
void light_add_point(const vec3d *pos, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r, float spec_g, float spec_b, bool specular)
int light_get_global_dir(vec3d *pos, int n)
struct vec3d::@225::@227 xyz
void setLightFilter(int objnum, const vec3d *pos, float rad)
vec3d * vm_vec_rotate(vec3d *dest, const vec3d *src, const matrix *m)
#define Assertion(expr, msg,...)
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
float static_point_factor
void vm_vec_dist_squared_to_line(const vec3d *p, const vec3d *l0, const vec3d *l1, vec3d *nearest, float *dist_squared)
float vm_vec_mag_squared(const vec3d *v)
#define CLAMP(x, min, max)
#define AMBIENT_LIGHT_DEFAULT
SCP_vector< light * > Static_light
light_indexing_info bufferLights()
typedef int(SCP_EXT_CALLCONV *SCPDLL_PFVERSION)(SCPDLL_Version *)
GLdouble GLdouble GLdouble r
void vm_vec_scale(vec3d *dest, float s)
GLboolean GLboolean GLboolean GLboolean a
int light_filter_push_box(const vec3d *min, const vec3d *max)
int vm_vec_dist_to_line(const vec3d *p, const vec3d *l0, const vec3d *l1, vec3d *nearest, float *dist)
bool dc_maybe_stuff_boolean(bool *b)
Tries to stuff a bool from the Command_string.
bool dc_optional_string_either(const char *str1, const char *str2)
Searches for an optional string and it's alias.
bool setLights(const light_indexing_info *info)
DCF(light,"Changes lighting parameters")
void light_set_ambient(float ambient_light)
void vm_vec_copy_scale(vec3d *dest, const vec3d *src, float s)
void dc_stuff_float(float *f)
Stuffs a float to the given variable.
ubyte light_apply(const vec3d *pos, const vec3d *norm, float static_light_level)
int light_get_global_count()
void vm_vec_sub(vec3d *dest, const vec3d *src0, const vec3d *src1)
void dc_stuff_string_white(char *out_str, size_t maxlen)
Stuffs a whitespace delimited string to out_str from the command line, stopping at the end of the com...
GLboolean GLboolean GLboolean b
void dc_stuff_boolean(bool *b)
stuffs a boolean evaluated integer or string into the given variable.
void light_add_tube(const vec3d *p0, const vec3d *p1, float r1, float r2, float intensity, float r, float g, float b, int affected_objnum, float spec_r, float spec_g, float spec_b, bool specular)
typedef float(SCP_EXT_CALLCONV *SCPTRACKIR_PFFLOATVOID)()
void light_set_all_relevent()
void light_add_cone(const vec3d *pos, const vec3d *dir, float angle, float inner_angle, bool dual_cone, float r1, float r2, float intensity, float r, float g, float b, int light_ignore_objnum, float spec_r, float spec_g, float spec_b, bool specular)
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
float vm_vec_dot(const vec3d *v0, const vec3d *v1)
#define gr_reset_lighting
void light_apply_rgb(ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, float static_light_level)
void light_apply_specular(ubyte *param_r, ubyte *param_g, ubyte *param_b, const vec3d *pos, const vec3d *norm, const vec3d *cam)
bool dc_optional_string(const char *pstr)
Searches for an optional string.
double specular_exponent_value
void opengl_change_active_lights(int pos, int d_offset)
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
bool is_minimum_GLSL_version()
void light_add_point_unique(const vec3d *pos, float r1, float r2, float intensity, float r, float g, float b, int affected_objnum, float spec_r, float spec_g, float spec_b, bool specular)
void light_set_shadow(int state)
void vm_vec_add(vec3d *dest, const vec3d *src0, const vec3d *src1)
void addLight(const light *light_ptr)
float vm_vec_normalize(vec3d *v)