|
|
@@ -1092,23 +1092,12 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|
|
const LightAttrib *target_light = (const LightAttrib *)
|
|
|
_target_rs->get_attrib_def(LightAttrib::get_class_slot());
|
|
|
|
|
|
- int num_on_lights = target_light->get_num_on_lights();
|
|
|
- if (num_on_lights == 0) {
|
|
|
+ if (!target_light->has_any_on_light()) {
|
|
|
// There are no lights at all. This means, to follow the fixed-
|
|
|
// function model, we pretend there is an all-white ambient light.
|
|
|
t.set_row(3, LVecBase4(1, 1, 1, 1));
|
|
|
} else {
|
|
|
- for (int li = 0; li < num_on_lights; li++) {
|
|
|
- NodePath light = target_light->get_on_light(li);
|
|
|
- nassertr(!light.is_empty(), &LMatrix4::zeros_mat());
|
|
|
- Light *light_obj = light.node()->as_light();
|
|
|
- nassertr(light_obj != (Light *)NULL, &LMatrix4::zeros_mat());
|
|
|
-
|
|
|
- if (light_obj->is_ambient_light()) {
|
|
|
- cur_ambient_light += light_obj->get_color();
|
|
|
- }
|
|
|
- }
|
|
|
- t.set_row(3, cur_ambient_light);
|
|
|
+ t.set_row(3, target_light->get_ambient_contribution());
|
|
|
}
|
|
|
return &t;
|
|
|
}
|
|
|
@@ -1374,28 +1363,20 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
|
|
|
const LightAttrib *target_light;
|
|
|
_target_rs->get_attrib_def(target_light);
|
|
|
|
|
|
- // We want to ignore ambient lights. To that effect, iterate through the
|
|
|
- // list of lights. In the future, we will improve this system, by also
|
|
|
- // filtering down to the number of lights specified by the shader.
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- int num_on_lights = target_light->get_num_on_lights();
|
|
|
- for (int li = 0; li < num_on_lights; li++) {
|
|
|
- NodePath light = target_light->get_on_light(li);
|
|
|
+ // We don't count ambient lights, which would be pretty silly to handle
|
|
|
+ // via this mechanism.
|
|
|
+ size_t num_lights = target_light->get_num_non_ambient_lights();
|
|
|
+ if (index >= 0 && (size_t)index < num_lights) {
|
|
|
+ NodePath light = target_light->get_on_light((size_t)index);
|
|
|
nassertr(!light.is_empty(), &LMatrix4::ident_mat());
|
|
|
Light *light_obj = light.node()->as_light();
|
|
|
- nassertr(light_obj != (Light *)NULL, &LMatrix4::ident_mat());
|
|
|
+ nassertr(light_obj != nullptr, &LMatrix4::ident_mat());
|
|
|
|
|
|
- if (!light_obj->is_ambient_light()) {
|
|
|
- if (i++ == index) {
|
|
|
- return fetch_specified_member(light, name, t);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ return fetch_specified_member(light, name, t);
|
|
|
|
|
|
- // Apply the default OpenGL lights otherwise.
|
|
|
- // Special exception for light 0, which defaults to white.
|
|
|
- if (index == 0) {
|
|
|
+ } else if (index == 0) {
|
|
|
+ // Apply the default OpenGL lights otherwise.
|
|
|
+ // Special exception for light 0, which defaults to white.
|
|
|
string basename = name->get_basename();
|
|
|
if (basename == "color" || basename == "diffuse") {
|
|
|
t.set_row(3, _light_color_scale);
|
|
|
@@ -1776,35 +1757,28 @@ fetch_specified_texture(Shader::ShaderTexSpec &spec, SamplerState &sampler,
|
|
|
const LightAttrib *target_light;
|
|
|
_target_rs->get_attrib_def(target_light);
|
|
|
|
|
|
- // We want to ignore ambient lights. To that effect, iterate through
|
|
|
- // the list of lights. In the future, we will improve this system, by
|
|
|
- // also filtering down to the number of lights specified by the shader.
|
|
|
- int i = 0;
|
|
|
-
|
|
|
- int num_on_lights = target_light->get_num_on_lights();
|
|
|
- for (int li = 0; li < num_on_lights; li++) {
|
|
|
- NodePath light = target_light->get_on_light(li);
|
|
|
- nassertr(!light.is_empty(), NULL);
|
|
|
+ // We don't count ambient lights, which would be pretty silly to handle
|
|
|
+ // via this mechanism.
|
|
|
+ size_t num_lights = target_light->get_num_non_ambient_lights();
|
|
|
+ if (spec._stage >= 0 && (size_t)spec._stage < num_lights) {
|
|
|
+ NodePath light = target_light->get_on_light((size_t)spec._stage);
|
|
|
+ nassertr(!light.is_empty(), nullptr);
|
|
|
Light *light_obj = light.node()->as_light();
|
|
|
- nassertr(light_obj != (Light *)NULL, NULL);
|
|
|
-
|
|
|
- if (!light_obj->is_ambient_light()) {
|
|
|
- if (i++ == spec._stage) {
|
|
|
- PT(Texture) tex = get_shadow_map(light);
|
|
|
- if (tex != (Texture *)NULL) {
|
|
|
- sampler = tex->get_default_sampler();
|
|
|
- }
|
|
|
- return tex;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ nassertr(light_obj != nullptr, nullptr);
|
|
|
|
|
|
- // There is no such light assigned. Bind a dummy shadow map.
|
|
|
- PT(Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
|
|
|
- if (tex != nullptr) {
|
|
|
- sampler = tex->get_default_sampler();
|
|
|
+ PT(Texture) tex = get_shadow_map(light);
|
|
|
+ if (tex != nullptr) {
|
|
|
+ sampler = tex->get_default_sampler();
|
|
|
+ }
|
|
|
+ return tex;
|
|
|
+ } else {
|
|
|
+ // There is no such light assigned. Bind a dummy shadow map.
|
|
|
+ PT(Texture) tex = get_dummy_shadow_map((Texture::TextureType)spec._desired_type);
|
|
|
+ if (tex != nullptr) {
|
|
|
+ sampler = tex->get_default_sampler();
|
|
|
+ }
|
|
|
+ return tex;
|
|
|
}
|
|
|
- return tex;
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
@@ -2645,7 +2619,7 @@ do_issue_light() {
|
|
|
int i;
|
|
|
|
|
|
int num_enabled = 0;
|
|
|
- int num_on_lights = 0;
|
|
|
+ bool any_on_lights = false;
|
|
|
|
|
|
const LightAttrib *target_light;
|
|
|
_target_rs->get_attrib_def(target_light);
|
|
|
@@ -2654,18 +2628,16 @@ do_issue_light() {
|
|
|
display_cat.spam()
|
|
|
<< "do_issue_light: " << target_light << "\n";
|
|
|
}
|
|
|
- if (target_light != (LightAttrib *)NULL) {
|
|
|
- CPT(LightAttrib) new_light = target_light->filter_to_max(_max_lights);
|
|
|
- if (display_cat.is_spam()) {
|
|
|
- new_light->write(display_cat.spam(false), 2);
|
|
|
- }
|
|
|
-
|
|
|
- num_on_lights = new_light->get_num_on_lights();
|
|
|
- for (int li = 0; li < num_on_lights; li++) {
|
|
|
- NodePath light = new_light->get_on_light(li);
|
|
|
+ if (target_light != nullptr) {
|
|
|
+ // LightAttrib guarantees that the on lights are sorted, and that
|
|
|
+ // non-ambient lights come before ambient lights.
|
|
|
+ any_on_lights = target_light->has_any_on_light();
|
|
|
+ size_t filtered_lights = min((size_t)_max_lights, target_light->get_num_non_ambient_lights());
|
|
|
+ for (size_t li = 0; li < filtered_lights; ++li) {
|
|
|
+ NodePath light = target_light->get_on_light(li);
|
|
|
nassertv(!light.is_empty());
|
|
|
Light *light_obj = light.node()->as_light();
|
|
|
- nassertv(light_obj != (Light *)NULL);
|
|
|
+ nassertv(light_obj != nullptr);
|
|
|
|
|
|
// Lighting should be enabled before we apply any lights.
|
|
|
if (!_lighting_enabled) {
|
|
|
@@ -2673,23 +2645,16 @@ do_issue_light() {
|
|
|
_lighting_enabled = true;
|
|
|
}
|
|
|
|
|
|
- if (light_obj->is_ambient_light()) {
|
|
|
- // Ambient lights don't require specific light ids; simply add in the
|
|
|
- // ambient contribution to the current total
|
|
|
- cur_ambient_light += light_obj->get_color();
|
|
|
-
|
|
|
- } else {
|
|
|
- const LColor &color = light_obj->get_color();
|
|
|
- // Don't bother binding the light if it has no color to contribute.
|
|
|
- if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
|
|
|
- enable_light(num_enabled, true);
|
|
|
- if (num_enabled == 0) {
|
|
|
- begin_bind_lights();
|
|
|
- }
|
|
|
-
|
|
|
- light_obj->bind(this, light, num_enabled);
|
|
|
- num_enabled++;
|
|
|
+ const LColor &color = light_obj->get_color();
|
|
|
+ // Don't bother binding the light if it has no color to contribute.
|
|
|
+ if (color[0] != 0.0 || color[1] != 0.0 || color[2] != 0.0) {
|
|
|
+ enable_light(num_enabled, true);
|
|
|
+ if (num_enabled == 0) {
|
|
|
+ begin_bind_lights();
|
|
|
}
|
|
|
+
|
|
|
+ light_obj->bind(this, light, num_enabled);
|
|
|
+ num_enabled++;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -2700,7 +2665,7 @@ do_issue_light() {
|
|
|
_num_lights_enabled = num_enabled;
|
|
|
|
|
|
// If no lights were set, disable lighting
|
|
|
- if (num_on_lights == 0) {
|
|
|
+ if (!any_on_lights) {
|
|
|
if (_color_scale_via_lighting && (_has_material_force_color || _light_color_scale != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f))) {
|
|
|
// Unless we need lighting anyway to apply a color or color scale.
|
|
|
if (!_lighting_enabled) {
|
|
|
@@ -2717,7 +2682,7 @@ do_issue_light() {
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
- set_ambient_light(cur_ambient_light);
|
|
|
+ set_ambient_light(target_light->get_ambient_contribution());
|
|
|
}
|
|
|
|
|
|
if (num_enabled != 0) {
|