Просмотр исходного кода

Make fetching of p3d_LightSource[n] input clearly defined for non-existent lights

Refer to OpenGL 2.1 spec page 61

Closes: #129
rdb 9 лет назад
Родитель
Сommit
7db45cb647
1 измененных файлов с 92 добавлено и 33 удалено
  1. 92 33
      panda/src/display/graphicsStateGuardian.cxx

+ 92 - 33
panda/src/display/graphicsStateGuardian.cxx

@@ -1363,8 +1363,18 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
       }
       }
     }
     }
 
 
-    // TODO: dummy light
-    nassertr(false, &LMatrix4::ident_mat());
+    // Apply the default OpenGL lights otherwise.
+    // Special exception for light 0, which defaults to white.
+    if (index == 0) {
+      string basename = name->get_basename();
+      if (basename == "color" || basename == "diffuse") {
+        t.set_row(3, _light_color_scale);
+        return &t;
+      } else if (basename == "specular") {
+        return &LMatrix4::ones_mat();
+      }
+    }
+    return fetch_specified_member(NodePath(), name, t);
   }
   }
   default:
   default:
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
     nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
@@ -1395,8 +1405,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_quadraticAttenuation("quadraticAttenuation");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
   static const CPT_InternalName IN_shadowMatrix("shadowMatrix");
 
 
+  PandaNode *node = NULL;
+  if (!np.is_empty()) {
+    node = np.node();
+  }
+
   if (attrib == IN_color) {
   if (attrib == IN_color) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     LColor c = light->get_color();
     LColor c = light->get_color();
     c.componentwise_mult(_light_color_scale);
     c.componentwise_mult(_light_color_scale);
@@ -1404,9 +1422,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_ambient) {
   } else if (attrib == IN_ambient) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       LColor c = light->get_color();
       LColor c = light->get_color();
       c.componentwise_mult(_light_color_scale);
       c.componentwise_mult(_light_color_scale);
       t.set_row(3, c);
       t.set_row(3, c);
@@ -1417,9 +1438,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_diffuse) {
   } else if (attrib == IN_diffuse) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no diffuse color.
       // Ambient light has no diffuse color.
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
       t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
     } else {
     } else {
@@ -1430,19 +1454,25 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     return &t;
     return &t;
 
 
   } else if (attrib == IN_specular) {
   } else if (attrib == IN_specular) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ident_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     t.set_row(3, light->get_specular_color());
     t.set_row(3, light->get_specular_color());
     return &t;
     return &t;
 
 
   } else if (attrib == IN_position) {
   } else if (attrib == IN_position) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no position.
       // Ambient light has no position.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1451,7 +1481,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1466,13 +1496,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_halfVector) {
   } else if (attrib == IN_halfVector) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (np.is_empty()) {
+      t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0);
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no half-vector.
       // Ambient light has no half-vector.
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       t = LMatrix4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
       return &t;
       return &t;
-    } else if (np.node()->is_of_type(DirectionalLight::get_class_type())) {
+    } else if (node->is_of_type(DirectionalLight::get_class_type())) {
       DirectionalLight *light;
       DirectionalLight *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
 
 
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
       LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1484,7 +1517,7 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1502,13 +1535,16 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotDirection) {
   } else if (attrib == IN_spotDirection) {
-    if (np.node()->is_of_type(AmbientLight::get_class_type())) {
+    if (node == (PandaNode *)NULL) {
+      t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
+      return &t;
+    } else if (node->is_of_type(AmbientLight::get_class_type())) {
       // Ambient light has no spot direction.
       // Ambient light has no spot direction.
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
       return &t;
       return &t;
     } else {
     } else {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1523,9 +1559,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotCutoff) {
   } else if (attrib == IN_spotCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1539,9 +1576,10 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
     }
     }
 
 
   } else if (attrib == IN_spotCosCutoff) {
   } else if (attrib == IN_spotCosCutoff) {
-    if (np.node()->is_of_type(Spotlight::get_class_type())) {
+    if (node != (PandaNode *)NULL &&
+        node->is_of_type(Spotlight::get_class_type())) {
       LightLensNode *light;
       LightLensNode *light;
-      DCAST_INTO_R(light, np.node(), &LMatrix4::ident_mat());
+      DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
       Lens *lens = light->get_lens();
       Lens *lens = light->get_lens();
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
       nassertr(lens != (Lens *)NULL, &LMatrix4::ident_mat());
 
 
@@ -1553,51 +1591,72 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
       t.set_row(3, LVecBase4(-1));
       t.set_row(3, LVecBase4(-1));
       return &t;
       return &t;
     }
     }
+
   } else if (attrib == IN_spotExponent) {
   } else if (attrib == IN_spotExponent) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_exponent()));
     t.set_row(3, LVecBase4(light->get_exponent()));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_attenuation) {
   } else if (attrib == IN_attenuation) {
-    Light *light = np.node()->as_light();
-    nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
+    if (node != (PandaNode *)NULL) {
+      Light *light = node->as_light();
+      nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
 
-    t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+      t.set_row(3, LVecBase4(light->get_attenuation(), 0));
+    } else {
+      t.set_row(3, LVecBase4(1, 0, 0, 0));
+    }
     return &t;
     return &t;
 
 
   } else if (attrib == IN_constantAttenuation) {
   } else if (attrib == IN_constantAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::ones_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ones_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     t.set_row(3, LVecBase4(light->get_attenuation()[0]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_linearAttenuation) {
   } else if (attrib == IN_linearAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     t.set_row(3, LVecBase4(light->get_attenuation()[1]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_quadraticAttenuation) {
   } else if (attrib == IN_quadraticAttenuation) {
-    Light *light = np.node()->as_light();
+    if (node == (PandaNode *)NULL) {
+      return &LMatrix4::zeros_mat();
+    }
+    Light *light = node->as_light();
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
     nassertr(light != (Light *)NULL, &LMatrix4::ident_mat());
 
 
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     t.set_row(3, LVecBase4(light->get_attenuation()[2]));
     return &t;
     return &t;
 
 
   } else if (attrib == IN_shadowMatrix) {
   } else if (attrib == IN_shadowMatrix) {
-    LensNode *lnode;
-    DCAST_INTO_R(lnode, np.node(), &LMatrix4::ident_mat());
-    Lens *lens = lnode->get_lens();
-
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
     static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.5f, 0.0f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.0f, 0.0f, 0.5f, 0.0f,
                                   0.5f, 0.5f, 0.5f, 1.0f);
                                   0.5f, 0.5f, 0.5f, 1.0f);
 
 
+    if (node == (PandaNode *)NULL) {
+      return &biasmat;
+    }
+
+    LensNode *lnode;
+    DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
+    Lens *lens = lnode->get_lens();
+
     t = get_external_transform()->get_mat() *
     t = get_external_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       get_scene()->get_camera_transform()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *
       np.get_net_transform()->get_inverse()->get_mat() *